From 850d3d6a4d7579716b8f2beadf66b67be4574675 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Sat, 28 Jun 2014 07:25:35 +0200 Subject: [PATCH] decoder: h264: fix tracking of DPB size changes. Add support for MVC streams with multiple SPS and subset SPS headers emitted regularly, e.g. at around every I-frame. Track the maximum number of views in ensure_context() and really reset the DPB size to the expected value, always. i.e. even if it decreased. dpb_reset() only cares of ensuring the DPB allocation. --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 24d1aae..2db5073 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -985,9 +985,6 @@ dpb_reset(GstVaapiDecoderH264 *decoder, guint dpb_size) { GstVaapiDecoderH264Private * const priv = &decoder->priv; - if (dpb_size < priv->dpb_count) - return FALSE; - if (dpb_size > priv->dpb_size_max) { priv->dpb = g_try_realloc_n(priv->dpb, dpb_size, sizeof(*priv->dpb)); if (!priv->dpb) @@ -996,11 +993,7 @@ dpb_reset(GstVaapiDecoderH264 *decoder, guint dpb_size) (dpb_size - priv->dpb_size_max) * sizeof(*priv->dpb)); priv->dpb_size_max = dpb_size; } - - if (priv->dpb_size < dpb_size) - priv->dpb_size = dpb_size; - else if (dpb_size < priv->dpb_count) - return FALSE; + priv->dpb_size = dpb_size; GST_DEBUG("DPB size %u", priv->dpb_size); return TRUE; @@ -1300,7 +1293,13 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps) GstVaapiProfile profile; GstVaapiChromaType chroma_type; gboolean reset_context = FALSE; - guint mb_width, mb_height, dpb_size; + guint mb_width, mb_height, dpb_size, num_views; + + num_views = get_num_views(sps); + if (priv->max_views < num_views) { + priv->max_views = num_views; + GST_DEBUG("maximum number of views changed to %u", num_views); + } dpb_size = get_max_dec_frame_buffering(sps); if (priv->dpb_size < dpb_size) { @@ -1495,9 +1494,6 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) if (result != GST_H264_PARSER_OK) return get_status(result); - /* Reset defaults */ - priv->max_views = 1; - priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; return GST_VAAPI_DECODER_STATUS_SUCCESS; } @@ -1577,7 +1573,6 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) GstH264NalUnit * const nalu = &pi->nalu; GstH264SPS *sps; GstH264ParserResult result; - guint num_views; GST_DEBUG("parse slice"); @@ -1625,11 +1620,6 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) sps = slice_hdr->pps->sequence; /* Update MVC data */ - num_views = get_num_views(sps); - if (priv->max_views < num_views) { - priv->max_views = num_views; - GST_DEBUG("maximum number of views changed to %u", num_views); - } pi->view_id = get_view_id(&pi->nalu); pi->voc = get_view_order_index(sps, pi->view_id); @@ -1679,6 +1669,7 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit) static GstVaapiDecoderStatus decode_sequence_end(GstVaapiDecoderH264 *decoder) { + GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDecoderStatus status; GST_DEBUG("decode sequence-end"); @@ -1688,6 +1679,9 @@ decode_sequence_end(GstVaapiDecoderH264 *decoder) return status; dpb_flush(decoder, NULL); + + /* Reset defaults, should there be a new sequence available next */ + priv->max_views = 1; return GST_VAAPI_DECODER_STATUS_SUCCESS; } -- 2.7.4