From ea3dfadbedf85e24086e6cb9449e063f22e99016 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Tue, 5 Sep 2023 21:27:30 +0900 Subject: [PATCH] h264decoder: Port to GstCodecPicture struct Part-of: --- .../gst-libs/gst/codecs/gsth264decoder.c | 24 ++++---- .../gst-libs/gst/codecs/gsth264decoder.h | 4 +- .../gst-libs/gst/codecs/gsth264picture.c | 57 +------------------ .../gst-libs/gst/codecs/gsth264picture.h | 38 +++++++------ .../sys/d3d11/gstd3d11h264dec.cpp | 4 +- .../sys/nvcodec/gstnvh264dec.cpp | 3 +- .../sys/v4l2codecs/gstv4l2codech264dec.c | 20 ++++--- .../gst-plugins-bad/sys/va/gstvah264dec.c | 4 +- 8 files changed, 57 insertions(+), 97 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264decoder.c b/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264decoder.c index 065ae668eb..fb19179b6a 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264decoder.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264decoder.c @@ -473,7 +473,7 @@ gst_h264_decoder_clear_dpb (GstH264Decoder * self, gboolean flush) if (!flush) { while ((picture = gst_h264_dpb_bump (priv->dpb, TRUE)) != NULL) { GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder, - picture->system_frame_number); + GST_CODEC_PICTURE_FRAME_NUMBER (picture)); if (frame) gst_video_decoder_release_frame (decoder, frame); @@ -796,7 +796,7 @@ gst_h264_decoder_split_frame (GstH264Decoder * self, GstH264Picture * picture) other_field->frame_num = picture->frame_num; other_field->ref = picture->ref; other_field->nonexisting = picture->nonexisting; - other_field->system_frame_number = picture->system_frame_number; + GST_CODEC_PICTURE_COPY_FRAME_NUMBER (other_field, picture); other_field->field_pic_flag = picture->field_pic_flag; return other_field; @@ -1034,11 +1034,12 @@ gst_h264_decoder_start_current_picture (GstH264Decoder * self) g_assert (priv->active_sps != NULL); g_assert (priv->active_pps != NULL); + current_picture = priv->current_picture; + /* If subclass didn't update output state at this point, * marking this picture as a discont and stores current input state */ if (priv->input_state_changed) { - priv->current_picture->discont_state = - gst_video_codec_state_ref (self->input_state); + gst_h264_picture_set_discont_state (current_picture, self->input_state); priv->input_state_changed = FALSE; } @@ -1056,8 +1057,6 @@ gst_h264_decoder_start_current_picture (GstH264Decoder * self) if (!gst_h264_decoder_init_current_picture (self)) return GST_FLOW_ERROR; - current_picture = priv->current_picture; - /* If the new picture is an IDR, flush DPB */ if (current_picture->idr) { if (!current_picture->dec_ref_pic_marking.no_output_of_prior_pics_flag) { @@ -1294,7 +1293,8 @@ gst_h264_decoder_parse_slice (GstH264Decoder * self, GstH264NalUnit * nalu) } /* This allows accessing the frame from the picture. */ - picture->system_frame_number = priv->current_frame->system_frame_number; + GST_CODEC_PICTURE_FRAME_NUMBER (picture) = + priv->current_frame->system_frame_number; priv->current_picture = picture; ret = gst_h264_decoder_start_current_picture (self); @@ -1798,7 +1798,7 @@ gst_h264_decoder_do_output_picture (GstH264Decoder * self, #endif frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self), - picture->system_frame_number); + GST_CODEC_PICTURE_FRAME_NUMBER (picture)); if (!frame) { /* The case where the end_picture() got failed and corresponding @@ -1808,7 +1808,7 @@ gst_h264_decoder_do_output_picture (GstH264Decoder * self, } else { GST_ERROR_OBJECT (self, "No available codec frame with frame number %d", - picture->system_frame_number); + GST_CODEC_PICTURE_FRAME_NUMBER (picture)); UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR); } @@ -2109,10 +2109,10 @@ gst_h264_decoder_finish_picture (GstH264Decoder * self, * drop codec frame of the second field because we are consuming * only the first codec frame via GstH264Decoder::output_picture() method */ if (picture->second_field && picture->other_field && - picture->system_frame_number != - picture->other_field->system_frame_number) { + GST_CODEC_PICTURE_FRAME_NUMBER (picture) != + GST_CODEC_PICTURE_FRAME_NUMBER (picture->other_field)) { GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder, - picture->system_frame_number); + GST_CODEC_PICTURE_FRAME_NUMBER (picture)); gst_video_decoder_release_frame (decoder, frame); } diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264decoder.h b/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264decoder.h index faf66de450..72e0c7886d 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264decoder.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264decoder.h @@ -132,7 +132,7 @@ struct _GstH264DecoderClass * * Optional. Called whenever new #GstH264Picture is created. * Subclass can set implementation specific user data - * on the #GstH264Picture via gst_h264_picture_set_user_data() + * on the #GstH264Picture via gst_h264_picture_set_user_data */ GstFlowReturn (*new_picture) (GstH264Decoder * decoder, GstVideoCodecFrame * frame, @@ -146,7 +146,7 @@ struct _GstH264DecoderClass * * Called when a new field picture is created for interlaced field picture. * Subclass can attach implementation specific user data on @second_field via - * gst_h264_picture_set_user_data() + * gst_h264_picture_set_user_data * * Since: 1.20 */ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264picture.c b/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264picture.c index 0511302b3d..b49bfcd0d2 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264picture.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264picture.c @@ -22,6 +22,7 @@ #endif #include "gsth264picture-private.h" +#include "gstcodecpicture-private.h" #include @@ -30,18 +31,6 @@ GST_DEBUG_CATEGORY_EXTERN (gst_h264_decoder_debug); GST_DEFINE_MINI_OBJECT_TYPE (GstH264Picture, gst_h264_picture); -static void -_gst_h264_picture_free (GstH264Picture * picture) -{ - if (picture->notify) - picture->notify (picture->user_data); - - if (picture->discont_state) - gst_video_codec_state_unref (picture->discont_state); - - g_free (picture); -} - /** * gst_h264_picture_new: * @@ -62,51 +51,11 @@ gst_h264_picture_new (void) gst_mini_object_init (GST_MINI_OBJECT_CAST (pic), 0, GST_TYPE_H264_PICTURE, NULL, NULL, - (GstMiniObjectFreeFunction) _gst_h264_picture_free); + (GstMiniObjectFreeFunction) gst_codec_picture_free); return pic; } -/** - * gst_h264_picture_set_user_data: - * @picture: a #GstH264Picture - * @user_data: (nullable): private data - * @notify: (closure user_data): a #GDestroyNotify - * - * Sets @user_data on the picture and the #GDestroyNotify that will be called when - * the picture is freed. - * - * If a @user_data was previously set, then the previous set @notify will be called - * before the @user_data is replaced. - */ -void -gst_h264_picture_set_user_data (GstH264Picture * picture, gpointer user_data, - GDestroyNotify notify) -{ - g_return_if_fail (GST_IS_H264_PICTURE (picture)); - - if (picture->notify) - picture->notify (picture->user_data); - - picture->user_data = user_data; - picture->notify = notify; -} - -/** - * gst_h264_picture_get_user_data: - * @picture: a #GstH264Picture - * - * Gets private data set on the picture via - * gst_h264_picture_set_user_data() previously. - * - * Returns: (transfer none) (nullable): The previously set user_data - */ -gpointer -gst_h264_picture_get_user_data (GstH264Picture * picture) -{ - return picture->user_data; -} - struct _GstH264Dpb { GArray *pic_list; @@ -646,7 +595,7 @@ gst_h264_dpb_get_picture (GstH264Dpb * dpb, guint32 system_frame_number) GstH264Picture *picture = g_array_index (dpb->pic_list, GstH264Picture *, i); - if (picture->system_frame_number == system_frame_number) { + if (GST_CODEC_PICTURE_FRAME_NUMBER (picture) == system_frame_number) { gst_h264_picture_ref (picture); return picture; } diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264picture.h b/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264picture.h index 73547066d8..e458f01384 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264picture.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/codecs/gsth264picture.h @@ -21,6 +21,7 @@ #define __GST_H264_PICTURE_H__ #include +#include #include #include @@ -114,13 +115,10 @@ typedef enum struct _GstH264Picture { /*< private >*/ - GstMiniObject parent; + GstCodecPicture parent; GstH264SliceType type; - /* From GstVideoCodecFrame */ - guint32 system_frame_number; - guint8 pic_order_cnt_type; /* SPS */ gint32 top_field_order_cnt; gint32 bottom_field_order_cnt; @@ -160,12 +158,6 @@ struct _GstH264Picture GstH264Picture * other_field; GstVideoBufferFlags buffer_flags; - - /* decoder input state if this picture is discont point */ - GstVideoCodecState *discont_state; - - gpointer user_data; - GDestroyNotify notify; }; /** @@ -218,13 +210,27 @@ gst_clear_h264_picture (GstH264Picture ** picture) } } -GST_CODECS_API -void gst_h264_picture_set_user_data (GstH264Picture * picture, - gpointer user_data, - GDestroyNotify notify); +static inline void +gst_h264_picture_set_user_data (GstH264Picture * picture, gpointer user_data, + GDestroyNotify notify) +{ + gst_codec_picture_set_user_data (GST_CODEC_PICTURE (picture), + user_data, notify); +} -GST_CODECS_API -gpointer gst_h264_picture_get_user_data (GstH264Picture * picture); +static inline gpointer +gst_h264_picture_get_user_data (GstH264Picture * picture) +{ + return gst_codec_picture_get_user_data (GST_CODEC_PICTURE (picture)); +} + +static inline void +gst_h264_picture_set_discont_state (GstH264Picture * picture, + GstVideoCodecState * discont_state) +{ + gst_codec_picture_set_discont_state (GST_CODEC_PICTURE (picture), + discont_state); +} /******************* * GstH264Dpb * diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11h264dec.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11h264dec.cpp index 43499ad4ae..f428fde1ad 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11h264dec.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11h264dec.cpp @@ -885,8 +885,8 @@ gst_d3d11_h264_dec_output_picture (GstH264Decoder * decoder, } if (!gst_d3d11_decoder_process_output (inner->d3d11_decoder, vdec, - picture->discont_state, inner->width, inner->height, view_buffer, - &frame->output_buffer)) { + GST_CODEC_PICTURE (picture)->discont_state, inner->width, + inner->height, view_buffer, &frame->output_buffer)) { GST_ERROR_OBJECT (self, "Failed to copy buffer"); goto error; } diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.cpp b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.cpp index 415fc8dd4c..2e06c76ba2 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.cpp +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.cpp @@ -750,7 +750,8 @@ gst_nv_h264_dec_output_picture (GstH264Decoder * decoder, } ret = gst_nv_decoder_finish_surface (self->decoder, - vdec, picture->discont_state, surface, &frame->output_buffer); + vdec, GST_CODEC_PICTURE (picture)->discont_state, surface, + &frame->output_buffer); if (ret != GST_FLOW_OK) goto error; diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech264dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech264dec.c index b604fc5903..6bde230a1a 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech264dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech264dec.c @@ -628,7 +628,7 @@ gst_v4l2_codec_h264_dec_fill_decoder_params (GstV4l2CodecH264Dec * self, * The reference is multiplied by 1000 because it's was set as micro * seconds and this TS is nanosecond. */ - .reference_ts = (guint64) ref_pic->system_frame_number * 1000, + .reference_ts = (guint64) GST_CODEC_PICTURE_FRAME_NUMBER (ref_pic) * 1000, .frame_num = frame_num, .pic_num = pic_num, .flags = V4L2_H264_DPB_ENTRY_FLAG_VALID @@ -779,7 +779,7 @@ lookup_dpb_index (struct v4l2_h264_dpb_entry dpb[16], GstH264Picture * ref_pic) if (ref_pic->second_field && ref_pic->other_field) ref_pic = ref_pic->other_field; - ref_ts = (guint64) ref_pic->system_frame_number * 1000; + ref_ts = (guint64) GST_CODEC_PICTURE_FRAME_NUMBER (ref_pic) * 1000; for (i = 0; i < 16; i++) { if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE && dpb[i].reference_ts == ref_ts) @@ -1056,21 +1056,23 @@ gst_v4l2_codec_h264_dec_output_picture (GstH264Decoder * decoder, GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder); GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder); GstV4l2Request *request = gst_h264_picture_get_user_data (picture); + GstCodecPicture *codec_picture = GST_CODEC_PICTURE (picture); gint ret; - if (picture->discont_state) { + if (codec_picture->discont_state) { if (!gst_video_decoder_negotiate (vdec)) { GST_ERROR_OBJECT (vdec, "Could not re-negotiate with updated state"); return FALSE; } } - GST_DEBUG_OBJECT (self, "Output picture %u", picture->system_frame_number); + GST_DEBUG_OBJECT (self, "Output picture %u", + codec_picture->system_frame_number); ret = gst_v4l2_request_set_done (request); if (ret == 0) { GST_ELEMENT_ERROR (self, STREAM, DECODE, - ("Decoding frame %u took too long", picture->system_frame_number), + ("Decoding frame %u took too long", codec_picture->system_frame_number), (NULL)); goto error; } else if (ret < 0) { @@ -1082,7 +1084,8 @@ gst_v4l2_codec_h264_dec_output_picture (GstH264Decoder * decoder, if (gst_v4l2_request_failed (request)) { GST_ELEMENT_ERROR (self, STREAM, DECODE, - ("Failed to decode frame %u", picture->system_frame_number), (NULL)); + ("Failed to decode frame %u", codec_picture->system_frame_number), + (NULL)); goto error; } @@ -1175,16 +1178,17 @@ gst_v4l2_codec_h264_dec_submit_bitstream (GstV4l2CodecH264Dec * self, self->bitstream); } else { GstVideoCodecFrame *frame; + guint32 system_frame_number = GST_CODEC_PICTURE_FRAME_NUMBER (picture); frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self), - picture->system_frame_number); + system_frame_number); g_return_val_if_fail (frame, FALSE); if (!gst_v4l2_codec_h264_dec_ensure_output_buffer (self, frame)) goto done; request = gst_v4l2_decoder_alloc_request (self->decoder, - picture->system_frame_number, self->bitstream, frame->output_buffer); + system_frame_number, self->bitstream, frame->output_buffer); gst_video_codec_frame_unref (frame); } diff --git a/subprojects/gst-plugins-bad/sys/va/gstvah264dec.c b/subprojects/gst-plugins-bad/sys/va/gstvah264dec.c index 44a1ba6d5d..c17dbfda83 100644 --- a/subprojects/gst-plugins-bad/sys/va/gstvah264dec.c +++ b/subprojects/gst-plugins-bad/sys/va/gstvah264dec.c @@ -123,8 +123,8 @@ gst_va_h264_dec_output_picture (GstH264Decoder * decoder, GST_LOG_OBJECT (self, "Outputting picture %p (poc %d)", picture, picture->pic_order_cnt); - ret = gst_va_base_dec_process_output (base, frame, picture->discont_state, - picture->buffer_flags); + ret = gst_va_base_dec_process_output (base, frame, + GST_CODEC_PICTURE (picture)->discont_state, picture->buffer_flags); gst_h264_picture_unref (picture); if (ret)