decoder: h264: improve DPB bumping process for MVC.

While invoking the DPB bumping process in presence of many views,
it could be necessary to output previous pictures that are ready,
in a whole. i.e. emitting all view components from the very first
view order index zero to the very last one in its original access
unit; and not starting from the view order index of the picture
that caused the DPB bumping process to be invoked.

As a reminder, the maximum number of frames in DPB for MultiView
High profile with more than 2 views is not necessarily a multiple
of the number of views.

This fixes decoding of MVCNV-4.264.
This commit is contained in:
Gwenole Beauchesne 2014-06-03 17:36:38 +02:00
parent e8fe78824b
commit 42ab3e0669

View file

@ -770,6 +770,34 @@ dpb_find_lowest_voc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture,
return found_picture ? found_index : -1;
}
static gboolean
dpb_output_other_views(GstVaapiDecoderH264 *decoder,
GstVaapiPictureH264 *picture, guint voc)
{
GstVaapiDecoderH264Private * const priv = &decoder->priv;
GstVaapiPictureH264 *found_picture;
gint found_index;
gboolean success;
if (priv->max_views == 1)
return TRUE;
/* Emit all other view components that were in the same access
unit than the picture we have just found */
found_picture = picture;
for (;;) {
found_index = dpb_find_lowest_voc(decoder, found_picture,
&found_picture);
if (found_index < 0 || found_picture->base.voc >= voc)
break;
success = dpb_output(decoder, priv->dpb[found_index], found_picture);
dpb_evict(decoder, found_picture, found_index);
if (!success)
return FALSE;
}
return TRUE;
}
static gboolean
dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
{
@ -782,21 +810,16 @@ dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
if (found_index < 0)
return FALSE;
if (picture && picture->base.poc != found_picture->base.poc)
dpb_output_other_views(decoder, found_picture, found_picture->base.voc);
success = dpb_output(decoder, priv->dpb[found_index], found_picture);
dpb_evict(decoder, found_picture, found_index);
if (priv->max_views == 1)
return success;
/* Emit all other view components that were in the same access
unit than the picture we have just found */
for (;;) {
found_index = dpb_find_lowest_voc(decoder, found_picture,
&found_picture);
if (found_index < 0)
break;
dpb_output(decoder, priv->dpb[found_index], found_picture);
dpb_evict(decoder, found_picture, found_index);
}
if (picture && picture->base.poc != found_picture->base.poc)
dpb_output_other_views(decoder, found_picture, G_MAXUINT32);
return success;
}