decoder: cope with new GstVaapiContextInfo based API.

Update decoders to report the maximum number of reference frames to use.
This commit is contained in:
Gwenole Beauchesne 2012-09-10 18:26:51 +02:00
parent 893e45ecb5
commit a10b3d3032
7 changed files with 121 additions and 102 deletions

View file

@ -529,31 +529,23 @@ gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced)
gboolean gboolean
gst_vaapi_decoder_ensure_context( gst_vaapi_decoder_ensure_context(
GstVaapiDecoder *decoder, GstVaapiDecoder *decoder,
GstVaapiProfile profile, GstVaapiContextInfo *cip
GstVaapiEntrypoint entrypoint,
guint width,
guint height
) )
{ {
GstVaapiDecoderPrivate * const priv = decoder->priv; GstVaapiDecoderPrivate * const priv = decoder->priv;
gst_vaapi_decoder_set_picture_size(decoder, width, height); gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height);
if (priv->context)
return gst_vaapi_context_reset(priv->context,
profile, entrypoint, width, height);
priv->context = gst_vaapi_context_new(
priv->display,
profile,
entrypoint,
width,
height
);
if (!priv->context)
return FALSE;
if (priv->context) {
if (!gst_vaapi_context_reset_full(priv->context, cip))
return FALSE;
}
else {
priv->context = gst_vaapi_context_new_full(priv->display, cip);
if (!priv->context)
return FALSE;
}
priv->va_context = gst_vaapi_context_get_id(priv->context); priv->va_context = gst_vaapi_context_get_id(priv->context);
return TRUE; return TRUE;
} }

View file

@ -306,6 +306,66 @@ clear_references(
guint *picture_count guint *picture_count
); );
/* Get number of reference frames to use */
static guint
get_max_dec_frame_buffering(GstH264SPS *sps)
{
guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
/* Table A-1 - Level limits */
switch (sps->level_idc) {
case 10: MaxDpbMbs = 396; break;
case 11: MaxDpbMbs = 900; break;
case 12: MaxDpbMbs = 2376; break;
case 13: MaxDpbMbs = 2376; break;
case 20: MaxDpbMbs = 2376; break;
case 21: MaxDpbMbs = 4752; break;
case 22: MaxDpbMbs = 8100; break;
case 30: MaxDpbMbs = 8100; break;
case 31: MaxDpbMbs = 18000; break;
case 32: MaxDpbMbs = 20480; break;
case 40: MaxDpbMbs = 32768; break;
case 41: MaxDpbMbs = 32768; break;
case 42: MaxDpbMbs = 34816; break;
case 50: MaxDpbMbs = 110400; break;
case 51: MaxDpbMbs = 184320; break;
default:
g_assert(0 && "unhandled level");
break;
}
PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
(sps->pic_height_in_map_units_minus1 + 1) *
(sps->frame_mbs_only_flag ? 1 : 2));
max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
/* VUI parameters */
if (sps->vui_parameters_present_flag) {
GstH264VUIParams * const vui_params = &sps->vui_parameters;
if (vui_params->bitstream_restriction_flag)
max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
else {
switch (sps->profile_idc) {
case 44: // CAVLC 4:4:4 Intra profile
case 86: // Scalable High profile
case 100: // High profile
case 110: // High 10 profile
case 122: // High 4:2:2 profile
case 244: // High 4:4:4 Predictive profile
if (sps->constraint_set3_flag)
max_dec_frame_buffering = 0;
break;
}
}
}
if (max_dec_frame_buffering > 16)
max_dec_frame_buffering = 16;
else if (max_dec_frame_buffering < sps->num_ref_frames)
max_dec_frame_buffering = sps->num_ref_frames;
return MAX(1, max_dec_frame_buffering);
}
static void static void
dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
{ {
@ -415,64 +475,12 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
return TRUE; return TRUE;
} }
static void static inline void
dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
{ {
GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderH264Private * const priv = decoder->priv;
guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
/* Table A-1 - Level limits */ priv->dpb_size = get_max_dec_frame_buffering(sps);
switch (sps->level_idc) {
case 10: MaxDpbMbs = 396; break;
case 11: MaxDpbMbs = 900; break;
case 12: MaxDpbMbs = 2376; break;
case 13: MaxDpbMbs = 2376; break;
case 20: MaxDpbMbs = 2376; break;
case 21: MaxDpbMbs = 4752; break;
case 22: MaxDpbMbs = 8100; break;
case 30: MaxDpbMbs = 8100; break;
case 31: MaxDpbMbs = 18000; break;
case 32: MaxDpbMbs = 20480; break;
case 40: MaxDpbMbs = 32768; break;
case 41: MaxDpbMbs = 32768; break;
case 42: MaxDpbMbs = 34816; break;
case 50: MaxDpbMbs = 110400; break;
case 51: MaxDpbMbs = 184320; break;
default:
g_assert(0 && "unhandled level");
break;
}
PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
(sps->pic_height_in_map_units_minus1 + 1) *
(sps->frame_mbs_only_flag ? 1 : 2));
max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
/* VUI parameters */
if (sps->vui_parameters_present_flag) {
GstH264VUIParams * const vui_params = &sps->vui_parameters;
if (vui_params->bitstream_restriction_flag)
max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
else {
switch (sps->profile_idc) {
case 44: // CAVLC 4:4:4 Intra profile
case 86: // Scalable High profile
case 100: // High profile
case 110: // High 10 profile
case 122: // High 4:2:2 profile
case 244: // High 4:4:4 Predictive profile
if (sps->constraint_set3_flag)
max_dec_frame_buffering = 0;
break;
}
}
}
if (max_dec_frame_buffering > 16)
max_dec_frame_buffering = 16;
else if (max_dec_frame_buffering < sps->num_ref_frames)
max_dec_frame_buffering = sps->num_ref_frames;
priv->dpb_size = MAX(1, max_dec_frame_buffering);
GST_DEBUG("DPB size %u", priv->dpb_size); GST_DEBUG("DPB size %u", priv->dpb_size);
} }
@ -632,13 +640,15 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
} }
if (reset_context) { if (reset_context) {
success = gst_vaapi_decoder_ensure_context( GstVaapiContextInfo info;
GST_VAAPI_DECODER(decoder),
priv->profile, info.profile = priv->profile;
entrypoint, info.entrypoint = entrypoint;
priv->width, priv->height info.width = priv->width;
); info.height = priv->height;
if (!success) info.ref_frames = get_max_dec_frame_buffering(sps);
if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info))
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
priv->has_context = TRUE; priv->has_context = TRUE;

View file

@ -137,11 +137,16 @@ ensure_context(GstVaapiDecoderJpeg *decoder)
} }
if (reset_context) { if (reset_context) {
reset_context = gst_vaapi_decoder_ensure_context( GstVaapiContextInfo info;
info.profile = priv->profile;
info.entrypoint = entrypoint;
info.width = priv->width;
info.height = priv->height;
info.ref_frames = 2;
reset_context = gst_vaapi_decoder_ensure_context(
GST_VAAPI_DECODER(decoder), GST_VAAPI_DECODER(decoder),
priv->profile, &info
entrypoint,
priv->width, priv->height
); );
if (!reset_context) if (!reset_context)
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;

View file

@ -410,11 +410,16 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder)
} }
if (reset_context) { if (reset_context) {
reset_context = gst_vaapi_decoder_ensure_context( GstVaapiContextInfo info;
info.profile = priv->hw_profile;
info.entrypoint = entrypoint;
info.width = priv->width;
info.height = priv->height;
info.ref_frames = 2;
reset_context = gst_vaapi_decoder_ensure_context(
GST_VAAPI_DECODER(decoder), GST_VAAPI_DECODER(decoder),
priv->hw_profile, &info
entrypoint,
priv->width, priv->height
); );
if (!reset_context) if (!reset_context)
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;

View file

@ -205,11 +205,16 @@ ensure_context(GstVaapiDecoderMpeg4 *decoder)
} }
if (reset_context) { if (reset_context) {
reset_context = gst_vaapi_decoder_ensure_context( GstVaapiContextInfo info;
info.profile = priv->profile;
info.entrypoint = entrypoint;
info.width = priv->width;
info.height = priv->height;
info.ref_frames = 2;
reset_context = gst_vaapi_decoder_ensure_context(
GST_VAAPI_DECODER(decoder), GST_VAAPI_DECODER(decoder),
priv->profile, &info
entrypoint,
priv->width, priv->height
); );
if (!reset_context) if (!reset_context)
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;

View file

@ -159,11 +159,8 @@ gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced);
G_GNUC_INTERNAL G_GNUC_INTERNAL
gboolean gboolean
gst_vaapi_decoder_ensure_context( gst_vaapi_decoder_ensure_context(
GstVaapiDecoder *decoder, GstVaapiDecoder *decoder,
GstVaapiProfile profile, GstVaapiContextInfo *cip
GstVaapiEntrypoint entrypoint,
guint width,
guint height
); );
G_GNUC_INTERNAL G_GNUC_INTERNAL

View file

@ -194,11 +194,16 @@ ensure_context(GstVaapiDecoderVC1 *decoder)
} }
if (reset_context) { if (reset_context) {
reset_context = gst_vaapi_decoder_ensure_context( GstVaapiContextInfo info;
info.profile = priv->profile;
info.entrypoint = entrypoint;
info.width = priv->width;
info.height = priv->height;
info.ref_frames = 2;
reset_context = gst_vaapi_decoder_ensure_context(
GST_VAAPI_DECODER(decoder), GST_VAAPI_DECODER(decoder),
priv->profile, &info
entrypoint,
priv->width, priv->height
); );
if (!reset_context) if (!reset_context)
return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;