mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +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;
|
picture->system_frame_number = frame->system_frame_number;
|
||||||
|
|
||||||
if (klass->new_picture) {
|
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");
|
GST_ERROR_OBJECT (self, "subclass cannot handle new picture");
|
||||||
goto unmap_and_error;
|
goto unmap_and_error;
|
||||||
}
|
}
|
||||||
|
@ -361,15 +361,10 @@ gst_vp8_decoder_handle_frame (GstVideoDecoder * decoder,
|
||||||
|
|
||||||
gst_buffer_unmap (in_buf, &map);
|
gst_buffer_unmap (in_buf, &map);
|
||||||
|
|
||||||
gst_video_codec_frame_set_user_data (frame, gst_vp8_picture_ref (picture),
|
gst_vp8_decoder_update_reference (self, 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);
|
|
||||||
|
|
||||||
g_assert (klass->output_picture);
|
g_assert (klass->output_picture);
|
||||||
return klass->output_picture (self, picture);
|
return klass->output_picture (self, frame, picture);
|
||||||
|
|
||||||
unmap_and_error:
|
unmap_and_error:
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,7 +91,14 @@ struct _GstVp8DecoderClass
|
||||||
gboolean (*new_sequence) (GstVp8Decoder * decoder,
|
gboolean (*new_sequence) (GstVp8Decoder * decoder,
|
||||||
const GstVp8FrameHdr * frame_hdr);
|
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,
|
gboolean (*new_picture) (GstVp8Decoder * decoder,
|
||||||
|
GstVideoCodecFrame * frame,
|
||||||
GstVp8Picture * picture);
|
GstVp8Picture * picture);
|
||||||
|
|
||||||
gboolean (*start_picture) (GstVp8Decoder * decoder,
|
gboolean (*start_picture) (GstVp8Decoder * decoder,
|
||||||
|
@ -104,7 +111,14 @@ struct _GstVp8DecoderClass
|
||||||
gboolean (*end_picture) (GstVp8Decoder * decoder,
|
gboolean (*end_picture) (GstVp8Decoder * decoder,
|
||||||
GstVp8Picture * picture);
|
GstVp8Picture * picture);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstVp8Decoder:output_picture:
|
||||||
|
* @decoder: a #GstVp8Decoder
|
||||||
|
* @frame: (transfer full): a #GstVideoCodecFrame
|
||||||
|
* @picture: (transfer full): a #GstVp8Picture
|
||||||
|
*/
|
||||||
GstFlowReturn (*output_picture) (GstVp8Decoder * decoder,
|
GstFlowReturn (*output_picture) (GstVp8Decoder * decoder,
|
||||||
|
GstVideoCodecFrame * frame,
|
||||||
GstVp8Picture * picture);
|
GstVp8Picture * picture);
|
||||||
|
|
||||||
/*< private >*/
|
/*< 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,
|
static gboolean gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
|
||||||
const GstVp8FrameHdr * frame_hdr);
|
const GstVp8FrameHdr * frame_hdr);
|
||||||
static gboolean gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder,
|
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 *
|
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,
|
static gboolean gst_d3d11_vp8_dec_start_picture (GstVp8Decoder * decoder,
|
||||||
GstVp8Picture * picture);
|
GstVp8Picture * picture);
|
||||||
static gboolean gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
|
static gboolean gst_d3d11_vp8_dec_decode_picture (GstVp8Decoder * decoder,
|
||||||
|
@ -335,7 +335,8 @@ gst_d3d11_vp8_dec_new_sequence (GstVp8Decoder * decoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
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);
|
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
|
||||||
GstBuffer *view_buffer;
|
GstBuffer *view_buffer;
|
||||||
|
@ -362,10 +363,10 @@ gst_d3d11_vp8_dec_new_picture (GstVp8Decoder * decoder, GstVp8Picture * picture)
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
||||||
GstVp8Picture * picture)
|
GstVideoCodecFrame * frame, GstVp8Picture * picture)
|
||||||
{
|
{
|
||||||
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
|
GstD3D11Vp8Dec *self = GST_D3D11_VP8_DEC (decoder);
|
||||||
GstVideoCodecFrame *frame = NULL;
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstBuffer *output_buffer = NULL;
|
GstBuffer *output_buffer = NULL;
|
||||||
GstBuffer *view_buffer;
|
GstBuffer *view_buffer;
|
||||||
|
|
||||||
|
@ -375,25 +376,16 @@ gst_d3d11_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
||||||
|
|
||||||
if (!view_buffer) {
|
if (!view_buffer) {
|
||||||
GST_ERROR_OBJECT (self, "Could not get output view");
|
GST_ERROR_OBJECT (self, "Could not get output view");
|
||||||
return GST_FLOW_ERROR;
|
goto 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!picture->frame_hdr.show_frame) {
|
if (!picture->frame_hdr.show_frame) {
|
||||||
GST_LOG_OBJECT (self, "Decode only picture %p", picture);
|
GST_LOG_OBJECT (self, "Decode only picture %p", picture);
|
||||||
GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
|
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,
|
/* 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 */
|
* up to gop size but our dpb pool cannot be increased */
|
||||||
if (self->use_d3d11_output &&
|
if (self->use_d3d11_output &&
|
||||||
gst_d3d11_decoder_supports_direct_rendering (self->d3d11_decoder) &&
|
gst_d3d11_decoder_supports_direct_rendering (self->d3d11_decoder) &&
|
||||||
GST_VIDEO_DECODER (self)->input_segment.rate > 0) {
|
vdec->input_segment.rate > 0) {
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
|
|
||||||
output_buffer = gst_buffer_ref (view_buffer);
|
output_buffer = gst_buffer_ref (view_buffer);
|
||||||
mem = gst_buffer_peek_memory (output_buffer, 0);
|
mem = gst_buffer_peek_memory (output_buffer, 0);
|
||||||
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
|
||||||
} else {
|
} else {
|
||||||
output_buffer =
|
output_buffer = gst_video_decoder_allocate_output_buffer (vdec);
|
||||||
gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER (self));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!output_buffer) {
|
if (!output_buffer) {
|
||||||
GST_ERROR_OBJECT (self, "Couldn't allocate output buffer");
|
GST_ERROR_OBJECT (self, "Couldn't allocate output buffer");
|
||||||
return GST_FLOW_ERROR;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->output_buffer = output_buffer;
|
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,
|
picture->frame_hdr.width, picture->frame_hdr.height,
|
||||||
view_buffer, output_buffer)) {
|
view_buffer, output_buffer)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
GST_ERROR_OBJECT (self, "Failed to copy buffer");
|
||||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
goto error;
|
||||||
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "Finish frame %" GST_TIME_FORMAT,
|
GST_LOG_OBJECT (self, "Finish frame %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (GST_BUFFER_PTS (output_buffer)));
|
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 *
|
static GstD3D11DecoderOutputView *
|
||||||
|
|
|
@ -657,18 +657,17 @@ fail:
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_v4l2_codec_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
gst_v4l2_codec_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
||||||
GstVp8Picture * picture)
|
GstVideoCodecFrame * frame, GstVp8Picture * picture)
|
||||||
{
|
{
|
||||||
GstV4l2CodecVp8Dec *self = GST_V4L2_CODEC_VP8_DEC (decoder);
|
GstV4l2CodecVp8Dec *self = GST_V4L2_CODEC_VP8_DEC (decoder);
|
||||||
|
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||||
GstV4l2Request *request = gst_vp8_picture_get_user_data (picture);
|
GstV4l2Request *request = gst_vp8_picture_get_user_data (picture);
|
||||||
gint ret;
|
gint ret;
|
||||||
guint32 frame_num;
|
guint32 frame_num;
|
||||||
GstVideoCodecFrame *frame, *other_frame;
|
|
||||||
GstVp8Picture *other_pic;
|
|
||||||
GstV4l2Request *other_request;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Output picture %u", picture->system_frame_number);
|
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))
|
if (gst_v4l2_request_is_done (request))
|
||||||
goto finish_frame;
|
goto finish_frame;
|
||||||
|
|
||||||
|
@ -676,38 +675,27 @@ gst_v4l2_codec_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
||||||
("Decoding frame took too long"), (NULL));
|
("Decoding frame took too long"), (NULL));
|
||||||
return GST_FLOW_ERROR;
|
goto error;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
||||||
("Decoding request failed: %s", g_strerror (errno)), (NULL));
|
("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)) {
|
||||||
if (!gst_v4l2_decoder_dequeue_src (self->decoder, &frame_num)) {
|
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
||||||
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
("Decoder did not produce a frame"), (NULL));
|
||||||
("Decoder did not produce a frame"), (NULL));
|
goto error;
|
||||||
return GST_FLOW_ERROR;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (frame_num == picture->system_frame_number)
|
if (frame_num != picture->system_frame_number) {
|
||||||
break;
|
GST_ELEMENT_ERROR (self, STREAM, DECODE,
|
||||||
|
("Decoder produced out of order frame"), (NULL));
|
||||||
other_frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
|
goto error;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finish_frame:
|
finish_frame:
|
||||||
gst_v4l2_request_set_done (request);
|
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);
|
g_return_val_if_fail (frame->output_buffer, GST_FLOW_ERROR);
|
||||||
|
|
||||||
/* Hold on reference buffers for the rest of the picture lifetime */
|
/* Hold on reference buffers for the rest of the picture lifetime */
|
||||||
|
@ -717,7 +705,15 @@ finish_frame:
|
||||||
if (self->copy_frames)
|
if (self->copy_frames)
|
||||||
gst_v4l2_codec_vp8_dec_copy_output_buffer (self, frame);
|
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
|
static void
|
||||||
|
|
Loading…
Reference in a new issue