summaryrefslogtreecommitdiff
path: root/gst-libs/gst
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-11-13 16:35:30 +0100
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-11-16 16:50:31 +0100
commitead5043e8f7a767a5d21e22266bdce52c40cd00e (patch)
tree876738e89007422194f922b88210f557464c2587 /gst-libs/gst
parent1f183e52172aa45110dceb2a93c201dbf76c8c97 (diff)
h264: split remove_reference_at() into finer units.
Split remove_reference_at() into a function that actually removes the specified entry from the short-term or long-term reference picture array, and a function that sets reference flags to the desired value, possibly zero. The latters marks the picture as "unused for reference".
Diffstat (limited to 'gst-libs/gst')
-rw-r--r--gst-libs/gst/vaapi/gstvaapidecoder_h264.c128
1 files changed, 80 insertions, 48 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
index de9e035a..1b3e4f3e 100644
--- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
+++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c
@@ -181,6 +181,18 @@ gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
return GST_VAAPI_PICTURE_H264_CAST(object);
}
+static inline void
+gst_vaapi_picture_h264_set_reference(
+ GstVaapiPictureH264 *picture,
+ guint reference_flags
+)
+{
+ g_return_if_fail(GST_VAAPI_IS_PICTURE_H264(picture));
+
+ GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
+ GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
+}
+
static inline GstVaapiSliceH264 *
gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture)
{
@@ -527,6 +539,46 @@ get_max_dec_frame_buffering(GstH264SPS *sps)
}
static void
+array_remove_index_fast(void *array, guint *array_length_ptr, guint index)
+{
+ gpointer * const entries = array;
+ guint num_entries = *array_length_ptr;
+
+ g_return_if_fail(index < num_entries);
+
+ if (index != --num_entries)
+ entries[index] = entries[num_entries];
+ entries[num_entries] = NULL;
+ *array_length_ptr = num_entries;
+}
+
+#if 1
+static inline void
+array_remove_index(void *array, guint *array_length_ptr, guint index)
+{
+ array_remove_index_fast(array, array_length_ptr, index);
+}
+#else
+static void
+array_remove_index(void *array, guint *array_length_ptr, guint index)
+{
+ gpointer * const entries = array;
+ const guint num_entries = *array_length_ptr - 1;
+ guint i;
+
+ g_return_if_fail(index <= num_entries);
+
+ for (i = index; i < num_entries; i++)
+ entries[i] = entries[i + 1];
+ entries[num_entries] = NULL;
+ *array_length_ptr = num_entries;
+}
+#endif
+
+#define ARRAY_REMOVE_INDEX(array, index) \
+ array_remove_index(array, &array##_count, index)
+
+static void
dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
@@ -1602,29 +1654,6 @@ init_picture_refs_b_slice(
#undef SORT_REF_LIST
-static gboolean
-remove_reference_at(
- GstVaapiDecoderH264 *decoder,
- GstVaapiPictureH264 **pictures,
- guint *picture_count,
- guint index
-)
-{
- guint num_pictures = *picture_count;
- GstVaapiPictureH264 *picture;
-
- g_return_val_if_fail(index < num_pictures, FALSE);
-
- picture = pictures[index];
- GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
-
- if (index != --num_pictures)
- pictures[index] = pictures[num_pictures];
- pictures[num_pictures] = NULL;
- *picture_count = num_pictures;
- return TRUE;
-}
-
static gint
find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
{
@@ -1966,8 +1995,8 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
GstVaapiDecoderH264Private * const priv = decoder->priv;
GstH264PPS * const pps = priv->current_picture->pps;
GstH264SPS * const sps = pps->sequence;
- guint i, max_num_ref_frames, lowest_frame_num_index;
- gint32 lowest_frame_num;
+ GstVaapiPictureH264 *ref_picture;
+ guint i, m, max_num_ref_frames;
GST_DEBUG("reference picture marking process (sliding window)");
@@ -1980,20 +2009,15 @@ exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
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;
- }
+ for (m = 0, i = 1; i < priv->short_ref_count; i++) {
+ GstVaapiPictureH264 * const picture = priv->short_ref[i];
+ if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap)
+ m = i;
}
- remove_reference_at(
- decoder,
- priv->short_ref, &priv->short_ref_count,
- lowest_frame_num_index
- );
+ ref_picture = priv->short_ref[m];
+ gst_vaapi_picture_h264_set_reference(ref_picture, 0);
+ ARRAY_REMOVE_INDEX(priv->short_ref, m);
return TRUE;
}
@@ -2025,7 +2049,9 @@ exec_ref_pic_marking_adaptive_mmco_1(
i = find_short_term_reference(decoder, picNumX);
if (i < 0)
return;
- remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i);
+
+ gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0);
+ ARRAY_REMOVE_INDEX(priv->short_ref, i);
}
/* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
@@ -2042,7 +2068,9 @@ exec_ref_pic_marking_adaptive_mmco_2(
i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
if (i < 0)
return;
- remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
+
+ gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0);
+ ARRAY_REMOVE_INDEX(priv->long_ref, i);
}
/* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
@@ -2054,26 +2082,29 @@ exec_ref_pic_marking_adaptive_mmco_3(
)
{
GstVaapiDecoderH264Private * const priv = decoder->priv;
+ GstVaapiPictureH264 *ref_picture;
gint32 i, picNumX;
for (i = 0; i < priv->long_ref_count; i++) {
if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
break;
}
- if (i != priv->long_ref_count)
- remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
+ if (i != priv->long_ref_count) {
+ gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0);
+ ARRAY_REMOVE_INDEX(priv->long_ref, i);
+ }
picNumX = get_picNumX(picture, ref_pic_marking);
i = find_short_term_reference(decoder, picNumX);
if (i < 0)
return;
- picture = priv->short_ref[i];
- remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i);
- priv->long_ref[priv->long_ref_count++] = picture;
+ ref_picture = priv->short_ref[i];
+ ARRAY_REMOVE_INDEX(priv->short_ref, i);
+ priv->long_ref[priv->long_ref_count++] = ref_picture;
- picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
- GST_VAAPI_PICTURE_FLAG_SET(picture,
+ ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
+ gst_vaapi_picture_h264_set_reference(ref_picture,
GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
}
@@ -2094,7 +2125,8 @@ exec_ref_pic_marking_adaptive_mmco_4(
for (i = 0; i < priv->long_ref_count; i++) {
if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
continue;
- remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
+ gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0);
+ ARRAY_REMOVE_INDEX(priv->long_ref, i);
i--;
}
}
@@ -2135,7 +2167,7 @@ exec_ref_pic_marking_adaptive_mmco_6(
)
{
picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
- GST_VAAPI_PICTURE_FLAG_SET(picture,
+ gst_vaapi_picture_h264_set_reference(picture,
GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
}