From a10b3d30326bb1a8141c8a9c604d4e4c41c73f25 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 10 Sep 2012 18:26:51 +0200 Subject: [PATCH] decoder: cope with new GstVaapiContextInfo based API. Update decoders to report the maximum number of reference frames to use. --- gst-libs/gst/vaapi/gstvaapidecoder.c | 32 +++---- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 132 ++++++++++++++++------------- gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c | 13 ++- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 13 ++- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 13 ++- gst-libs/gst/vaapi/gstvaapidecoder_priv.h | 7 +- gst-libs/gst/vaapi/gstvaapidecoder_vc1.c | 13 ++- 7 files changed, 121 insertions(+), 102 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder.c b/gst-libs/gst/vaapi/gstvaapidecoder.c index 0865dba..148a6a2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder.c @@ -529,31 +529,23 @@ gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced) gboolean gst_vaapi_decoder_ensure_context( - GstVaapiDecoder *decoder, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, - guint width, - guint height + GstVaapiDecoder *decoder, + GstVaapiContextInfo *cip ) { GstVaapiDecoderPrivate * const priv = decoder->priv; - gst_vaapi_decoder_set_picture_size(decoder, width, 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; + gst_vaapi_decoder_set_picture_size(decoder, cip->width, cip->height); + 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); return TRUE; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 05bd927..d0e2432 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -306,6 +306,66 @@ clear_references( 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 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index) { @@ -415,64 +475,12 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture) return TRUE; } -static void +static inline void dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) { GstVaapiDecoderH264Private * const priv = decoder->priv; - 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; - priv->dpb_size = MAX(1, max_dec_frame_buffering); + priv->dpb_size = get_max_dec_frame_buffering(sps); GST_DEBUG("DPB size %u", priv->dpb_size); } @@ -632,13 +640,15 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) } if (reset_context) { - success = gst_vaapi_decoder_ensure_context( - GST_VAAPI_DECODER(decoder), - priv->profile, - entrypoint, - priv->width, priv->height - ); - if (!success) + GstVaapiContextInfo info; + + info.profile = priv->profile; + info.entrypoint = entrypoint; + info.width = priv->width; + info.height = priv->height; + 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; priv->has_context = TRUE; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c index 540b0e3..ddeb24d 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_jpeg.c @@ -137,11 +137,16 @@ ensure_context(GstVaapiDecoderJpeg *decoder) } 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), - priv->profile, - entrypoint, - priv->width, priv->height + &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 5e2c392..21bbee6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -410,11 +410,16 @@ ensure_context(GstVaapiDecoderMpeg2 *decoder) } 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), - priv->hw_profile, - entrypoint, - priv->width, priv->height + &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index 84e2020..f408cd6 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -205,11 +205,16 @@ ensure_context(GstVaapiDecoderMpeg4 *decoder) } 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), - priv->profile, - entrypoint, - priv->width, priv->height + &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h index 66646d3..c753c27 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_priv.h +++ b/gst-libs/gst/vaapi/gstvaapidecoder_priv.h @@ -159,11 +159,8 @@ gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced); G_GNUC_INTERNAL gboolean gst_vaapi_decoder_ensure_context( - GstVaapiDecoder *decoder, - GstVaapiProfile profile, - GstVaapiEntrypoint entrypoint, - guint width, - guint height + GstVaapiDecoder *decoder, + GstVaapiContextInfo *cip ); G_GNUC_INTERNAL diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c index 7ee0594..d54a18a 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_vc1.c @@ -194,11 +194,16 @@ ensure_context(GstVaapiDecoderVC1 *decoder) } 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), - priv->profile, - entrypoint, - priv->width, priv->height + &info ); if (!reset_context) return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; -- 2.7.4