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.
This commit is contained in:
Gwenole Beauchesne 2014-06-28 07:25:35 +02:00
parent 9169c520cb
commit 850d3d6a4d

View file

@ -985,9 +985,6 @@ dpb_reset(GstVaapiDecoderH264 *decoder, guint dpb_size)
{ {
GstVaapiDecoderH264Private * const priv = &decoder->priv; GstVaapiDecoderH264Private * const priv = &decoder->priv;
if (dpb_size < priv->dpb_count)
return FALSE;
if (dpb_size > priv->dpb_size_max) { if (dpb_size > priv->dpb_size_max) {
priv->dpb = g_try_realloc_n(priv->dpb, dpb_size, sizeof(*priv->dpb)); priv->dpb = g_try_realloc_n(priv->dpb, dpb_size, sizeof(*priv->dpb));
if (!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)); (dpb_size - priv->dpb_size_max) * sizeof(*priv->dpb));
priv->dpb_size_max = dpb_size; priv->dpb_size_max = dpb_size;
} }
priv->dpb_size = dpb_size;
if (priv->dpb_size < dpb_size)
priv->dpb_size = dpb_size;
else if (dpb_size < priv->dpb_count)
return FALSE;
GST_DEBUG("DPB size %u", priv->dpb_size); GST_DEBUG("DPB size %u", priv->dpb_size);
return TRUE; return TRUE;
@ -1300,7 +1293,13 @@ ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
GstVaapiProfile profile; GstVaapiProfile profile;
GstVaapiChromaType chroma_type; GstVaapiChromaType chroma_type;
gboolean reset_context = FALSE; 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); dpb_size = get_max_dec_frame_buffering(sps);
if (priv->dpb_size < dpb_size) { if (priv->dpb_size < dpb_size) {
@ -1495,9 +1494,6 @@ parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
if (result != GST_H264_PARSER_OK) if (result != GST_H264_PARSER_OK)
return get_status(result); return get_status(result);
/* Reset defaults */
priv->max_views = 1;
priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS; priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS;
return GST_VAAPI_DECODER_STATUS_SUCCESS; return GST_VAAPI_DECODER_STATUS_SUCCESS;
} }
@ -1577,7 +1573,6 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
GstH264NalUnit * const nalu = &pi->nalu; GstH264NalUnit * const nalu = &pi->nalu;
GstH264SPS *sps; GstH264SPS *sps;
GstH264ParserResult result; GstH264ParserResult result;
guint num_views;
GST_DEBUG("parse slice"); GST_DEBUG("parse slice");
@ -1625,11 +1620,6 @@ parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
sps = slice_hdr->pps->sequence; sps = slice_hdr->pps->sequence;
/* Update MVC data */ /* 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->view_id = get_view_id(&pi->nalu);
pi->voc = get_view_order_index(sps, pi->view_id); pi->voc = get_view_order_index(sps, pi->view_id);
@ -1679,6 +1669,7 @@ decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
static GstVaapiDecoderStatus static GstVaapiDecoderStatus
decode_sequence_end(GstVaapiDecoderH264 *decoder) decode_sequence_end(GstVaapiDecoderH264 *decoder)
{ {
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiDecoderStatus status; GstVaapiDecoderStatus status;
GST_DEBUG("decode sequence-end"); GST_DEBUG("decode sequence-end");
@ -1688,6 +1679,9 @@ decode_sequence_end(GstVaapiDecoderH264 *decoder)
return status; return status;
dpb_flush(decoder, NULL); dpb_flush(decoder, NULL);
/* Reset defaults, should there be a new sequence available next */
priv->max_views = 1;
return GST_VAAPI_DECODER_STATUS_SUCCESS; return GST_VAAPI_DECODER_STATUS_SUCCESS;
} }