Skip to content

Commit

Permalink
minor tweaks
Browse files Browse the repository at this point in the history
* add BT2020 in yuv converter code for future use
* clean up setup of mp4 metadata MF sink writer - it doesn't
seem to be always used correctly, but at least now it documents
in what format exactly video is stored
  • Loading branch information
mmozeiko committed Sep 18, 2024
1 parent 1d5d5af commit eb1332e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 10 deletions.
9 changes: 5 additions & 4 deletions wcap_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ BOOL Encoder_Start(Encoder* Encoder, ID3D11Device* Device, LPWSTR FileName, cons
HR(IMFMediaType_SetGUID(Type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video));
HR(IMFMediaType_SetGUID(Type, &MF_MT_SUBTYPE, Codec));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_MPEG2_PROFILE, Profile));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_VIDEO_CHROMA_SITING, MFVideoChromaSubsampling_MPEG2));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_Wide));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_VIDEO_PRIMARIES, IsHD ? MFVideoPrimaries_BT709 : MFVideoPrimaries_SMPTE170M));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_YUV_MATRIX, IsHD ? MFVideoTransferMatrix_BT709 : MFVideoTransferMatrix_BT601));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_TRANSFER_FUNCTION, MFVideoPrimaries_BT709));
Expand All @@ -422,9 +424,6 @@ BOOL Encoder_Start(Encoder* Encoder, ID3D11Device* Device, LPWSTR FileName, cons
HR(MFCreateMediaType(&Type));
HR(IMFMediaType_SetGUID(Type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video));
HR(IMFMediaType_SetGUID(Type, &MF_MT_SUBTYPE, MediaFormatYUV));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_VIDEO_PRIMARIES, IsHD ? MFVideoPrimaries_BT709 : MFVideoPrimaries_SMPTE170M));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_YUV_MATRIX, IsHD ? MFVideoTransferMatrix_BT709 : MFVideoTransferMatrix_BT601));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_TRANSFER_FUNCTION, MFVideoPrimaries_BT709));
HR(IMFMediaType_SetUINT32(Type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
HR(IMFMediaType_SetUINT64(Type, &MF_MT_FRAME_RATE, MFT64(Config->FramerateNum, Config->FramerateDen)));
HR(IMFMediaType_SetUINT64(Type, &MF_MT_FRAME_SIZE, MFT64(OutputWidth, OutputHeight)));
Expand Down Expand Up @@ -572,7 +571,8 @@ BOOL Encoder_Start(Encoder* Encoder, ID3D11Device* Device, LPWSTR FileName, cons

// yuv converter
{
YuvConvert_Create(&Encoder->Convert, Device, Encoder->Resize.OutputTexture, OutputWidth, OutputHeight, IsHD, Config->Config->ImprovedColorConversion);
YuvColorSpace ColorSpace = IsHD ? YuvColorSpace_BT709 : YuvColorSpace_BT601;
YuvConvert_Create(&Encoder->Convert, Device, Encoder->Resize.OutputTexture, OutputWidth, OutputHeight, ColorSpace, Config->Config->ImprovedColorConversion);

UINT32 Size;
HR(MFCalculateImageSize(MediaFormatYUV, OutputWidth, OutputHeight, &Size));
Expand Down Expand Up @@ -753,6 +753,7 @@ BOOL Encoder_NewFrame(Encoder* Encoder, ID3D11Texture2D* Texture, RECT Rect, UIN
// convert to YUV
YuvConvert_Dispatch(&Encoder->Convert, Context, &Encoder->ConvertOutput[Index]);

ID3D11DeviceContext_Flush(Context);
ID3D11Multithread_Leave(Encoder->Multithread);

// setup input time & duration
Expand Down
43 changes: 37 additions & 6 deletions wcap_yuv_convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,18 @@ typedef struct
}
YuvConvert;

typedef enum
{
YuvColorSpace_BT601,
YuvColorSpace_BT709,
YuvColorSpace_BT2020,
}
YuvColorSpace;

static void YuvConvertOutput_Create(YuvConvertOutput* Output, ID3D11Device* Device, uint32_t Width, uint32_t Height, DXGI_FORMAT Format);
static void YuvConvertOutput_Release(YuvConvertOutput* Output);

static void YuvConvert_Create(YuvConvert* Convert, ID3D11Device* Device, ID3D11Texture2D* InputTexture, uint32_t Width, uint32_t Height, bool IsHD, bool ImprovedConversion);
static void YuvConvert_Create(YuvConvert* Convert, ID3D11Device* Device, ID3D11Texture2D* InputTexture, uint32_t Width, uint32_t Height, YuvColorSpace ColorSpace, bool ImprovedConversion);
static void YuvConvert_Release(YuvConvert* Convert);

static void YuvConvert_Dispatch(YuvConvert* Convert, ID3D11DeviceContext* Context, YuvConvertOutput* Output);
Expand Down Expand Up @@ -96,7 +104,7 @@ void YuvConvertOutput_Release(YuvConvertOutput* Output)
ID3D11ShaderResourceView_Release(Output->ViewInUV);
}

void YuvConvert_Create(YuvConvert* Convert, ID3D11Device* Device, ID3D11Texture2D* InputTexture, uint32_t Width, uint32_t Height, bool IsHD, bool ImprovedConversion)
void YuvConvert_Create(YuvConvert* Convert, ID3D11Device* Device, ID3D11Texture2D* InputTexture, uint32_t Width, uint32_t Height, YuvColorSpace ColorSpace, bool ImprovedConversion)
{
Assert(Width % 2 == 0 && Height % 2 == 0);

Expand All @@ -108,8 +116,21 @@ void YuvConvert_Create(YuvConvert* Convert, ID3D11Device* Device, ID3D11Texture2
};
ID3D11Device_CreateShaderResourceView(Device, (ID3D11Resource*)InputTexture, &InputViewDesc, &Convert->InputView);

// https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion
static const float BT2020[6][4] =
{
// RGB to YUV
{ +0.26270f, +0.678000f, +0.0593000f },
{ -0.13963f, -0.360370f, +0.5000000f },
{ +0.50000f, -0.459786f, -0.0402143f },
// YUV to RGB
{ 1.f, +0.000000f, +1.474600f },
{ 1.f, -0.164553f, -0.571353f },
{ 1.f, +1.881400f, +0.000000f },
};

// https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.709_conversion
static const float BT709[7][4] =
static const float BT709[6][4] =
{
// RGB to YUV
{ +0.2126f, +0.7152f, +0.0722f },
Expand All @@ -120,8 +141,9 @@ void YuvConvert_Create(YuvConvert* Convert, ID3D11Device* Device, ID3D11Texture2
{ 1.f, -0.1873f, -0.4681f },
{ 1.f, +1.8556f, +0.0000f },
};

// https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion
static const float BT601[7][4] =
static const float BT601[6][4] =
{
// RGB to YUV
{ +0.299000f, +0.587000f, +0.114000f },
Expand All @@ -133,16 +155,25 @@ void YuvConvert_Create(YuvConvert* Convert, ID3D11Device* Device, ID3D11Texture2
{ 1.f, +1.772000f, +0.000000f },
};

const float (*ConvertMatrix)[4];
switch (ColorSpace)
{
case YuvColorSpace_BT601: ConvertMatrix = BT601; break;
case YuvColorSpace_BT709: ConvertMatrix = BT709; break;
case YuvColorSpace_BT2020: ConvertMatrix = BT2020; break;
default: Assert(false);
}

D3D11_BUFFER_DESC ConstantBufferDesc =
{
.ByteWidth = IsHD ? sizeof(BT709) : sizeof(BT601),
.ByteWidth = 6 * 4 * sizeof(float),
.Usage = D3D11_USAGE_IMMUTABLE,
.BindFlags = D3D11_BIND_CONSTANT_BUFFER,
};

D3D11_SUBRESOURCE_DATA ConstantBufferData =
{
.pSysMem = IsHD ? BT709 : BT601,
.pSysMem = ConvertMatrix,
};

ID3D11Device_CreateBuffer(Device, &ConstantBufferDesc, &ConstantBufferData, &Convert->ConstantBuffer);
Expand Down

0 comments on commit eb1332e

Please sign in to comment.