Commit fb581c0d authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont Committed by Jean-Paul Saman

vdpau: determine correct decoder profile and level (fixes #8400)

This should render vdpau safe to enable with profiles not supported
by the hardware (such as high depth or high chroma). Software fallback
will be used automatically.
(cherry picked from commit 1b83ab71d0f2787be4070b1a43235dc99d3d5ad2)
Signed-off-by: default avatarJean-Paul Saman <jpsaman@videolan.org>
parent 8c89fc3a
...@@ -153,8 +153,14 @@ static int Init (vlc_va_t *va, void **ctxp, vlc_fourcc_t *chromap, ...@@ -153,8 +153,14 @@ static int Init (vlc_va_t *va, void **ctxp, vlc_fourcc_t *chromap,
height = (height + 3) & ~3; height = (height + 3) & ~3;
unsigned surfaces = 2; unsigned surfaces = 2;
if (sys->profile == VDP_DECODER_PROFILE_H264_HIGH) switch (sys->profile)
{
case VDP_DECODER_PROFILE_H264_BASELINE:
case VDP_DECODER_PROFILE_H264_MAIN:
case VDP_DECODER_PROFILE_H264_HIGH:
surfaces = 16; surfaces = 16;
break;
}
err = sys->DecoderCreate (sys->device, sys->profile, width, height, err = sys->DecoderCreate (sys->device, sys->profile, width, height,
surfaces, &sys->context.decoder); surfaces, &sys->context.decoder);
...@@ -262,28 +268,96 @@ static int Open (vlc_va_t *va, int codec, const es_format_t *fmt) ...@@ -262,28 +268,96 @@ static int Open (vlc_va_t *va, int codec, const es_format_t *fmt)
{ {
VdpStatus err; VdpStatus err;
VdpDecoderProfile profile; VdpDecoderProfile profile;
int level;
switch (codec) switch (codec)
{ {
case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG1VIDEO:
profile = VDP_DECODER_PROFILE_MPEG1; profile = VDP_DECODER_PROFILE_MPEG1;
level = VDP_DECODER_LEVEL_MPEG1_NA;
break; break;
case AV_CODEC_ID_MPEG2VIDEO: case AV_CODEC_ID_MPEG2VIDEO:
switch (fmt->i_profile)
{
case FF_PROFILE_MPEG2_MAIN:
profile = VDP_DECODER_PROFILE_MPEG2_MAIN; profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
break; break;
case FF_PROFILE_MPEG2_SIMPLE:
profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE;
break;
default:
msg_Err (va, "unsupported %s profile %d", "MPEG2", fmt->i_profile);
return VLC_EGENERIC;
}
level = VDP_DECODER_LEVEL_MPEG2_HL;
break;
case AV_CODEC_ID_H263: case AV_CODEC_ID_H263:
profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP;
level = VDP_DECODER_LEVEL_MPEG4_PART2_ASP_L5;
break;
case AV_CODEC_ID_MPEG4: case AV_CODEC_ID_MPEG4:
switch (fmt->i_profile)
{
case FF_PROFILE_MPEG4_SIMPLE:
profile = VDP_DECODER_PROFILE_MPEG4_PART2_SP;
break;
case FF_PROFILE_MPEG4_SIMPLE_STUDIO:
msg_Err (va, "unsupported %s profile %d", "MPEG4", fmt->i_profile);
return VLC_EGENERIC;
default:
profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP;
break; break;
}
level = fmt->i_level;
break;
case AV_CODEC_ID_H264: case AV_CODEC_ID_H264:
switch (fmt->i_profile
& ~(FF_PROFILE_H264_CONSTRAINED|FF_PROFILE_H264_INTRA))
{
case FF_PROFILE_H264_BASELINE:
profile = VDP_DECODER_PROFILE_H264_BASELINE;
break;
case FF_PROFILE_H264_MAIN:
profile = VDP_DECODER_PROFILE_H264_MAIN;
break;
case FF_PROFILE_H264_HIGH:
profile = VDP_DECODER_PROFILE_H264_HIGH; profile = VDP_DECODER_PROFILE_H264_HIGH;
break; break;
case FF_PROFILE_H264_EXTENDED:
default:
msg_Err (va, "unsupported %s profile %d", "H.264", fmt->i_profile);
return VLC_EGENERIC;
}
level = fmt->i_level;
if ((fmt->i_profile & FF_PROFILE_H264_INTRA) && (fmt->i_level == 11))
level = VDP_DECODER_LEVEL_H264_1b;
break;
case AV_CODEC_ID_WMV3: case AV_CODEC_ID_WMV3:
case AV_CODEC_ID_VC1: case AV_CODEC_ID_VC1:
switch (fmt->i_profile)
{
case FF_PROFILE_VC1_SIMPLE:
profile = VDP_DECODER_PROFILE_VC1_SIMPLE;
break;
case FF_PROFILE_VC1_MAIN:
profile = VDP_DECODER_PROFILE_VC1_MAIN;
break;
case FF_PROFILE_VC1_ADVANCED:
profile = VDP_DECODER_PROFILE_VC1_ADVANCED; profile = VDP_DECODER_PROFILE_VC1_ADVANCED;
break; break;
default: default:
msg_Err (va, "unknown codec (%d)", codec); msg_Err (va, "unsupported %s profile %d", "VC-1", fmt->i_profile);
return VLC_EGENERIC;
}
level = fmt->i_level;
break;
default:
msg_Err (va, "unknown codec %d", codec);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -336,7 +410,7 @@ static int Open (vlc_va_t *va, int codec, const es_format_t *fmt) ...@@ -336,7 +410,7 @@ static int Open (vlc_va_t *va, int codec, const es_format_t *fmt)
/* Check capabilities */ /* Check capabilities */
VdpBool support; VdpBool support;
uint32_t level, mb, width, height; uint32_t lvl, mb, width, height;
if (sys->VideoSurfaceQueryCapabilities (device, VDP_CHROMA_TYPE_420, if (sys->VideoSurfaceQueryCapabilities (device, VDP_CHROMA_TYPE_420,
&support, &width, &height) != VDP_STATUS_OK) &support, &width, &height) != VDP_STATUS_OK)
...@@ -360,17 +434,18 @@ static int Open (vlc_va_t *va, int codec, const es_format_t *fmt) ...@@ -360,17 +434,18 @@ static int Open (vlc_va_t *va, int codec, const es_format_t *fmt)
goto error; goto error;
} }
if (sys->DecoderQueryCapabilities (device, profile, &support, &level, if (sys->DecoderQueryCapabilities (device, profile, &support, &lvl,
&mb, &width, &height) != VDP_STATUS_OK) &mb, &width, &height) != VDP_STATUS_OK)
support = VDP_FALSE; support = VDP_FALSE;
if (!support || width < fmt->video.i_width || height < fmt->video.i_height) if (!support || (int)lvl < level
|| width < fmt->video.i_width || height < fmt->video.i_height)
{ {
msg_Err (va, "decoding profile not supported: %"PRIu32" %ux%u", msg_Err (va, "decoding profile not supported: %"PRIu32".%d %ux%u",
profile, fmt->video.i_width, fmt->video.i_height); profile, lvl, fmt->video.i_width, fmt->video.i_height);
goto error; goto error;
} }
msg_Dbg (va, "decoding profile supported maximum: %"PRIu32".%"PRIu32" mb %" msg_Dbg (va, "decoding profile supported maximum: %"PRIu32".%"PRIu32" mb %"
PRIu32", %"PRIu32"x%"PRIu32, profile, level, mb, width, height); PRIu32", %"PRIu32"x%"PRIu32, profile, lvl, mb, width, height);
const char *infos; const char *infos;
if (sys->GetInformationString (&infos) != VDP_STATUS_OK) if (sys->GetInformationString (&infos) != VDP_STATUS_OK)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment