codecs: vp8decoder: Sync up with h264decoder implementation

Pass GstVideoCodecFrame with GstVp8Picture to new_picture() and
output_picture() methods for subclass to be able to reference
it directly.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1458>
This commit is contained in:
Seungha Yang 2020-07-23 17:45:03 +09:00 committed by Nicolas Dufresne
parent c78fe6bfb0
commit deaa29bd96
4 changed files with 63 additions and 61 deletions

View file

@ -332,7 +332,7 @@ gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
picture->system_frame_number = frame->system_frame_number;
if (klass->new_picture) {
if (!klass->new_picture (self, picture)) {
if (!klass->new_picture (self, frame, picture)) {
GST_ERROR_OBJECT (self, "subclass cannot handle new picture");
goto unmap_and_error;
}
@ -361,15 +361,10 @@ gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
gst_buffer_unmap (in_buf, &map);
gst_video_codec_frame_set_user_data (frame, gst_vp8_picture_ref (picture),
(GDestroyNotify) gst_vp8_picture_unref);
gst_video_codec_frame_unref (frame);
/* transfer ownership of picture */
gst_vp8_decoder_update_reference (self, picture);
gst_vp8_decoder_update_reference (self, gst_vp8_picture_ref (picture));
g_assert (klass->output_picture);
return klass->output_picture (self, picture);
return klass->output_picture (self, frame, picture);
unmap_and_error:
{

View file

@ -91,7 +91,14 @@ struct _GstVp8DecoderClass
gboolean (*new_sequence) (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr);
/**
* GstVp8Decoder:new_picture:
* @decoder: a #GstVp8Decoder
* @frame: (transfer none): a #GstVideoCodecFrame
* @picture: (transfer none): a #GstVp8Picture
*/
gboolean (*new_picture) (GstVp8Decoder * decoder,
GstVideoCodecFrame * frame,
GstVp8Picture * picture);
gboolean (*start_picture) (GstVp8Decoder * decoder,
@ -104,7 +111,14 @@ struct _GstVp8DecoderClass
gboolean (*end_picture) (GstVp8Decoder * decoder,
GstVp8Picture * picture);
/**
* GstVp8Decoder:output_picture:
* @decoder: a #GstVp8Decoder
* @frame: (transfer full): a #GstVideoCodecFrame
* @picture: (transfer full): a #GstVp8Picture
*/
GstFlowReturn (*output_picture) (GstVp8Decoder * decoder,
GstVideoCodecFrame * frame,
GstVp8Picture * picture);
/*< private >*/

View file

@ -99,9 +99,9 @@ static gboolean gst_d3d11_vp8_dec_src_query (GstVideoDecoder * decoder,
static gboolean gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
const GstVp8FrameHdr * frame_hdr);
static gboolean gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
GstVp8Picture * picture);
GstVideoCodecFrame * frame, GstVp8Picture * picture);
static GstFlowReturn gst_d3d11_vp8_dec_output_picture (GstVp8Decoder *
decoder, GstVp8Picture * picture);
decoder, GstVideoCodecFrame * frame, GstVp8Picture * picture);
static gboolean gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
GstVp8Picture * picture);
static gboolean gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
@ -335,7 +335,8 @@ gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
}
static gboolean
gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder, GstVp8Picture * picture)
gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
GstVideoCodecFrame * frame, GstVp8Picture * picture)
{
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
GstBuffer *view_buffer;
@ -362,10 +363,10 @@ gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder, GstVp8Picture * picture)
static GstFlowReturn
gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
GstVp8Picture * picture)
GstVideoCodecFrame * frame, GstVp8Picture * picture)
{
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
GstVideoCodecFrame *frame = NULL;
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
GstBuffer *output_buffer = NULL;
GstBuffer *view_buffer;
@ -375,25 +376,16 @@ gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
if (!view_buffer) {
GST_ERROR_OBJECT (self, "Could not get output view");
return GST_FLOW_ERROR;
}
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
picture->system_frame_number);
if (!frame) {
GST_ERROR_OBJECT (self,
"No frame corresponding to system frame number %d",
picture->system_frame_number);
return GST_FLOW_ERROR;
goto error;
}
if (!picture->frame_hdr.show_frame) {
GST_LOG_OBJECT (self, "Decode only picture %p", picture);
GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
return gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
gst_vp8_picture_unref (picture);
return gst_video_decoder_finish_frame (vdec, frame);
}
/* if downstream is d3d11 element and forward playback case,
@ -402,20 +394,19 @@ gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
* up to gop size but our dpb pool cannot be increased */
if (self->use_d3d11_output &&
gst_d3d11_decoder_supports_direct_rendering (self->d3d11_decoder) &&
GST_VIDEO_DECODER (self)->input_segment.rate > 0) {
vdec->input_segment.rate > 0) {
GstMemory *mem;
output_buffer = gst_buffer_ref (view_buffer);
mem = gst_buffer_peek_memory (output_buffer, 0);
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
} else {
output_buffer =
gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER (self));
output_buffer = gst_video_decoder_allocate_output_buffer (vdec);
}
if (!output_buffer) {
GST_ERROR_OBJECT (self, "Couldn't allocate output buffer");
return GST_FLOW_ERROR;
goto error;
}
frame->output_buffer = output_buffer;
@ -425,15 +416,21 @@ gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
picture->frame_hdr.width, picture->frame_hdr.height,
view_buffer, output_buffer)) {
GST_ERROR_OBJECT (self, "Failed to copy buffer");
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
return GST_FLOW_ERROR;
goto error;
}
GST_LOG_OBJECT (self, "Finish frame %" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_PTS (output_buffer)));
return gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
gst_vp8_picture_unref (picture);
return gst_video_decoder_finish_frame (vdec, frame);
error:
gst_video_decoder_drop_frame (vdec, frame);
gst_vp8_picture_unref (picture);
return GST_FLOW_ERROR;
}
static GstD3D11DecoderOutputView *

View file

@ -657,18 +657,17 @@ fail:
static GstFlowReturn
gst_v4l2_codec_vp8_dec_output_picture (GstVp8Decoder * decoder,
GstVp8Picture * picture)
GstVideoCodecFrame * frame, GstVp8Picture * picture)
{
GstV4l2CodecVp8Dec *self = GST_V4L2_CODEC_VP8_DEC (decoder);
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
GstV4l2Request *request = gst_vp8_picture_get_user_data (picture);
gint ret;
guint32 frame_num;
GstVideoCodecFrame *frame, *other_frame;
GstVp8Picture *other_pic;
GstV4l2Request *other_request;
GST_DEBUG_OBJECT (self, "Output picture %u", picture->system_frame_number);
/* Unlikely, but it would not break this decoding flow */
if (gst_v4l2_request_is_done (request))
goto finish_frame;
@ -676,38 +675,27 @@ gst_v4l2_codec_vp8_dec_output_picture (GstVp8Decoder * decoder,
if (ret == 0) {
GST_ELEMENT_ERROR (self, STREAM, DECODE,
("Decoding frame took too long"), (NULL));
return GST_FLOW_ERROR;
goto error;
} else if (ret < 0) {
GST_ELEMENT_ERROR (self, STREAM, DECODE,
("Decoding request failed: %s", g_strerror (errno)), (NULL));
return GST_FLOW_ERROR;
goto error;
}
while (TRUE) {
if (!gst_v4l2_decoder_dequeue_src (self->decoder, &frame_num)) {
GST_ELEMENT_ERROR (self, STREAM, DECODE,
("Decoder did not produce a frame"), (NULL));
return GST_FLOW_ERROR;
}
if (!gst_v4l2_decoder_dequeue_src (self->decoder, &frame_num)) {
GST_ELEMENT_ERROR (self, STREAM, DECODE,
("Decoder did not produce a frame"), (NULL));
goto error;
}
if (frame_num == picture->system_frame_number)
break;
other_frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
frame_num);
g_return_val_if_fail (other_frame, GST_FLOW_ERROR);
other_pic = gst_video_codec_frame_get_user_data (other_frame);
other_request = gst_vp8_picture_get_user_data (other_pic);
gst_v4l2_request_set_done (other_request);
gst_video_codec_frame_unref (other_frame);
if (frame_num != picture->system_frame_number) {
GST_ELEMENT_ERROR (self, STREAM, DECODE,
("Decoder produced out of order frame"), (NULL));
goto error;
}
finish_frame:
gst_v4l2_request_set_done (request);
frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
picture->system_frame_number);
g_return_val_if_fail (frame, GST_FLOW_ERROR);
g_return_val_if_fail (frame->output_buffer, GST_FLOW_ERROR);
/* Hold on reference buffers for the rest of the picture lifetime */
@ -717,7 +705,15 @@ finish_frame:
if (self->copy_frames)
gst_v4l2_codec_vp8_dec_copy_output_buffer (self, frame);
return gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
gst_vp8_picture_unref (picture);
return gst_video_decoder_finish_frame (vdec, frame);
error:
gst_video_decoder_drop_frame (vdec, frame);
gst_vp8_picture_unref (picture);
return GST_FLOW_ERROR;
}
static void