Buffer<uint>  rgbData;
Buffer<float> yuvData;

cbuffer PS_CONSTANT_BUFFER : register(b0)
{
    int frameWidth;
    int frameHeight;
    int frameNumber;
    int numFrames;
};

struct PsInput{
     float4 outputPosition : SV_Position;
     float2 tex : MyTex;
};

// calculate U and V values from a 4:2:0 8-bit frame
float UV_420_8(int x, int y, int width, int height, bool v)
{
    // calculate start of component data
    int offset = width * height;
    if (v)
    {
        offset += (width * height) >> 2;
    }

    // calculate pixel offset
    offset += (y >> 2) * width + (x >> 1);

    return yuvData[offset];
}

void PS_yuv420_8(PsInput pos ,
        out float4 color : SV_TARGET)
{
    int width = frameWidth;
    int height = frameHeight;

    pos.tex = abs(pos.tex);

    // calculate integer position
    int x = pos.tex.x * width;
    int y = pos.tex.y * height;

    float Y, U, V;
    
    // extract luma value
    Y = yuvData[y * width + x];
        
    // extract chroma values
    U = UV_420_8(x, y, width, height, false);
    V = UV_420_8(x, y, width, height, true);

    Y = clamp(Y, 16.f/255.f, 235.f/255.f);
    U = clamp(U, 16.f/255.f, 240.f/255.f);
    V = clamp(V, 16.f/255.f, 240.f/255.f);

    Y -= 16.f/255.f;
    U -= 0.5f;
    V -= 0.5f;

    // convert YUV to RGB
    float r = 1.164384f * Y                +  1.79263f * V;
    float g = 1.164384f * Y - 0.21321f * U -  0.53302f * V;
    float b = 1.164384f * Y + 2.11244f * U;

    color = float4(r, g, b, 1.0);    

    int seekbarHeight = height * 2 / 100;

    if (y > (height - seekbarHeight))
    {
        if (y > (height - seekbarHeight + 4))
        {
            if (x < (frameNumber * width / numFrames))
            {
                color = float4(1.0, 0.0, 0.0, 1.0);
            }
        }
        else
        {
            color = float4(1.0, 0.0, 0.0, 1.0);
        }
    }
}


//
// the data should be arranged in RGBA (10:10:10:2) sequential int (not planes)
// however we read it in as uint, so it comes as 1 byte of information in each uint!!!
void PS_rgb10(PsInput pos,
        out float4 color : SV_TARGET)
{
    int width = frameWidth;
    int height = frameHeight;

    pos.tex = abs(pos.tex);

    // calculate integer position
    int x = pos.tex.x * width;
    int y = pos.tex.y * height;


    // calculate offsets
    const int offset = y * width * 4 + x * 4;

    // bit calculate each component    
    uint red = (rgbData[offset] << 2);
    red |= (rgbData[offset + 1] >> 6);

    uint green = ((rgbData[offset + 1] & 0x3F) << 4);
    green |= (rgbData[offset + 2] >> 4);

    uint blue = ((rgbData[offset + 2] & 0xF) << 6);
    blue |= (rgbData[offset + 3] >> 2);

    // convert to float and normalize
    float r, g, b;
    r = red;
    r /= 1023.0; // 0x3FF;
    g = green;
    g /= 1023.0; // 0x3FF;
    b = blue;
    b /= 1023.0; // 0x3FF;

    color = float4(r, g, b, 1.0);    
}
