mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 05:01:23 +00:00
mpeg2decoder: Port to GstCodecPicture struct
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5285>
This commit is contained in:
parent
6e7cab43be
commit
a5ddf7af3b
7 changed files with 57 additions and 90 deletions
|
@ -841,8 +841,8 @@ gst_mpeg2_decoder_start_current_picture (GstMpeg2Decoder * decoder,
|
||||||
/* 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_mpeg2_picture_set_discont_state (priv->current_picture,
|
||||||
gst_video_codec_state_ref (decoder->input_state);
|
decoder->input_state);
|
||||||
priv->input_state_changed = FALSE;
|
priv->input_state_changed = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +942,8 @@ gst_mpeg2_decoder_ensure_current_picture (GstMpeg2Decoder * decoder,
|
||||||
|
|
||||||
picture->needed_for_output = TRUE;
|
picture->needed_for_output = TRUE;
|
||||||
/* 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;
|
||||||
picture->type = priv->pic_hdr.pic_type;
|
picture->type = priv->pic_hdr.pic_type;
|
||||||
picture->tsn = priv->pic_hdr.tsn;
|
picture->tsn = priv->pic_hdr.tsn;
|
||||||
priv->current_pts =
|
priv->current_pts =
|
||||||
|
@ -956,8 +957,8 @@ gst_mpeg2_decoder_ensure_current_picture (GstMpeg2Decoder * decoder,
|
||||||
picture,
|
picture,
|
||||||
(picture->structure == GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME) ?
|
(picture->structure == GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME) ?
|
||||||
"frame" : "field",
|
"frame" : "field",
|
||||||
picture->system_frame_number, picture->pic_order_cnt, picture->type,
|
GST_CODEC_PICTURE_FRAME_NUMBER (picture),
|
||||||
picture->first_field);
|
picture->pic_order_cnt, picture->type, picture->first_field);
|
||||||
|
|
||||||
return gst_mpeg2_decoder_start_current_picture (decoder, slice);
|
return gst_mpeg2_decoder_start_current_picture (decoder, slice);
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1067,8 @@ gst_mpeg2_decoder_handle_slice (GstMpeg2Decoder * decoder,
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
GST_WARNING_OBJECT (decoder,
|
GST_WARNING_OBJECT (decoder,
|
||||||
"Subclass didn't want to decode picture %p (frame_num %d, poc %d)",
|
"Subclass didn't want to decode picture %p (frame_num %d, poc %d)",
|
||||||
priv->current_picture, priv->current_picture->system_frame_number,
|
priv->current_picture,
|
||||||
|
GST_CODEC_PICTURE_FRAME_NUMBER (priv->current_picture),
|
||||||
priv->current_picture->pic_order_cnt);
|
priv->current_picture->pic_order_cnt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1155,12 +1157,12 @@ gst_mpeg2_decoder_do_output_picture (GstMpeg2Decoder * decoder,
|
||||||
|
|
||||||
frame =
|
frame =
|
||||||
gst_video_decoder_get_frame (GST_VIDEO_DECODER (decoder),
|
gst_video_decoder_get_frame (GST_VIDEO_DECODER (decoder),
|
||||||
to_output->system_frame_number);
|
GST_CODEC_PICTURE_FRAME_NUMBER (to_output));
|
||||||
|
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
GST_ERROR_OBJECT (decoder,
|
GST_ERROR_OBJECT (decoder,
|
||||||
"No available codec frame with frame number %d",
|
"No available codec frame with frame number %d",
|
||||||
to_output->system_frame_number);
|
GST_CODEC_PICTURE_FRAME_NUMBER (to_output));
|
||||||
UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR);
|
UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR);
|
||||||
|
|
||||||
gst_mpeg2_picture_unref (to_output);
|
gst_mpeg2_picture_unref (to_output);
|
||||||
|
@ -1197,7 +1199,8 @@ gst_mpeg2_decoder_output_current_picture (GstMpeg2Decoder * decoder)
|
||||||
|
|
||||||
GST_LOG_OBJECT (decoder,
|
GST_LOG_OBJECT (decoder,
|
||||||
"Add picture %p (frame_num %d, poc %d, type 0x%x), into DPB", picture,
|
"Add picture %p (frame_num %d, poc %d, type 0x%x), into DPB", picture,
|
||||||
picture->system_frame_number, picture->pic_order_cnt, picture->type);
|
GST_CODEC_PICTURE_FRAME_NUMBER (picture), picture->pic_order_cnt,
|
||||||
|
picture->type);
|
||||||
|
|
||||||
while (gst_mpeg2_dpb_need_bump (priv->dpb)) {
|
while (gst_mpeg2_dpb_need_bump (priv->dpb)) {
|
||||||
GstMpeg2Picture *to_output;
|
GstMpeg2Picture *to_output;
|
||||||
|
@ -1345,7 +1348,8 @@ gst_mpeg2_decoder_drain_output_queue (GstMpeg2Decoder * self, guint num,
|
||||||
GST_LOG_OBJECT (self,
|
GST_LOG_OBJECT (self,
|
||||||
"Output picture %p (frame_num %d, poc %d, pts: %" GST_TIME_FORMAT
|
"Output picture %p (frame_num %d, poc %d, pts: %" GST_TIME_FORMAT
|
||||||
"), from DPB",
|
"), from DPB",
|
||||||
output_frame->picture, output_frame->picture->system_frame_number,
|
output_frame->picture,
|
||||||
|
GST_CODEC_PICTURE_FRAME_NUMBER (output_frame->picture),
|
||||||
output_frame->picture->pic_order_cnt,
|
output_frame->picture->pic_order_cnt,
|
||||||
GST_TIME_ARGS (output_frame->frame->pts));
|
GST_TIME_ARGS (output_frame->frame->pts));
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ struct _GstMpeg2DecoderClass
|
||||||
*
|
*
|
||||||
* Optional. Called whenever new #GstMpeg2Picture is created.
|
* Optional. Called whenever new #GstMpeg2Picture is created.
|
||||||
* Subclass can set implementation specific user data
|
* Subclass can set implementation specific user data
|
||||||
* on the #GstMpeg2Picture via gst_mpeg2_picture_set_user_data()
|
* on the #GstMpeg2Picture via gst_mpeg2_picture_set_user_data
|
||||||
*
|
*
|
||||||
* Since: 1.20
|
* Since: 1.20
|
||||||
*/
|
*/
|
||||||
|
@ -111,7 +111,7 @@ struct _GstMpeg2DecoderClass
|
||||||
*
|
*
|
||||||
* Called when a new field picture is created for interlaced field picture.
|
* Called when a new field picture is created for interlaced field picture.
|
||||||
* Subclass can attach implementation specific user data on @second_field via
|
* Subclass can attach implementation specific user data on @second_field via
|
||||||
* gst_mpeg2_picture_set_user_data()
|
* gst_mpeg2_picture_set_user_data
|
||||||
*
|
*
|
||||||
* Since: 1.20
|
* Since: 1.20
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gstmpeg2picture.h"
|
#include "gstmpeg2picture.h"
|
||||||
|
#include "gstcodecpicture-private.h"
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_mpeg2_decoder_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_mpeg2_decoder_debug);
|
||||||
#define GST_CAT_DEFAULT gst_mpeg2_decoder_debug
|
#define GST_CAT_DEFAULT gst_mpeg2_decoder_debug
|
||||||
|
@ -37,13 +38,7 @@ _gst_mpeg2_picture_free (GstMpeg2Picture * picture)
|
||||||
if (picture->first_field)
|
if (picture->first_field)
|
||||||
gst_mpeg2_picture_unref (picture->first_field);
|
gst_mpeg2_picture_unref (picture->first_field);
|
||||||
|
|
||||||
if (picture->notify)
|
gst_codec_picture_free (GST_CODEC_PICTURE (picture));
|
||||||
picture->notify (picture->user_data);
|
|
||||||
|
|
||||||
if (picture->discont_state)
|
|
||||||
gst_video_codec_state_unref (picture->discont_state);
|
|
||||||
|
|
||||||
g_free (picture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,50 +69,6 @@ gst_mpeg2_picture_new (void)
|
||||||
return pic;
|
return pic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_mpeg2_picture_set_user_data:
|
|
||||||
* @picture: a #GstMpeg2Picture
|
|
||||||
* @user_data: 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.
|
|
||||||
*
|
|
||||||
* Since: 1.20
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gst_mpeg2_picture_set_user_data (GstMpeg2Picture * picture, gpointer user_data,
|
|
||||||
GDestroyNotify notify)
|
|
||||||
{
|
|
||||||
g_return_if_fail (GST_IS_MPEG2_PICTURE (picture));
|
|
||||||
|
|
||||||
if (picture->notify)
|
|
||||||
picture->notify (picture->user_data);
|
|
||||||
|
|
||||||
picture->user_data = user_data;
|
|
||||||
picture->notify = notify;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_mpeg2_picture_get_user_data:
|
|
||||||
* @picture: a #GstMpeg2Picture
|
|
||||||
*
|
|
||||||
* Gets private data set on the picture via
|
|
||||||
* gst_mpeg2_picture_set_user_data() previously.
|
|
||||||
*
|
|
||||||
* Returns: (transfer none): The previously set user_data
|
|
||||||
*
|
|
||||||
* Since: 1.20
|
|
||||||
*/
|
|
||||||
gpointer
|
|
||||||
gst_mpeg2_picture_get_user_data (GstMpeg2Picture * picture)
|
|
||||||
{
|
|
||||||
return picture->user_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _GstMpeg2Dpb
|
struct _GstMpeg2Dpb
|
||||||
{
|
{
|
||||||
GstMpeg2Picture *ref_pic_list[2];
|
GstMpeg2Picture *ref_pic_list[2];
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define __GST_MPEG2_PICTURE_H__
|
#define __GST_MPEG2_PICTURE_H__
|
||||||
|
|
||||||
#include <gst/codecs/codecs-prelude.h>
|
#include <gst/codecs/codecs-prelude.h>
|
||||||
|
#include <gst/codecs/gstcodecpicture.h>
|
||||||
#include <gst/codecparsers/gstmpegvideoparser.h>
|
#include <gst/codecparsers/gstmpegvideoparser.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
|
@ -79,10 +80,8 @@ struct _GstMpeg2Slice
|
||||||
struct _GstMpeg2Picture
|
struct _GstMpeg2Picture
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GstMiniObject parent;
|
GstCodecPicture parent;
|
||||||
|
|
||||||
/* From GstVideoCodecFrame */
|
|
||||||
guint32 system_frame_number;
|
|
||||||
gboolean needed_for_output;
|
gboolean needed_for_output;
|
||||||
/* For interlaced streams */
|
/* For interlaced streams */
|
||||||
GstMpeg2Picture *first_field;
|
GstMpeg2Picture *first_field;
|
||||||
|
@ -93,12 +92,6 @@ struct _GstMpeg2Picture
|
||||||
gint tsn;
|
gint tsn;
|
||||||
GstMpegVideoPictureStructure structure;
|
GstMpegVideoPictureStructure structure;
|
||||||
GstMpegVideoPictureType type;
|
GstMpegVideoPictureType type;
|
||||||
|
|
||||||
/* decoder input state if this picture is discont point */
|
|
||||||
GstVideoCodecState *discont_state;
|
|
||||||
|
|
||||||
gpointer user_data;
|
|
||||||
GDestroyNotify notify;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,14 +141,27 @@ gst_clear_mpeg2_picture (GstMpeg2Picture ** picture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_CODECS_API
|
static inline void
|
||||||
void gst_mpeg2_picture_set_user_data (GstMpeg2Picture * picture,
|
gst_mpeg2_picture_set_user_data (GstMpeg2Picture * 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_mpeg2_picture_get_user_data (GstMpeg2Picture * picture);
|
gst_mpeg2_picture_get_user_data (GstMpeg2Picture * picture)
|
||||||
|
{
|
||||||
|
return gst_codec_picture_get_user_data (GST_CODEC_PICTURE (picture));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gst_mpeg2_picture_set_discont_state (GstMpeg2Picture * picture,
|
||||||
|
GstVideoCodecState * discont_state)
|
||||||
|
{
|
||||||
|
gst_codec_picture_set_discont_state (GST_CODEC_PICTURE (picture),
|
||||||
|
discont_state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstMpeg2Dpb:
|
* GstMpeg2Dpb:
|
||||||
|
|
|
@ -747,8 +747,8 @@ gst_d3d11_mpeg2_dec_output_picture (GstMpeg2Decoder * 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -577,8 +577,10 @@ gst_v4l2_codec_mpeg2_dec_start_picture (GstMpeg2Decoder * decoder,
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
self->v4l2_picture = (struct v4l2_ctrl_mpeg2_picture) {
|
self->v4l2_picture = (struct v4l2_ctrl_mpeg2_picture) {
|
||||||
.backward_ref_ts = next_picture ? next_picture->system_frame_number * 1000 : GST_CLOCK_TIME_NONE,
|
.backward_ref_ts = next_picture ?
|
||||||
.forward_ref_ts = prev_picture ? prev_picture->system_frame_number * 1000 : GST_CLOCK_TIME_NONE,
|
GST_CODEC_PICTURE_FRAME_NUMBER (next_picture) * 1000 : GST_CLOCK_TIME_NONE,
|
||||||
|
.forward_ref_ts = prev_picture ?
|
||||||
|
GST_CODEC_PICTURE_FRAME_NUMBER (prev_picture) * 1000 : GST_CLOCK_TIME_NONE,
|
||||||
.intra_dc_precision = slice->pic_ext ? slice->pic_ext->intra_dc_precision : 0,
|
.intra_dc_precision = slice->pic_ext ? slice->pic_ext->intra_dc_precision : 0,
|
||||||
.flags = (slice->pic_ext && slice->pic_ext->top_field_first ? V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST : 0) |
|
.flags = (slice->pic_ext && slice->pic_ext->top_field_first ? V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST : 0) |
|
||||||
(slice->pic_ext && slice->pic_ext->frame_pred_frame_dct ? V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT : 0 ) |
|
(slice->pic_ext && slice->pic_ext->frame_pred_frame_dct ? V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT : 0 ) |
|
||||||
|
@ -680,21 +682,23 @@ gst_v4l2_codec_mpeg2_dec_output_picture (GstMpeg2Decoder * decoder,
|
||||||
GstV4l2CodecMpeg2Dec *self = GST_V4L2_CODEC_MPEG2_DEC (decoder);
|
GstV4l2CodecMpeg2Dec *self = GST_V4L2_CODEC_MPEG2_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstV4l2Request *request = gst_mpeg2_picture_get_user_data (picture);
|
GstV4l2Request *request = gst_mpeg2_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) {
|
||||||
|
@ -706,7 +710,8 @@ gst_v4l2_codec_mpeg2_dec_output_picture (GstMpeg2Decoder * 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,16 +806,17 @@ gst_v4l2_codec_mpeg2_dec_submit_bitstream (GstV4l2CodecMpeg2Dec * 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_mpeg2_dec_ensure_output_buffer (self, frame))
|
if (!gst_v4l2_codec_mpeg2_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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -518,8 +518,8 @@ gst_va_mpeg2_dec_output_picture (GstMpeg2Decoder * decoder,
|
||||||
GST_LOG_OBJECT (self,
|
GST_LOG_OBJECT (self,
|
||||||
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
|
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
|
||||||
|
|
||||||
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_mpeg2_picture_unref (picture);
|
gst_mpeg2_picture_unref (picture);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in a new issue