mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 11:55:39 +00:00
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:
parent
9169c520cb
commit
850d3d6a4d
1 changed files with 12 additions and 18 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue