decoder: h264: simplify the DPB output process.

Simplify the dpb_output() function to exclusively rely on the frame store
buffer to output, since this is now always provided. Besides, also fix
cases where split fields would not be displayed.

This is a regression from f48b1e0.
This commit is contained in:
Gwenole Beauchesne 2014-07-03 11:13:33 +02:00
parent e6cdacee65
commit a3e49d6d13

View file

@ -326,7 +326,12 @@ gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture)
fs->buffers[0] = gst_vaapi_picture_ref(picture); fs->buffers[0] = gst_vaapi_picture_ref(picture);
fs->buffers[1] = NULL; fs->buffers[1] = NULL;
fs->num_buffers = 1; fs->num_buffers = 1;
fs->output_needed = picture->output_needed; fs->output_needed = 0;
if (picture->output_flag) {
picture->output_needed = TRUE;
fs->output_needed++;
}
return fs; return fs;
} }
@ -390,6 +395,13 @@ gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs)
return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME; return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME;
} }
static inline gboolean
gst_vaapi_frame_store_is_complete(GstVaapiFrameStore *fs)
{
return gst_vaapi_frame_store_has_frame(fs) ||
GST_VAAPI_PICTURE_IS_ONEFIELD(fs->buffers[0]);
}
static inline gboolean static inline gboolean
gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs) gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs)
{ {
@ -684,19 +696,26 @@ dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
} }
static gboolean static gboolean
dpb_output( dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiFrameStore *fs)
GstVaapiDecoderH264 *decoder,
GstVaapiFrameStore *fs,
GstVaapiPictureH264 *picture
)
{ {
GstVaapiPictureH264 *picture;
g_return_val_if_fail(fs != NULL, FALSE);
if (!gst_vaapi_frame_store_is_complete(fs))
return TRUE;
picture = fs->buffers[0];
g_return_val_if_fail(picture != NULL, FALSE);
picture->output_needed = FALSE; picture->output_needed = FALSE;
if (--fs->output_needed > 0) if (fs->num_buffers > 1) {
return TRUE; picture = fs->buffers[1];
g_return_val_if_fail(picture != NULL, FALSE);
picture->output_needed = FALSE;
}
if (!GST_VAAPI_PICTURE_IS_COMPLETE(picture)) fs->output_needed = 0;
return TRUE;
return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture)); return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
} }
@ -805,7 +824,7 @@ dpb_output_other_views(GstVaapiDecoderH264 *decoder,
&found_picture); &found_picture);
if (found_index < 0 || found_picture->base.voc >= voc) if (found_index < 0 || found_picture->base.voc >= voc)
break; break;
success = dpb_output(decoder, priv->dpb[found_index], found_picture); success = dpb_output(decoder, priv->dpb[found_index]);
dpb_evict(decoder, found_picture, found_index); dpb_evict(decoder, found_picture, found_index);
if (!success) if (!success)
return FALSE; return FALSE;
@ -828,7 +847,7 @@ dpb_bump(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
if (picture && picture->base.poc != found_picture->base.poc) if (picture && picture->base.poc != found_picture->base.poc)
dpb_output_other_views(decoder, found_picture, found_picture->base.voc); dpb_output_other_views(decoder, found_picture, found_picture->base.voc);
success = dpb_output(decoder, priv->dpb[found_index], found_picture); success = dpb_output(decoder, priv->dpb[found_index]);
dpb_evict(decoder, found_picture, found_index); dpb_evict(decoder, found_picture, found_index);
if (priv->max_views == 1) if (priv->max_views == 1)
return success; return success;
@ -938,7 +957,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
if (fs && &fs->buffers[0]->base == picture->base.parent_picture) { if (fs && &fs->buffers[0]->base == picture->base.parent_picture) {
if (!gst_vaapi_frame_store_add(fs, picture)) if (!gst_vaapi_frame_store_add(fs, picture))
return FALSE; return FALSE;
return dpb_output(decoder, fs, picture); return dpb_output(decoder, fs);
} }
} }
@ -949,11 +968,6 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
gst_vaapi_frame_store_replace(&priv->prev_frames[picture->base.voc], fs); gst_vaapi_frame_store_replace(&priv->prev_frames[picture->base.voc], fs);
gst_vaapi_frame_store_unref(fs); gst_vaapi_frame_store_unref(fs);
if (picture->output_flag) {
picture->output_needed = TRUE;
fs->output_needed++;
}
if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) { if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) {
if (!gst_vaapi_frame_store_split_fields(fs)) if (!gst_vaapi_frame_store_split_fields(fs))
return FALSE; return FALSE;
@ -981,7 +995,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
if (!StoreInterViewOnlyRefFlag) { if (!StoreInterViewOnlyRefFlag) {
if (dpb_find_lowest_poc(decoder, picture, &found_picture) < 0 || if (dpb_find_lowest_poc(decoder, picture, &found_picture) < 0 ||
found_picture->base.poc > picture->base.poc) found_picture->base.poc > picture->base.poc)
return dpb_output(decoder, fs, picture); return dpb_output(decoder, fs);
} }
if (!dpb_bump(decoder, picture)) if (!dpb_bump(decoder, picture))
return FALSE; return FALSE;