mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
codecs: h264decoder: Don't attach extra ref of GstH264Picture to GstVideoCodecFrame
The lifecycle of GstH264Picture is being managed by our DPB implementation. If it's still required, subclass can do that by itself in the new_picture() method. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1449>
This commit is contained in:
parent
37aeb91d54
commit
7a024a740f
6 changed files with 43 additions and 24 deletions
|
@ -758,20 +758,19 @@ 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;
|
||||
|
||||
priv->current_picture = picture;
|
||||
g_assert (priv->current_frame);
|
||||
|
||||
if (klass->new_picture)
|
||||
ret = klass->new_picture (self, picture);
|
||||
ret = klass->new_picture (self, priv->current_frame, picture);
|
||||
|
||||
if (!ret) {
|
||||
GST_ERROR_OBJECT (self, "subclass does not want accept new picture");
|
||||
priv->current_picture = NULL;
|
||||
gst_h264_picture_unref (picture);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
priv->current_picture = picture;
|
||||
gst_video_codec_frame_set_user_data (priv->current_frame,
|
||||
gst_h264_picture_ref (priv->current_picture),
|
||||
(GDestroyNotify) gst_h264_picture_unref);
|
||||
|
||||
if (!gst_h264_decoder_start_current_picture (self)) {
|
||||
GST_ERROR_OBJECT (self, "start picture failed");
|
||||
return FALSE;
|
||||
|
|
|
@ -90,7 +90,15 @@ struct _GstH264DecoderClass
|
|||
const GstH264SPS * sps,
|
||||
gint max_dpb_size);
|
||||
|
||||
/**
|
||||
* GstVideoDecoder:new_picture:
|
||||
*
|
||||
* @decoder: a #GstH264Decoder
|
||||
* @frame: (transfer none): a #GstVideoCodecFrame
|
||||
* @picture: (transfer none): a #GstH264Picture
|
||||
*/
|
||||
gboolean (*new_picture) (GstH264Decoder * decoder,
|
||||
GstVideoCodecFrame * frame,
|
||||
GstH264Picture * picture);
|
||||
|
||||
gboolean (*start_picture) (GstH264Decoder * decoder,
|
||||
|
|
|
@ -151,7 +151,7 @@ static gboolean gst_d3d11_h264_dec_src_query (GstVideoDecoder * decoder,
|
|||
static gboolean gst_d3d11_h264_dec_new_sequence (GstH264Decoder * decoder,
|
||||
const GstH264SPS * sps, gint max_dpb_size);
|
||||
static gboolean gst_d3d11_h264_dec_new_picture (GstH264Decoder * decoder,
|
||||
GstH264Picture * picture);
|
||||
GstVideoCodecFrame * frame, GstH264Picture * picture);
|
||||
static GstFlowReturn gst_d3d11_h264_dec_output_picture (GstH264Decoder *
|
||||
decoder, GstH264Picture * picture);
|
||||
static gboolean gst_d3d11_h264_dec_start_picture (GstH264Decoder * decoder,
|
||||
|
@ -578,7 +578,7 @@ gst_d3d11_h264_dec_start_picture (GstH264Decoder * decoder,
|
|||
|
||||
static gboolean
|
||||
gst_d3d11_h264_dec_new_picture (GstH264Decoder * decoder,
|
||||
GstH264Picture * picture)
|
||||
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
||||
{
|
||||
GstD3D11H264Dec *self = GST_D3D11_H264_DEC (decoder);
|
||||
GstBuffer *view_buffer;
|
||||
|
|
|
@ -146,7 +146,7 @@ static gboolean gst_nv_h264_dec_src_query (GstVideoDecoder * decoder,
|
|||
static gboolean gst_nv_h264_dec_new_sequence (GstH264Decoder * decoder,
|
||||
const GstH264SPS * sps, gint max_dpb_size);
|
||||
static gboolean gst_nv_h264_dec_new_picture (GstH264Decoder * decoder,
|
||||
GstH264Picture * picture);
|
||||
GstVideoCodecFrame * frame, GstH264Picture * picture);
|
||||
static GstFlowReturn gst_nv_h264_dec_output_picture (GstH264Decoder *
|
||||
decoder, GstH264Picture * picture);
|
||||
static gboolean gst_nv_h264_dec_start_picture (GstH264Decoder * decoder,
|
||||
|
@ -416,21 +416,23 @@ gst_nv_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_nv_h264_dec_new_picture (GstH264Decoder * decoder, GstH264Picture * picture)
|
||||
gst_nv_h264_dec_new_picture (GstH264Decoder * decoder,
|
||||
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
||||
{
|
||||
GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
|
||||
GstNvDecoderFrame *frame;
|
||||
GstNvDecoderFrame *nv_frame;
|
||||
|
||||
frame = gst_nv_decoder_new_frame (self->decoder);
|
||||
if (!frame) {
|
||||
nv_frame = gst_nv_decoder_new_frame (self->decoder);
|
||||
if (!nv_frame) {
|
||||
GST_ERROR_OBJECT (self, "No available decoder frame");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (self, "New decoder frame %p (index %d)", frame, frame->index);
|
||||
GST_LOG_OBJECT (self,
|
||||
"New decoder frame %p (index %d)", nv_frame, nv_frame->index);
|
||||
|
||||
gst_h264_picture_set_user_data (picture,
|
||||
frame, (GDestroyNotify) gst_nv_decoder_frame_free);
|
||||
nv_frame, (GDestroyNotify) gst_nv_decoder_frame_free);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -544,7 +544,7 @@ gst_v4l2_codec_h264_dec_fill_slice_params (GstV4l2CodecH264Dec * self,
|
|||
.flags = (slice->header.field_pic_flag ? V4L2_H264_SLICE_FLAG_FIELD_PIC : 0) |
|
||||
(slice->header.bottom_field_flag ? V4L2_H264_SLICE_FLAG_BOTTOM_FIELD : 0) |
|
||||
(slice->header.direct_spatial_mv_pred_flag ? V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED : 0) |
|
||||
(slice->header.sp_for_switch_flag ? V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH : 0),
|
||||
(slice->header.sp_for_switch_flag ? V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH : 0),
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
@ -751,6 +751,17 @@ done:
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_v4l2_codec_h264_dec_new_picture (GstH264Decoder * decoder,
|
||||
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
||||
{
|
||||
/* This user data will be referenced in _output_picture */
|
||||
gst_video_codec_frame_set_user_data (frame,
|
||||
gst_h264_picture_ref (picture), (GDestroyNotify) gst_h264_picture_unref);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_v4l2_codec_h264_dec_start_picture (GstH264Decoder * decoder,
|
||||
GstH264Picture * picture, GstH264Slice * slice, GstH264Dpb * dpb)
|
||||
|
@ -1249,6 +1260,8 @@ gst_v4l2_codec_h264_dec_subclass_init (GstV4l2CodecH264DecClass * klass,
|
|||
|
||||
h264decoder_class->new_sequence =
|
||||
GST_DEBUG_FUNCPTR (gst_v4l2_codec_h264_dec_new_sequence);
|
||||
h264decoder_class->new_picture =
|
||||
GST_DEBUG_FUNCPTR (gst_v4l2_codec_h264_dec_new_picture);
|
||||
h264decoder_class->output_picture =
|
||||
GST_DEBUG_FUNCPTR (gst_v4l2_codec_h264_dec_output_picture);
|
||||
h264decoder_class->start_picture =
|
||||
|
|
|
@ -518,25 +518,20 @@ fail:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_va_h264_dec_new_picture (GstH264Decoder * decoder, GstH264Picture * picture)
|
||||
gst_va_h264_dec_new_picture (GstH264Decoder * decoder,
|
||||
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
||||
{
|
||||
GstVaH264Dec *self = GST_VA_H264_DEC (decoder);
|
||||
GstVaDecodePicture *pic;
|
||||
GstVideoCodecFrame *frame;
|
||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||
VASurfaceID surface;
|
||||
|
||||
frame = gst_video_decoder_get_frame (vdec, picture->system_frame_number);
|
||||
if (!frame)
|
||||
return FALSE; /* something failed before */
|
||||
self->last_ret = gst_video_decoder_allocate_output_frame (vdec, frame);
|
||||
if (self->last_ret != GST_FLOW_OK)
|
||||
goto error;
|
||||
|
||||
surface = gst_va_buffer_get_surface (frame->output_buffer, NULL);
|
||||
|
||||
gst_video_codec_frame_unref (frame);
|
||||
|
||||
pic = gst_va_decoder_new_decode_picture (self->decoder, surface);
|
||||
gst_h264_picture_set_user_data (picture, pic,
|
||||
(GDestroyNotify) gst_va_decode_picture_free);
|
||||
|
@ -547,7 +542,9 @@ gst_va_h264_dec_new_picture (GstH264Decoder * decoder, GstH264Picture * picture)
|
|||
|
||||
error:
|
||||
{
|
||||
gst_video_codec_frame_unref (frame);
|
||||
GST_WARNING_OBJECT (self,
|
||||
"Failed to allocated output buffer, return %s",
|
||||
gst_flow_get_name (self->last_ret));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue