mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-15 22:01:27 +00:00
h265decoder: Port to GstCodecPicture struct
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5285>
This commit is contained in:
parent
ea3dfadbed
commit
6e7cab43be
8 changed files with 52 additions and 91 deletions
|
@ -849,7 +849,8 @@ gst_h265_decoder_process_slice (GstH265Decoder * self, GstH265Slice * slice)
|
||||||
|
|
||||||
picture = gst_h265_picture_new ();
|
picture = gst_h265_picture_new ();
|
||||||
/* This allows accessing the frame from the picture. */
|
/* 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;
|
priv->current_picture = picture;
|
||||||
|
|
||||||
|
@ -1714,12 +1715,12 @@ gst_h265_decoder_do_output_picture (GstH265Decoder * self,
|
||||||
priv->last_output_poc = picture->pic_order_cnt;
|
priv->last_output_poc = picture->pic_order_cnt;
|
||||||
|
|
||||||
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
|
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
|
||||||
picture->system_frame_number);
|
GST_CODEC_PICTURE_FRAME_NUMBER (picture));
|
||||||
|
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
GST_ERROR_OBJECT (self,
|
GST_ERROR_OBJECT (self,
|
||||||
"No available codec frame with frame number %d",
|
"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);
|
UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR);
|
||||||
|
|
||||||
gst_h265_picture_unref (picture);
|
gst_h265_picture_unref (picture);
|
||||||
|
@ -1747,7 +1748,7 @@ gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush)
|
||||||
if (!flush) {
|
if (!flush) {
|
||||||
while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL) {
|
while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL) {
|
||||||
GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder,
|
GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder,
|
||||||
picture->system_frame_number);
|
GST_CODEC_PICTURE_FRAME_NUMBER (picture));
|
||||||
|
|
||||||
if (frame)
|
if (frame)
|
||||||
gst_video_decoder_release_frame (decoder, frame);
|
gst_video_decoder_release_frame (decoder, frame);
|
||||||
|
@ -1855,8 +1856,8 @@ gst_h265_decoder_start_current_picture (GstH265Decoder * self)
|
||||||
/* If subclass didn't update output state at this point,
|
/* If subclass didn't update output state at this point,
|
||||||
* marking this picture as a discont and stores current input state */
|
* marking this picture as a discont and stores current input state */
|
||||||
if (priv->input_state_changed) {
|
if (priv->input_state_changed) {
|
||||||
priv->current_picture->discont_state =
|
gst_h265_picture_set_discont_state (priv->current_picture,
|
||||||
gst_video_codec_state_ref (self->input_state);
|
self->input_state);
|
||||||
priv->input_state_changed = FALSE;
|
priv->input_state_changed = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1907,7 +1908,7 @@ gst_h265_decoder_finish_picture (GstH265Decoder * self,
|
||||||
/* This picture is decode only, drop corresponding frame */
|
/* This picture is decode only, drop corresponding frame */
|
||||||
if (!picture->output_flag) {
|
if (!picture->output_flag) {
|
||||||
GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder,
|
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);
|
gst_video_decoder_release_frame (decoder, frame);
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ struct _GstH265DecoderClass
|
||||||
*
|
*
|
||||||
* Optional. Called whenever new #GstH265Picture is created.
|
* Optional. Called whenever new #GstH265Picture is created.
|
||||||
* Subclass can set implementation specific user data
|
* Subclass can set implementation specific user data
|
||||||
* on the #GstH265Picture via gst_h265_picture_set_user_data()
|
* on the #GstH265Picture via gst_h265_picture_set_user_data
|
||||||
*/
|
*/
|
||||||
GstFlowReturn (*new_picture) (GstH265Decoder * decoder,
|
GstFlowReturn (*new_picture) (GstH265Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame,
|
GstVideoCodecFrame * frame,
|
||||||
|
|
|
@ -22,24 +22,13 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gsth265picture.h"
|
#include "gsth265picture.h"
|
||||||
|
#include "gstcodecpicture-private.h"
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_h265_decoder_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_h265_decoder_debug);
|
||||||
#define GST_CAT_DEFAULT gst_h265_decoder_debug
|
#define GST_CAT_DEFAULT gst_h265_decoder_debug
|
||||||
|
|
||||||
GST_DEFINE_MINI_OBJECT_TYPE (GstH265Picture, gst_h265_picture);
|
GST_DEFINE_MINI_OBJECT_TYPE (GstH265Picture, gst_h265_picture);
|
||||||
|
|
||||||
static void
|
|
||||||
_gst_h265_picture_free (GstH265Picture * 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_h265_picture_new:
|
* gst_h265_picture_new:
|
||||||
*
|
*
|
||||||
|
@ -62,51 +51,11 @@ gst_h265_picture_new (void)
|
||||||
|
|
||||||
gst_mini_object_init (GST_MINI_OBJECT_CAST (pic), 0,
|
gst_mini_object_init (GST_MINI_OBJECT_CAST (pic), 0,
|
||||||
GST_TYPE_H265_PICTURE, NULL, NULL,
|
GST_TYPE_H265_PICTURE, NULL, NULL,
|
||||||
(GstMiniObjectFreeFunction) _gst_h265_picture_free);
|
(GstMiniObjectFreeFunction) gst_codec_picture_free);
|
||||||
|
|
||||||
return pic;
|
return pic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_h265_picture_set_user_data:
|
|
||||||
* @picture: a #GstH265Picture
|
|
||||||
* @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_h265_picture_set_user_data (GstH265Picture * picture, gpointer user_data,
|
|
||||||
GDestroyNotify notify)
|
|
||||||
{
|
|
||||||
g_return_if_fail (GST_IS_H265_PICTURE (picture));
|
|
||||||
|
|
||||||
if (picture->notify)
|
|
||||||
picture->notify (picture->user_data);
|
|
||||||
|
|
||||||
picture->user_data = user_data;
|
|
||||||
picture->notify = notify;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_h265_picture_get_user_data:
|
|
||||||
* @picture: a #GstH265Picture
|
|
||||||
*
|
|
||||||
* Gets private data set on the picture via
|
|
||||||
* gst_h265_picture_set_user_data() previously.
|
|
||||||
*
|
|
||||||
* Returns: (transfer none) (nullable): The previously set user_data
|
|
||||||
*/
|
|
||||||
gpointer
|
|
||||||
gst_h265_picture_get_user_data (GstH265Picture * picture)
|
|
||||||
{
|
|
||||||
return picture->user_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _GstH265Dpb
|
struct _GstH265Dpb
|
||||||
{
|
{
|
||||||
GArray *pic_list;
|
GArray *pic_list;
|
||||||
|
@ -474,7 +423,7 @@ gst_h265_dpb_get_picture (GstH265Dpb * dpb, guint32 system_frame_number)
|
||||||
GstH265Picture *picture =
|
GstH265Picture *picture =
|
||||||
g_array_index (dpb->pic_list, GstH265Picture *, i);
|
g_array_index (dpb->pic_list, GstH265Picture *, i);
|
||||||
|
|
||||||
if (picture->system_frame_number == system_frame_number) {
|
if (GST_CODEC_PICTURE_FRAME_NUMBER (picture) == system_frame_number) {
|
||||||
gst_h265_picture_ref (picture);
|
gst_h265_picture_ref (picture);
|
||||||
return picture;
|
return picture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/codecs/codecs-prelude.h>
|
#include <gst/codecs/codecs-prelude.h>
|
||||||
|
#include <gst/codecs/gstcodecpicture.h>
|
||||||
#include <gst/codecparsers/gsth265parser.h>
|
#include <gst/codecparsers/gsth265parser.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
|
@ -60,13 +61,10 @@ struct _GstH265Slice
|
||||||
struct _GstH265Picture
|
struct _GstH265Picture
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GstMiniObject parent;
|
GstCodecPicture parent;
|
||||||
|
|
||||||
GstH265SliceType type;
|
GstH265SliceType type;
|
||||||
|
|
||||||
/* From GstVideoCodecFrame */
|
|
||||||
guint32 system_frame_number;
|
|
||||||
|
|
||||||
gint pic_order_cnt;
|
gint pic_order_cnt;
|
||||||
gint pic_order_cnt_msb;
|
gint pic_order_cnt_msb;
|
||||||
gint pic_order_cnt_lsb;
|
gint pic_order_cnt_lsb;
|
||||||
|
@ -89,12 +87,6 @@ struct _GstH265Picture
|
||||||
guint8 duplicate_flag;
|
guint8 duplicate_flag;
|
||||||
|
|
||||||
GstVideoBufferFlags buffer_flags;
|
GstVideoBufferFlags buffer_flags;
|
||||||
|
|
||||||
/* decoder input state if this picture is discont point */
|
|
||||||
GstVideoCodecState *discont_state;
|
|
||||||
|
|
||||||
gpointer user_data;
|
|
||||||
GDestroyNotify notify;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_CODECS_API
|
GST_CODECS_API
|
||||||
|
@ -132,13 +124,27 @@ gst_clear_h265_picture (GstH265Picture ** picture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_CODECS_API
|
static inline void
|
||||||
void gst_h265_picture_set_user_data (GstH265Picture * picture,
|
gst_h265_picture_set_user_data (GstH265Picture * picture, gpointer user_data,
|
||||||
gpointer user_data,
|
GDestroyNotify notify)
|
||||||
GDestroyNotify notify);
|
{
|
||||||
|
gst_codec_picture_set_user_data (GST_CODEC_PICTURE (picture),
|
||||||
|
user_data, notify);
|
||||||
|
}
|
||||||
|
|
||||||
GST_CODECS_API
|
static inline gpointer
|
||||||
gpointer gst_h265_picture_get_user_data (GstH265Picture * picture);
|
gst_h265_picture_get_user_data (GstH265Picture * picture)
|
||||||
|
{
|
||||||
|
return gst_codec_picture_get_user_data (GST_CODEC_PICTURE (picture));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gst_h265_picture_set_discont_state (GstH265Picture * picture,
|
||||||
|
GstVideoCodecState * discont_state)
|
||||||
|
{
|
||||||
|
gst_codec_picture_set_discont_state (GST_CODEC_PICTURE (picture),
|
||||||
|
discont_state);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
* GstH265Dpb *
|
* GstH265Dpb *
|
||||||
|
|
|
@ -933,8 +933,8 @@ gst_d3d11_h265_dec_output_picture (GstH265Decoder * decoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_d3d11_decoder_process_output (inner->d3d11_decoder, vdec,
|
if (!gst_d3d11_decoder_process_output (inner->d3d11_decoder, vdec,
|
||||||
picture->discont_state, inner->width, inner->height, view_buffer,
|
GST_CODEC_PICTURE (picture)->discont_state, inner->width,
|
||||||
&frame->output_buffer)) {
|
inner->height, view_buffer, &frame->output_buffer)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -682,7 +682,8 @@ gst_nv_h265_dec_output_picture (GstH265Decoder * decoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = gst_nv_decoder_finish_surface (self->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)
|
if (ret != GST_FLOW_OK)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
|
@ -814,7 +814,7 @@ lookup_dpb_index (struct v4l2_hevc_dpb_entry dpb[16], GstH265Picture * ref_pic)
|
||||||
if (!ref_pic)
|
if (!ref_pic)
|
||||||
return 0xff;
|
return 0xff;
|
||||||
|
|
||||||
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++) {
|
for (i = 0; i < 16; i++) {
|
||||||
if (dpb[i].timestamp == ref_ts)
|
if (dpb[i].timestamp == ref_ts)
|
||||||
return i;
|
return i;
|
||||||
|
@ -1010,7 +1010,7 @@ gst_v4l2_codec_h265_dec_fill_decode_params (GstV4l2CodecH265Dec * self,
|
||||||
* The reference is multiplied by 1000 because it's wassed as micro
|
* The reference is multiplied by 1000 because it's wassed as micro
|
||||||
* seconds and this TS is nanosecond.
|
* seconds and this TS is nanosecond.
|
||||||
*/
|
*/
|
||||||
.timestamp = (guint64) ref_pic->system_frame_number * 1000,
|
.timestamp = (guint64) GST_CODEC_PICTURE_FRAME_NUMBER (ref_pic) * 1000,
|
||||||
.flags = ref_pic->long_term ? V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE : 0,
|
.flags = ref_pic->long_term ? V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE : 0,
|
||||||
.field_pic = ref_pic->pic_struct,
|
.field_pic = ref_pic->pic_struct,
|
||||||
.pic_order_cnt_val = ref_pic->pic_order_cnt,
|
.pic_order_cnt_val = ref_pic->pic_order_cnt,
|
||||||
|
@ -1191,21 +1191,23 @@ gst_v4l2_codec_h265_dec_output_picture (GstH265Decoder * decoder,
|
||||||
GstV4l2CodecH265Dec *self = GST_V4L2_CODEC_H265_DEC (decoder);
|
GstV4l2CodecH265Dec *self = GST_V4L2_CODEC_H265_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstV4l2Request *request = gst_h265_picture_get_user_data (picture);
|
GstV4l2Request *request = gst_h265_picture_get_user_data (picture);
|
||||||
|
GstCodecPicture *codec_picture = GST_CODEC_PICTURE (picture);
|
||||||
gint ret;
|
gint ret;
|
||||||
|
|
||||||
if (picture->discont_state) {
|
if (codec_picture->discont_state) {
|
||||||
if (!gst_video_decoder_negotiate (vdec)) {
|
if (!gst_video_decoder_negotiate (vdec)) {
|
||||||
GST_ERROR_OBJECT (vdec, "Could not re-negotiate with updated state");
|
GST_ERROR_OBJECT (vdec, "Could not re-negotiate with updated state");
|
||||||
return FALSE;
|
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);
|
ret = gst_v4l2_request_set_done (request);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
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));
|
(NULL));
|
||||||
goto error;
|
goto error;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
|
@ -1217,7 +1219,8 @@ gst_v4l2_codec_h265_dec_output_picture (GstH265Decoder * decoder,
|
||||||
|
|
||||||
if (gst_v4l2_request_failed (request)) {
|
if (gst_v4l2_request_failed (request)) {
|
||||||
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1311,16 +1314,17 @@ gst_v4l2_codec_h265_dec_submit_bitstream (GstV4l2CodecH265Dec * self,
|
||||||
self->bitstream);
|
self->bitstream);
|
||||||
} else {
|
} else {
|
||||||
GstVideoCodecFrame *frame;
|
GstVideoCodecFrame *frame;
|
||||||
|
guint32 system_frame_number = GST_CODEC_PICTURE_FRAME_NUMBER (picture);
|
||||||
|
|
||||||
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
|
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
|
||||||
picture->system_frame_number);
|
system_frame_number);
|
||||||
g_return_val_if_fail (frame, FALSE);
|
g_return_val_if_fail (frame, FALSE);
|
||||||
|
|
||||||
if (!gst_v4l2_codec_h265_dec_ensure_output_buffer (self, frame))
|
if (!gst_v4l2_codec_h265_dec_ensure_output_buffer (self, frame))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
request = gst_v4l2_decoder_alloc_request (self->decoder,
|
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);
|
gst_video_codec_frame_unref (frame);
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,8 +237,8 @@ gst_va_h265_dec_output_picture (GstH265Decoder * decoder,
|
||||||
|
|
||||||
gst_buffer_replace (&frame->output_buffer, va_pic->gstbuffer);
|
gst_buffer_replace (&frame->output_buffer, va_pic->gstbuffer);
|
||||||
|
|
||||||
ret = gst_va_base_dec_process_output (base, frame, picture->discont_state,
|
ret = gst_va_base_dec_process_output (base, frame,
|
||||||
picture->buffer_flags);
|
GST_CODEC_PICTURE (picture)->discont_state, picture->buffer_flags);
|
||||||
gst_h265_picture_unref (picture);
|
gst_h265_picture_unref (picture);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in a new issue