diff options
-rw-r--r-- | gst-libs/gst/codecs/gsth264decoder.c | 69 | ||||
-rw-r--r-- | gst-libs/gst/codecs/gsth264decoder.h | 9 | ||||
-rw-r--r-- | sys/d3d11/gstd3d11h264dec.c | 6 | ||||
-rw-r--r-- | sys/nvcodec/gstnvh264dec.c | 6 | ||||
-rw-r--r-- | sys/v4l2codecs/gstv4l2codech264dec.c | 3 |
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); |