mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
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:
parent
c78fe6bfb0
commit
deaa29bd96
4 changed files with 63 additions and 61 deletions
|
@ -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:
|
||||
{
|
||||
|
|
|
@ -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 >*/
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue