summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-05-03 17:30:34 +0200
committerNicolas Dufresne <nicolas@ndufresne.ca>2020-05-19 16:57:09 +0000
commitd2aae6bb96b959840cb74559567f86135c8edb08 (patch)
tree2117cdd63614eea6e6ce281e5a0a3b9b3ab59f36
parent990392d595c336ddff8bce3d58406e9995c79ad9 (diff)
downloadgstreamer-plugins-bad-d2aae6bb96b959840cb74559567f86135c8edb08.tar.gz
codecs: h264decoder: ref pic lists as decode_slice parameters
Pass reference picture lists to decode_slice() vmethods Change gstv4l2codech264dec and gstnvh264dec accordingly. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1238>
-rw-r--r--gst-libs/gst/codecs/gsth264decoder.c69
-rw-r--r--gst-libs/gst/codecs/gsth264decoder.h9
-rw-r--r--sys/d3d11/gstd3d11h264dec.c6
-rw-r--r--sys/nvcodec/gstnvh264dec.c6
-rw-r--r--sys/v4l2codecs/gstv4l2codech264dec.c3
5 files changed, 58 insertions, 35 deletions
diff --git a/gst-libs/gst/codecs/gsth264decoder.c b/gst-libs/gst/codecs/gsth264decoder.c
index 57184bf0f..fe100e80e 100644
--- a/gst-libs/gst/codecs/gsth264decoder.c
+++ b/gst-libs/gst/codecs/gsth264decoder.c
@@ -137,6 +137,10 @@ struct _GstH264DecoderPrivate
GArray *ref_pic_list_b0;
GArray *ref_pic_list_b1;
+ /* Reference picture lists, constructed for each slice */
+ GArray *ref_pic_list0;
+ GArray *ref_pic_list1;
+
/* Cached array to handle pictures to be outputed */
GArray *to_output;
};
@@ -178,9 +182,8 @@ static gboolean gst_h264_decoder_finish_current_picture (GstH264Decoder * self);
static gboolean gst_h264_decoder_finish_picture (GstH264Decoder * self,
GstH264Picture * picture);
static void gst_h264_decoder_prepare_ref_pic_lists (GstH264Decoder * self);
-static gboolean gst_h264_decoder_modify_ref_pic_lists (GstH264Decoder * self,
- GPtrArray * ref_pic_l0, GPtrArray * ref_pic_l1);
static void gst_h264_decoder_clear_ref_pic_lists (GstH264Decoder * self);
+static gboolean gst_h264_decoder_modify_ref_pic_lists (GstH264Decoder * self);
static void
gst_h264_decoder_class_init (GstH264DecoderClass * klass)
@@ -224,6 +227,11 @@ gst_h264_decoder_init (GstH264Decoder * self)
g_array_set_clear_func (priv->ref_pic_list_b1,
(GDestroyNotify) gst_h264_picture_clear);
+ priv->ref_pic_list0 = g_array_sized_new (FALSE, TRUE,
+ sizeof (GstH264Picture *), 32);
+ priv->ref_pic_list1 = g_array_sized_new (FALSE, TRUE,
+ sizeof (GstH264Picture *), 32);
+
priv->to_output = g_array_sized_new (FALSE, TRUE,
sizeof (GstH264Picture *), 16);
g_array_set_clear_func (priv->to_output,
@@ -239,6 +247,8 @@ gst_h264_decoder_finalize (GObject * object)
g_array_unref (priv->ref_pic_list_p0);
g_array_unref (priv->ref_pic_list_b0);
g_array_unref (priv->ref_pic_list_b1);
+ g_array_unref (priv->ref_pic_list0);
+ g_array_unref (priv->ref_pic_list1);
g_array_unref (priv->to_output);
}
@@ -1924,7 +1934,8 @@ gst_h264_decoder_decode_slice (GstH264Decoder * self)
g_assert (klass->decode_slice);
- ret = klass->decode_slice (self, picture, slice);
+ ret = klass->decode_slice (self, picture, slice, ref_pic_list0,
+ ref_pic_list1);
if (!ret) {
GST_WARNING_OBJECT (self,
"Subclass didn't want to decode picture %p (frame_num %d, poc %d)",
@@ -2162,24 +2173,25 @@ pic_num_f (GstH264Decoder * self, const GstH264Picture * picture)
/* shift elements on the |array| starting from |from| to |to|,
* inclusive, one position to the right and insert pic at |from| */
static void
-shift_right_and_insert (GPtrArray * array, gint from, gint to,
+shift_right_and_insert (GArray * array, gint from, gint to,
GstH264Picture * picture)
{
g_return_if_fail (from <= to);
g_return_if_fail (array && picture);
- g_ptr_array_set_size (array, to + 2);
- g_ptr_array_insert (array, from, picture);
+ g_array_set_size (array, to + 2);
+ g_array_insert_val (array, from, picture);
}
/* This can process either ref_pic_list0 or ref_pic_list1, depending
* on the list argument. Set up pointers to proper list to be
* processed here. */
static gboolean
-modify_ref_pic_list (GstH264Decoder * self, int list, GPtrArray * ref_pic_listx)
+modify_ref_pic_list (GstH264Decoder * self, int list)
{
GstH264DecoderPrivate *priv = self->priv;
GstH264Picture *picture = priv->current_picture;
+ GArray *ref_pic_listx;
const GstH264SliceHdr *slice_hdr = &priv->current_slice.header;
const GstH264RefPicListModification *list_mod;
gboolean ref_pic_list_modification_flag_lX;
@@ -2194,12 +2206,14 @@ modify_ref_pic_list (GstH264Decoder * self, int list, GPtrArray * ref_pic_listx)
GstH264Picture *pic;
if (list == 0) {
+ ref_pic_listx = priv->ref_pic_list0;
ref_pic_list_modification_flag_lX =
slice_hdr->ref_pic_list_modification_flag_l0;
num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
num_ref_idx_lX_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1;
list_mod = slice_hdr->ref_pic_list_modification_l0;
} else {
+ ref_pic_listx = priv->ref_pic_list1;
ref_pic_list_modification_flag_lX =
slice_hdr->ref_pic_list_modification_flag_l1;
num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
@@ -2216,7 +2230,7 @@ modify_ref_pic_list (GstH264Decoder * self, int list, GPtrArray * ref_pic_listx)
* which must be handled by clients */
g_assert (num_ref_idx_lX_active_minus1 >= 0);
if (ref_pic_listx->len > num_ref_idx_lX_active_minus1 + 1)
- g_ptr_array_set_size (ref_pic_listx, num_ref_idx_lX_active_minus1 + 1);
+ g_array_set_size (ref_pic_listx, num_ref_idx_lX_active_minus1 + 1);
if (!ref_pic_list_modification_flag_lX)
return TRUE;
@@ -2270,10 +2284,11 @@ modify_ref_pic_list (GstH264Decoder * self, int list, GPtrArray * ref_pic_listx)
for (src = ref_idx_lx, dst = ref_idx_lx;
src <= num_ref_idx_lX_active_minus1 + 1; src++) {
- GstH264Picture *src_pic = g_ptr_array_index (ref_pic_listx, src);
+ GstH264Picture *src_pic =
+ g_array_index (ref_pic_listx, GstH264Picture *, src);
gint src_pic_num_lx = src_pic ? pic_num_f (self, src_pic) : -1;
if (src_pic_num_lx != pic_num_lx)
- g_ptr_array_index (ref_pic_listx, dst++) = src_pic;
+ g_array_index (ref_pic_listx, GstH264Picture *, dst++) = src_pic;
}
break;
@@ -2295,10 +2310,11 @@ modify_ref_pic_list (GstH264Decoder * self, int list, GPtrArray * ref_pic_listx)
for (src = ref_idx_lx, dst = ref_idx_lx;
src <= num_ref_idx_lX_active_minus1 + 1; src++) {
- GstH264Picture *src_pic = g_ptr_array_index (ref_pic_listx, src);
+ GstH264Picture *src_pic =
+ g_array_index (ref_pic_listx, GstH264Picture *, src);
if (long_term_pic_num_f (self, src_pic) !=
list_mod->value.long_term_pic_num)
- g_ptr_array_index (ref_pic_listx, dst++) = src_pic;
+ g_array_index (ref_pic_listx, GstH264Picture *, dst++) = src_pic;
}
break;
@@ -2322,39 +2338,36 @@ modify_ref_pic_list (GstH264Decoder * self, int list, GPtrArray * ref_pic_listx)
* temporarily made one element longer than the required final list.
* Resize the list back to its required size. */
if (ref_pic_listx->len > num_ref_idx_lX_active_minus1 + 1)
- g_ptr_array_set_size (ref_pic_listx, num_ref_idx_lX_active_minus1 + 1);
+ g_array_set_size (ref_pic_listx, num_ref_idx_lX_active_minus1 + 1);
return TRUE;
}
static void
-from_list_to_array (GPtrArray * array, GList * list)
+copy_pic_list_into (GArray * dest, GArray * src)
{
- GList *l;
+ gint i;
+ g_array_set_size (dest, 0);
- for (l = list; l; l = g_list_next (l))
- g_ptr_array_add (array, l->data);
+ for (i = 0; i < src->len; i++)
+ g_array_append_val (dest, g_array_index (src, gpointer, i));
}
static gboolean
-gst_h264_decoder_modify_ref_pic_lists (GstH264Decoder * self,
- GPtrArray * ref_pic_list0, GPtrArray * ref_pic_list1)
+gst_h264_decoder_modify_ref_pic_lists (GstH264Decoder * self)
{
GstH264DecoderPrivate *priv = self->priv;
GstH264SliceHdr *slice_hdr = &priv->current_slice.header;
- g_ptr_array_set_size (ref_pic_list0, 0);
- g_ptr_array_set_size (ref_pic_list1, 0);
-
/* fill reference picture lists for B and S/SP slices */
if (GST_H264_IS_P_SLICE (slice_hdr) || GST_H264_IS_SP_SLICE (slice_hdr)) {
- from_list_to_array (ref_pic_list0, priv->ref_pic_list_p0);
- return modify_ref_pic_list (self, 0, ref_pic_list0);
+ copy_pic_list_into (priv->ref_pic_list0, priv->ref_pic_list_p0);
+ return modify_ref_pic_list (self, 0);
} else {
- from_list_to_array (ref_pic_list0, priv->ref_pic_list_b0);
- from_list_to_array (ref_pic_list1, priv->ref_pic_list_b1);
- return modify_ref_pic_list (self, 0, ref_pic_list0)
- && modify_ref_pic_list (self, 1, ref_pic_list1);
+ copy_pic_list_into (priv->ref_pic_list0, priv->ref_pic_list_b0);
+ copy_pic_list_into (priv->ref_pic_list1, priv->ref_pic_list_b1);
+ return modify_ref_pic_list (self, 0)
+ && modify_ref_pic_list (self, 1);
}
return TRUE;
diff --git a/gst-libs/gst/codecs/gsth264decoder.h b/gst-libs/gst/codecs/gsth264decoder.h
index 0dbd25f3c..8272f547e 100644
--- a/gst-libs/gst/codecs/gsth264decoder.h
+++ b/gst-libs/gst/codecs/gsth264decoder.h
@@ -69,7 +69,10 @@ struct _GstH264Decoder
* Called per one #GstH264Picture to notify subclass to prepare
* decoding process for the #GstH264Picture
* @decode_slice: Provides per slice data with parsed slice header and
- * required raw bitstream for subclass to decode it
+ * required raw bitstream for subclass to decode it.
+ * if gst_h264_decoder_set_process_ref_pic_lists() is called
+ * with %TRUE by the subclass, @ref_pic_list0 and @ref_pic_list1
+ * are non-%NULL.
* @end_picture: Optional.
* Called per one #GstH264Picture to notify subclass to finish
* decoding process for the #GstH264Picture
@@ -97,7 +100,9 @@ struct _GstH264DecoderClass
gboolean (*decode_slice) (GstH264Decoder * decoder,
GstH264Picture * picture,
- GstH264Slice * slice);
+ GstH264Slice * slice,
+ GArray * ref_pic_list0,
+ GArray * ref_pic_list1);
gboolean (*end_picture) (GstH264Decoder * decoder,
GstH264Picture * picture);
diff --git a/sys/d3d11/gstd3d11h264dec.c b/sys/d3d11/gstd3d11h264dec.c
index efd8a0d9f..e180cfb07 100644
--- a/sys/d3d11/gstd3d11h264dec.c
+++ b/sys/d3d11/gstd3d11h264dec.c
@@ -157,7 +157,8 @@ static GstFlowReturn gst_d3d11_h264_dec_output_picture (GstH264Decoder *
static gboolean gst_d3d11_h264_dec_start_picture (GstH264Decoder * decoder,
GstH264Picture * picture, GstH264Slice * slice, GstH264Dpb * dpb);
static gboolean gst_d3d11_h264_dec_decode_slice (GstH264Decoder * decoder,
- GstH264Picture * picture, GstH264Slice * slice);
+ GstH264Picture * picture, GstH264Slice * slice, GArray * ref_pic_list0,
+ GArray * ref_pic_list1);
static gboolean gst_d3d11_h264_dec_end_picture (GstH264Decoder * decoder,
GstH264Picture * picture);
@@ -912,7 +913,8 @@ gst_d3d11_h264_dec_fill_picture_params (GstD3D11H264Dec * self,
static gboolean
gst_d3d11_h264_dec_decode_slice (GstH264Decoder * decoder,
- GstH264Picture * picture, GstH264Slice * slice)
+ GstH264Picture * picture, GstH264Slice * slice, GArray * ref_pic_list0,
+ GArray * ref_pic_list1)
{
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
GstH264SPS *sps;
diff --git a/sys/nvcodec/gstnvh264dec.c b/sys/nvcodec/gstnvh264dec.c
index 9db36d9c0..18984ad99 100644
--- a/sys/nvcodec/gstnvh264dec.c
+++ b/sys/nvcodec/gstnvh264dec.c
@@ -162,7 +162,8 @@ static GstFlowReturn gst_nv_h264_dec_output_picture (GstH264Decoder *
static gboolean gst_nv_h264_dec_start_picture (GstH264Decoder * decoder,
GstH264Picture * picture, GstH264Slice * slice, GstH264Dpb * dpb);
static gboolean gst_nv_h264_dec_decode_slice (GstH264Decoder * decoder,
- GstH264Picture * picture, GstH264Slice * slice);
+ GstH264Picture * picture, GstH264Slice * slice, GArray * ref_pic_list0,
+ GArray * ref_pic_list1);
static gboolean gst_nv_h264_dec_end_picture (GstH264Decoder * decoder,
GstH264Picture * picture);
@@ -907,7 +908,8 @@ gst_nv_h264_dec_start_picture (GstH264Decoder * decoder,
static gboolean
gst_nv_h264_dec_decode_slice (GstH264Decoder * decoder,
- GstH264Picture * picture, GstH264Slice * slice)
+ GstH264Picture * picture, GstH264Slice * slice, GArray * ref_pic_list0,
+ GArray * ref_pic_list1)
{
GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
gsize new_size;
diff --git a/sys/v4l2codecs/gstv4l2codech264dec.c b/sys/v4l2codecs/gstv4l2codech264dec.c
index 93b4d9379..a19556594 100644
--- a/sys/v4l2codecs/gstv4l2codech264dec.c
+++ b/sys/v4l2codecs/gstv4l2codech264dec.c
@@ -789,7 +789,8 @@ fail:
static gboolean
gst_v4l2_codec_h264_dec_decode_slice (GstH264Decoder * decoder,
- GstH264Picture * picture, GstH264Slice * slice)
+ GstH264Picture * picture, GstH264Slice * slice, GArray * ref_pic_list0,
+ GArray * ref_pic_list1)
{
GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder);