summaryrefslogtreecommitdiff
path: root/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-01-18 13:38:34 +0100
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-01-29 15:27:59 +0100
commit16ccf82363909e5e66c02319f1589c96ff69ec12 (patch)
tree85657ce4bb1474049cd22c72fb9bcdd7f1444571 /gst-libs/gst/vaapi/gstvaapidecoder_h264.c
parent5a795b439c5009cb660d69191f9a1522f1618052 (diff)
h264: execute reference picture marking process (sliding window).
Diffstat (limited to 'gst-libs/gst/vaapi/gstvaapidecoder_h264.c')
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_h264.c128
1 files changed, 114 insertions, 14 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
index 835c6607..78ca3863 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
@@ -320,6 +320,16 @@ get_status(GstH264ParserResult result)
return status;
}
+static inline GstH264DecRefPicMarking *
+get_dec_ref_pic_marking(GstVaapiPictureH264 *picture_h264)
+{
+ GstVaapiPicture * const picture = GST_VAAPI_PICTURE_CAST(picture_h264);
+ GstVaapiSliceH264 *slice;
+
+ slice = g_ptr_array_index(picture->slices, picture->slices->len - 1);
+ return &slice->slice_hdr.dec_ref_pic_marking;
+}
+
static void
gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
{
@@ -1066,6 +1076,25 @@ clear_references(
*picture_count = 0;
}
+static gboolean
+remove_reference_at(
+ GstVaapiDecoderH264 *decoder,
+ GstVaapiPictureH264 **pictures,
+ guint *picture_count,
+ guint index
+)
+{
+ guint num_pictures = *picture_count;
+
+ g_return_val_if_fail(index < num_pictures, FALSE);
+
+ if (index != --num_pictures)
+ gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]);
+ gst_vaapi_picture_replace(&pictures[num_pictures], NULL);
+ *picture_count = num_pictures;
+ return TRUE;
+}
+
static gint
find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
{
@@ -1302,6 +1331,7 @@ init_picture(
priv->frame_num = slice_hdr->frame_num;
picture->frame_num = priv->frame_num;
+ picture->frame_num_wrap = priv->frame_num;
picture->is_idr = nalu->type == GST_H264_NAL_SLICE_IDR;
picture->field_pic_flag = slice_hdr->field_pic_flag;
picture->bottom_field_flag = slice_hdr->bottom_field_flag;
@@ -1383,6 +1413,88 @@ init_picture(
return TRUE;
}
+/* 8.2.5.3 - Sliding window decoded reference picture marking process */
+static gboolean
+exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
+{
+ GstVaapiDecoderH264Private * const priv = decoder->priv;
+ GstH264SPS * const sps = priv->sps;
+ guint i, max_num_ref_frames, lowest_frame_num_index;
+ gint32 lowest_frame_num;
+
+ GST_DEBUG("reference picture marking process (sliding window)");
+
+ max_num_ref_frames = sps->num_ref_frames;
+ if (max_num_ref_frames == 0)
+ max_num_ref_frames = 1;
+
+ if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
+ return TRUE;
+ if (priv->short_ref_count < 1)
+ return FALSE;
+
+ lowest_frame_num = priv->short_ref[0]->frame_num_wrap;
+ lowest_frame_num_index = 0;
+ for (i = 1; i < priv->short_ref_count; i++) {
+ if (priv->short_ref[i]->frame_num_wrap < lowest_frame_num) {
+ lowest_frame_num = priv->short_ref[i]->frame_num_wrap;
+ lowest_frame_num_index = i;
+ }
+ }
+
+ remove_reference_at(
+ decoder,
+ priv->short_ref, &priv->short_ref_count,
+ lowest_frame_num_index
+ );
+ return TRUE;
+}
+
+/* 8.2.5.4 - Adaptive memory control decoded reference picture marking process */
+static gboolean
+exec_ref_pic_marking_adaptive(
+ GstVaapiDecoderH264 *decoder,
+ GstH264DecRefPicMarking *dec_ref_pic_marking
+)
+{
+ GstVaapiDecoderH264Private * const priv = decoder->priv;
+
+ GST_DEBUG("reference picture marking process (adaptive memory control)");
+
+ return TRUE;
+}
+
+/* 8.2.5 - Execute reference picture marking process */
+static gboolean
+exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
+{
+ GstVaapiDecoderH264Private * const priv = decoder->priv;
+ GstVaapiPictureH264 **picture_ptr;
+
+ if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
+ return TRUE;
+
+ if (!picture->is_idr) {
+ GstH264DecRefPicMarking * const dec_ref_pic_marking =
+ get_dec_ref_pic_marking(picture);
+ if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
+ if (!exec_ref_pic_marking_adaptive(decoder, dec_ref_pic_marking))
+ return FALSE;
+ }
+ else {
+ if (!exec_ref_pic_marking_sliding_window(decoder))
+ return FALSE;
+ }
+ }
+
+ if (picture->is_long_term)
+ picture_ptr = &priv->long_ref[priv->long_ref_count++];
+ else
+ picture_ptr = &priv->short_ref[priv->short_ref_count++];
+ gst_vaapi_picture_replace(picture_ptr, picture);
+ return TRUE;
+}
+
/* Update picture order count */
static void
exit_picture_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
@@ -1420,24 +1532,12 @@ exit_picture_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
static inline gboolean
exit_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
{
- GstVaapiDecoderH264Private * const priv = decoder->priv;
- GstVaapiPictureH264 **picture_ptr;
-
/* Update picture order count */
exit_picture_poc(decoder, picture);
/* Decoded reference picture marking process */
- if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
- return TRUE;
- if (picture->is_long_term) {
- g_assert(priv->long_ref_count < G_N_ELEMENTS(priv->long_ref));
- picture_ptr = &priv->long_ref[priv->long_ref_count++];
- }
- else {
- g_assert(priv->short_ref_count < G_N_ELEMENTS(priv->short_ref));
- picture_ptr = &priv->short_ref[priv->short_ref_count++];
- }
- gst_vaapi_picture_replace(picture_ptr, picture);
+ if (!exec_ref_pic_marking(decoder, picture))
+ return FALSE;
return TRUE;
}