Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions _studio/mfx_lib/decode/h264/src/mfx_h264_dec_decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ mfxStatus VideoDECODEH264::Init(mfxVideoParam *par)

eMFXHWType type = m_core->GetHWType();

if (par->mfx.FrameInfo.FourCC == MFX_FOURCC_P010 ||
par->mfx.FrameInfo.FourCC == MFX_FOURCC_P210 ||
par->mfx.FrameInfo.FourCC == MFX_FOURCC_Y210)
par->mfx.FrameInfo.Shift = 1;

mfxStatus mfxSts = CheckVideoParamDecoders(par, type);
MFX_CHECK(mfxSts >= MFX_ERR_NONE, MFX_ERR_INVALID_VIDEO_PARAM);

Expand Down Expand Up @@ -405,6 +410,8 @@ mfxStatus VideoDECODEH264::QueryImplsDescription(
#endif
, MFX_PROFILE_AVC_MULTIVIEW_HIGH
, MFX_PROFILE_AVC_STEREO_HIGH
, MFX_PROFILE_AVC_HIGH10
, MFX_PROFILE_AVC_HIGH_422
};
const mfxResourceType SupportedMemTypes[] =
{
Expand All @@ -414,6 +421,8 @@ mfxStatus VideoDECODEH264::QueryImplsDescription(
const mfxU32 SupportedFourCC[] =
{
MFX_FOURCC_NV12
, MFX_FOURCC_P010
, MFX_FOURCC_Y210
};

caps.CodecID = MFX_CODEC_AVC;
Expand Down Expand Up @@ -807,6 +816,15 @@ mfxStatus VideoDECODEH264::GetVideoParam(mfxVideoParam *par)
}
}

switch (par->mfx.FrameInfo.FourCC)
{
case MFX_FOURCC_P010:
case MFX_FOURCC_P210:
case MFX_FOURCC_Y210:
par->mfx.FrameInfo.Shift = 1;
default:
break;
}

TRACE_EVENT(MFX_TRACE_API_DECODE_GETVIDEOPARAM_TASK, EVENT_TYPE_END, TR_KEY_MFX_API, make_event_data(MFX_ERR_NONE));

Expand Down
8 changes: 8 additions & 0 deletions _studio/mfx_lib/shared/include/mfx_platform_caps.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,14 @@ namespace H264DCaps {
{
return platform < MFX_HW_XE_HP_SDV;
}
inline bool IsDec420TenBitSupported(eMFXHWType platform)
{
return (platform >= MFX_HW_PTL);
}
inline bool IsDec422TenBitSupported(eMFXHWType platform)
{
return (platform >= MFX_HW_PTL);
}
}
#endif // MFX_ENABLE_H264_VIDEO_DECODE
#endif // __MFX_PLATFORM_CAPS_H__
3 changes: 2 additions & 1 deletion _studio/mfx_lib/shared/src/mfx_common_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ mfxStatus CheckFrameInfoCodecs(mfxFrameInfo *info, mfxU32 codecId)
if (info->FourCC != MFX_FOURCC_NV12 &&
info->FourCC != MFX_FOURCC_P010 &&
info->FourCC != MFX_FOURCC_NV16 &&
info->FourCC != MFX_FOURCC_P210)
info->FourCC != MFX_FOURCC_P210 &&
info->FourCC != MFX_FOURCC_Y210)
MFX_RETURN(MFX_ERR_INVALID_VIDEO_PARAM);
break;
case MFX_CODEC_HEVC:
Expand Down
6 changes: 6 additions & 0 deletions _studio/shared/src/libmfx_core_hw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ mfxU32 ChooseProfile(mfxVideoParam const* param, eMFXHWType hwType)
}
#endif
}

if (param->mfx.CodecProfile == MFX_PROFILE_AVC_HIGH10 ||
param->mfx.CodecProfile == MFX_PROFILE_AVC_HIGH_422)
{
profile |= VA_PROFILE_REXT | VA_PROFILE_10;
}
break;

case MFX_CODEC_JPEG:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1919,7 +1919,9 @@ Status H264HeadersBitstream::GetPredWeightTable(
{
pPredWeight_L0[refindex].luma_weight = (int8_t)GetVLCElement(true);
pPredWeight_L0[refindex].luma_offset = (int8_t)GetVLCElement(true);
#if !defined(LINUX)
pPredWeight_L0[refindex].luma_offset <<= (sps->bit_depth_luma - 8);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason to exclude this for Linux? this should be common for linux and windows.

Copy link
Copy Markdown
Contributor Author

@vcheah vcheah Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consistently see pink/artifact corruption (shown below) that reproduces on Linux VPL (msdkh264dec/sample_decode) with a 10-bit clip H.264 containing non-zero chroma_offsets/luma_offsets values. The same clip decodes correctly with GStreamer's VA decoder (vah264dec). Comparing the LIBVA trace logs, the chroma_offsets/luma_offsets values differ between gst-vpl and gst-va — gst-va passes the exact raw bitstream values without prescaling (<< (bit_depth - 8)) to VAAPI while, gst-vpl does not. 

This is the transcode output (vah264dec/msdkh264dec → vah265enc) from a specific AVC input stream.


pic-1 The image above illustrates a specific corruption/artifact seen only with VPL when comparing against gst-va on the same frame.

pic-2 This is another clip where the frame turns pink only with VPL. The same problem does not occur with gst-va.

>>> any reason to exclude this for Linux? this should be common for linux and windows.
 The fix is guarded with #if !defined(LINUX) to preserve the existing Windows code path and minimize risk. Windows VPL sample_decode was tested  with a similar 10-bit H.264 stream and does not exhibit any pink frame/artifact corruption. Note that, this case exercises DXVA2 H.264 short slice code path, where the decoder does  pred_weight_table and H264HeadersBitstream::GetPredWeightTable() is never called. I think  DXVA2 H.264 long slice will call the function but I don't how to trigger this correctly on VPL. Subsequently, reading  Gstreamer (vah264dec) and FFMPEG  (vaapi_h264) implementation on Linux seems that the just pass raw luma_offset and chroma_offset value directly to VAAPI without pre-scaling. 

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plan to double check this again.

#endif
}
else
{
Expand All @@ -1940,8 +1942,10 @@ Status H264HeadersBitstream::GetPredWeightTable(
pPredWeight_L0[refindex].chroma_weight[1] = (int8_t)GetVLCElement(true);
pPredWeight_L0[refindex].chroma_offset[1] = (int8_t)GetVLCElement(true);

#if !defined(LINUX)
pPredWeight_L0[refindex].chroma_offset[0] <<= (sps->bit_depth_chroma - 8);
pPredWeight_L0[refindex].chroma_offset[1] <<= (sps->bit_depth_chroma - 8);
#endif
}
else
{
Expand All @@ -1961,7 +1965,9 @@ Status H264HeadersBitstream::GetPredWeightTable(
{
pPredWeight_L1[refindex].luma_weight = (int8_t)GetVLCElement(true);
pPredWeight_L1[refindex].luma_offset = (int8_t)GetVLCElement(true);
#if !defined(LINUX)
pPredWeight_L1[refindex].luma_offset <<= (sps->bit_depth_luma - 8);
#endif
}
else
{
Expand All @@ -1980,8 +1986,10 @@ Status H264HeadersBitstream::GetPredWeightTable(
pPredWeight_L1[refindex].chroma_weight[1] = (int8_t)GetVLCElement(true);
pPredWeight_L1[refindex].chroma_offset[1] = (int8_t)GetVLCElement(true);

#if !defined(LINUX)
pPredWeight_L1[refindex].chroma_offset[0] <<= (sps->bit_depth_chroma - 8);
pPredWeight_L1[refindex].chroma_offset[1] <<= (sps->bit_depth_chroma - 8);
#endif
}
else
{
Expand Down
38 changes: 31 additions & 7 deletions _studio/shared/umc/codec/h264_dec/src/umc_h264_mfx_supplier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,13 @@ bool MFX_Utility::IsNeedPartialAcceleration(mfxVideoParam * par, eMFXHWType )
if (par->mfx.SliceGroupsPresent) // Is FMO
return true;

if (par->mfx.FrameInfo.FourCC != MFX_FOURCC_NV12) // yuv422 in SW only
if (par->mfx.FrameInfo.FourCC != MFX_FOURCC_NV12
&& par->mfx.FrameInfo.FourCC != MFX_FOURCC_P210
&& par->mfx.FrameInfo.FourCC != MFX_FOURCC_P010
&& par->mfx.FrameInfo.FourCC != MFX_FOURCC_Y210)
return true;

if (par->mfx.FrameInfo.BitDepthLuma > 8 || par->mfx.FrameInfo.BitDepthChroma > 8) // yuv422 in SW only
if (par->mfx.FrameInfo.BitDepthLuma > 10 || par->mfx.FrameInfo.BitDepthChroma > 10)
return true;

mfxExtMVCSeqDesc * points = (mfxExtMVCSeqDesc*)GetExtendedBuffer(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_MVC_SEQ_DESC);
Expand Down Expand Up @@ -569,6 +572,17 @@ UMC::Status MFX_Utility::FillVideoParam(UMC::TaskSupplier * supplier, mfxVideoPa
if (pps)
par->mfx.SliceGroupsPresent = pps->num_slice_groups > 1;

if (par->mfx.FrameInfo.FourCC == MFX_FOURCC_P010
|| par->mfx.FrameInfo.FourCC == MFX_FOURCC_P210
|| par->mfx.FrameInfo.FourCC == MFX_FOURCC_Y210)
{
par->mfx.FrameInfo.Shift = 1;
}
else
{
par->mfx.FrameInfo.Shift = 0;
}

return UMC::UMC_OK;
}

Expand Down Expand Up @@ -1158,7 +1172,11 @@ inline bool CheckFourcc(mfxU32 fourcc, mfxU16 codecProfile, eMFXHWType type)
#endif
case MFX_PROFILE_AVC_MULTIVIEW_HIGH:
case MFX_PROFILE_AVC_STEREO_HIGH:
return fourcc == MFX_FOURCC_NV12;
return (fourcc == MFX_FOURCC_NV12);
case MFX_PROFILE_AVC_HIGH10: //High10 may have 8bit clip.
return H264DCaps::IsDec420TenBitSupported(type) ? (fourcc == MFX_FOURCC_NV12 || fourcc == MFX_FOURCC_P010) : (fourcc == MFX_FOURCC_NV12);
case MFX_PROFILE_AVC_HIGH_422: //HIGH_422 may have 420 clip
return H264DCaps::IsDec422TenBitSupported(type) ? (fourcc == MFX_FOURCC_NV12 || fourcc == MFX_FOURCC_P010 || fourcc == MFX_FOURCC_Y210) : (fourcc == MFX_FOURCC_NV12);
default:
return false;
}
Expand Down Expand Up @@ -1196,7 +1214,9 @@ mfxStatus MFX_Utility::Query(VideoCORE *core, mfxVideoParam *in, mfxVideoParam *
(MFX_PROFILE_AVC_SCALABLE_HIGH == in->mfx.CodecProfile) ||
#endif
(MFX_PROFILE_AVC_MULTIVIEW_HIGH == in->mfx.CodecProfile) ||
(MFX_PROFILE_AVC_STEREO_HIGH == in->mfx.CodecProfile)
(MFX_PROFILE_AVC_STEREO_HIGH == in->mfx.CodecProfile) ||
(MFX_PROFILE_AVC_HIGH_422 == in->mfx.CodecProfile) ||
(MFX_PROFILE_AVC_HIGH10 == in->mfx.CodecProfile)
)
out->mfx.CodecProfile = in->mfx.CodecProfile;
else
Expand Down Expand Up @@ -1340,6 +1360,9 @@ mfxStatus MFX_Utility::Query(VideoCORE *core, mfxVideoParam *in, mfxVideoParam *
sts = MFX_ERR_UNSUPPORTED;
}

out->mfx.FrameInfo.BitDepthLuma = in->mfx.FrameInfo.BitDepthLuma;
out->mfx.FrameInfo.BitDepthChroma = in->mfx.FrameInfo.BitDepthChroma;

out->mfx.FrameInfo.Shift = in->mfx.FrameInfo.Shift;
switch (in->mfx.FrameInfo.PicStruct)
{
Expand Down Expand Up @@ -1772,6 +1795,8 @@ bool MFX_Utility::CheckVideoParam(mfxVideoParam *in, eMFXHWType type)
case MFX_PROFILE_AVC_MAIN:
case MFX_PROFILE_AVC_EXTENDED:
case MFX_PROFILE_AVC_HIGH:
case MFX_PROFILE_AVC_HIGH10:
case MFX_PROFILE_AVC_HIGH_422:
case MFX_PROFILE_AVC_STEREO_HIGH:
case MFX_PROFILE_AVC_MULTIVIEW_HIGH:
#ifdef MFX_ENABLE_SVC_VIDEO_DECODE
Expand Down Expand Up @@ -1814,9 +1839,8 @@ bool MFX_Utility::CheckVideoParam(mfxVideoParam *in, eMFXHWType type)
if (in->mfx.FrameInfo.Height > 16384 || (in->mfx.FrameInfo.Height % 16))
return false;


if (in->mfx.FrameInfo.FourCC != MFX_FOURCC_NV12 && in->mfx.FrameInfo.FourCC != MFX_FOURCC_NV16 &&
in->mfx.FrameInfo.FourCC != MFX_FOURCC_P010 && in->mfx.FrameInfo.FourCC != MFX_FOURCC_P210)
in->mfx.FrameInfo.FourCC != MFX_FOURCC_P010 && in->mfx.FrameInfo.FourCC != MFX_FOURCC_P210 && in->mfx.FrameInfo.FourCC != MFX_FOURCC_Y210)
return false;

// both zero or not zero
Expand All @@ -1842,7 +1866,7 @@ bool MFX_Utility::CheckVideoParam(mfxVideoParam *in, eMFXHWType type)

if (in->mfx.FrameInfo.ChromaFormat == MFX_CHROMAFORMAT_YUV422)
{
if (in->mfx.FrameInfo.FourCC != MFX_FOURCC_P210 && in->mfx.FrameInfo.FourCC != MFX_FOURCC_NV16)
if (in->mfx.FrameInfo.FourCC != MFX_FOURCC_P210 && in->mfx.FrameInfo.FourCC != MFX_FOURCC_Y210 && in->mfx.FrameInfo.FourCC != MFX_FOURCC_NV16)
return false;
}

Expand Down
15 changes: 15 additions & 0 deletions _studio/shared/umc/io/umc_va/src/umc_va_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ VAProfile g_H264Profiles[] =
VAProfileH264High, VAProfileH264Main, VAProfileH264ConstrainedBaseline
};

#if VA_CHECK_VERSION(1, 18, 0)
VAProfile g_H26410BitProfiles[] =
{
VAProfileH264High10,
#if VA_CHECK_VERSION(1, 23, 0)
VAProfileH264High422,
#endif
};
#endif

VAProfile g_H265Profiles[] =
{
VAProfileHEVCMain
Expand Down Expand Up @@ -211,6 +221,11 @@ VAProfile get_next_va_profile(uint32_t umc_codec, uint32_t profile)
case UMC::VA_H264:
if (profile < UMC_ARRAY_SIZE(g_H264Profiles)) va_profile = g_H264Profiles[profile];
break;
#if VA_CHECK_VERSION(1, 18, 0)
case UMC::VA_H264 | UMC::VA_PROFILE_REXT | UMC::VA_PROFILE_10:
if (profile < UMC_ARRAY_SIZE(g_H26410BitProfiles)) va_profile = g_H26410BitProfiles[profile];
break;
#endif
case UMC::VA_H265:
if (profile < UMC_ARRAY_SIZE(g_H265Profiles)) va_profile = g_H265Profiles[profile];
break;
Expand Down
Loading