mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-22 09:41:07 +00:00
nvdecoder: Move common logic to decoder helper object
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5285>
This commit is contained in:
parent
6cf6c73712
commit
f9169c5431
7 changed files with 126 additions and 290 deletions
|
@ -583,20 +583,9 @@ gst_nv_av1_dec_new_picture (GstAV1Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstAV1Picture * picture)
|
||||
{
|
||||
GstNvAV1Dec *self = GST_NV_AV1_DEC (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret;
|
||||
|
||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
GST_LOG_OBJECT (self,
|
||||
"New decoder surface %p (index %d)", surface, surface->index);
|
||||
|
||||
gst_av1_picture_set_user_data (picture,
|
||||
surface, (GDestroyNotify) gst_nv_dec_surface_unref);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
return gst_nv_decoder_new_picture (self->decoder,
|
||||
GST_CODEC_PICTURE (picture));
|
||||
}
|
||||
|
||||
static GstNvDecSurface *
|
||||
|
@ -1019,33 +1008,9 @@ gst_nv_av1_dec_output_picture (GstAV1Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstAV1Picture * picture)
|
||||
{
|
||||
GstNvAV1Dec *self = GST_NV_AV1_DEC (decoder);
|
||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||
|
||||
GST_LOG_OBJECT (self, "Outputting picture %p", picture);
|
||||
|
||||
surface = (GstNvDecSurface *) gst_av1_picture_get_user_data (picture);
|
||||
if (!surface) {
|
||||
GST_ERROR_OBJECT (self, "No decoder frame in picture %p", picture);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = gst_nv_decoder_finish_surface (self->decoder,
|
||||
vdec, GST_CODEC_PICTURE (picture)->discont_state, surface,
|
||||
&frame->output_buffer);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto error;
|
||||
|
||||
gst_av1_picture_unref (picture);
|
||||
|
||||
return gst_video_decoder_finish_frame (vdec, frame);
|
||||
|
||||
error:
|
||||
gst_video_decoder_drop_frame (vdec, frame);
|
||||
gst_av1_picture_unref (picture);
|
||||
|
||||
return ret;
|
||||
return gst_nv_decoder_output_picture (self->decoder,
|
||||
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture), 0);
|
||||
}
|
||||
|
||||
static guint
|
||||
|
|
|
@ -361,9 +361,11 @@ gst_nv_decoder_configure (GstNvDecoder * decoder, cudaVideoCodec codec,
|
|||
}
|
||||
|
||||
GstFlowReturn
|
||||
gst_nv_decoder_acquire_surface (GstNvDecoder * decoder,
|
||||
GstNvDecSurface ** surface)
|
||||
gst_nv_decoder_new_picture (GstNvDecoder * decoder, GstCodecPicture * picture)
|
||||
{
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret;
|
||||
|
||||
g_return_val_if_fail (GST_IS_NV_DECODER (decoder), GST_FLOW_ERROR);
|
||||
|
||||
if (!decoder->object) {
|
||||
|
@ -394,7 +396,14 @@ gst_nv_decoder_acquire_surface (GstNvDecoder * decoder,
|
|||
}
|
||||
}
|
||||
|
||||
return gst_nv_dec_object_acquire_surface (decoder->object, surface);
|
||||
ret = gst_nv_dec_object_acquire_surface (decoder->object, &surface);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
gst_codec_picture_set_user_data (picture,
|
||||
surface, (GDestroyNotify) gst_nv_dec_surface_unref);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -710,38 +719,39 @@ done:
|
|||
}
|
||||
|
||||
GstFlowReturn
|
||||
gst_nv_decoder_finish_surface (GstNvDecoder * decoder,
|
||||
GstVideoDecoder * videodec, GstVideoCodecState * input_state,
|
||||
GstNvDecSurface * surface, GstBuffer ** buffer)
|
||||
gst_nv_decoder_output_picture (GstNvDecoder * decoder,
|
||||
GstVideoDecoder * videodec, GstVideoCodecFrame * frame,
|
||||
GstCodecPicture * picture, guint buffer_flags)
|
||||
{
|
||||
GstBuffer *outbuf = nullptr;
|
||||
gboolean ret = FALSE;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GstNvDecSurface *surface;
|
||||
GstCudaStream *stream;
|
||||
GstFlowReturn flow_ret;
|
||||
|
||||
g_return_val_if_fail (GST_IS_NV_DECODER (decoder), GST_FLOW_ERROR);
|
||||
g_return_val_if_fail (GST_IS_VIDEO_DECODER (videodec), GST_FLOW_ERROR);
|
||||
g_return_val_if_fail (decoder->object != nullptr, GST_FLOW_ERROR);
|
||||
g_return_val_if_fail (surface != nullptr, GST_FLOW_ERROR);
|
||||
g_return_val_if_fail (buffer != nullptr, GST_FLOW_ERROR);
|
||||
|
||||
if (input_state) {
|
||||
if (!gst_nv_decoder_negotiate (decoder, videodec, input_state)) {
|
||||
if (picture->discont_state) {
|
||||
if (!gst_nv_decoder_negotiate (decoder, videodec, picture->discont_state)) {
|
||||
GST_ERROR_OBJECT (videodec, "Couldn't re-negotiate with updated state");
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
ret = GST_FLOW_NOT_NEGOTIATED;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
surface = (GstNvDecSurface *) gst_codec_picture_get_user_data (picture);
|
||||
if (!surface) {
|
||||
GST_ERROR_OBJECT (decoder, "No decoder frame in picture %p", picture);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!gst_cuda_context_push (decoder->context)) {
|
||||
GST_ERROR_OBJECT (decoder, "Couldn't push context");
|
||||
return GST_FLOW_ERROR;
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
stream = decoder->stream;
|
||||
flow_ret = gst_nv_dec_object_map_surface (decoder->object, surface, stream);
|
||||
if (flow_ret != GST_FLOW_OK) {
|
||||
ret = gst_nv_dec_object_map_surface (decoder->object, surface, stream);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
gst_cuda_context_pop (nullptr);
|
||||
return flow_ret;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (decoder->output_type == GST_NV_DECODER_OUTPUT_TYPE_CUDA &&
|
||||
|
@ -752,13 +762,14 @@ gst_nv_decoder_finish_surface (GstNvDecoder * decoder,
|
|||
GstBuffer *buf;
|
||||
GstVideoInfo *info = &decoder->info;
|
||||
|
||||
flow_ret = gst_nv_dec_object_export_surface (decoder->object,
|
||||
ret = gst_nv_dec_object_export_surface (decoder->object,
|
||||
surface, stream, &mem);
|
||||
if (flow_ret != GST_FLOW_OK) {
|
||||
if (ret != GST_FLOW_OK) {
|
||||
GST_WARNING_OBJECT (decoder, "Couldn't export surface");
|
||||
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
return flow_ret;
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
gst_cuda_context_pop (nullptr);
|
||||
|
@ -776,67 +787,77 @@ gst_nv_decoder_finish_surface (GstNvDecoder * decoder,
|
|||
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
|
||||
cmem->info.offset, cmem->info.stride);
|
||||
|
||||
*buffer = buf;
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
frame->output_buffer = buf;
|
||||
} else {
|
||||
gboolean copy_ret = FALSE;
|
||||
|
||||
frame->output_buffer = gst_video_decoder_allocate_output_buffer (videodec);
|
||||
if (!frame->output_buffer) {
|
||||
GST_ERROR_OBJECT (videodec, "Couldn't allocate output buffer");
|
||||
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (decoder->output_type) {
|
||||
case GST_NV_DECODER_OUTPUT_TYPE_SYSTEM:
|
||||
copy_ret = gst_nv_decoder_copy_frame_to_system (decoder,
|
||||
surface, frame->output_buffer);
|
||||
break;
|
||||
#ifdef HAVE_CUDA_GST_GL
|
||||
case GST_NV_DECODER_OUTPUT_TYPE_GL:
|
||||
g_assert (decoder->gl_context != nullptr);
|
||||
|
||||
copy_ret = gst_nv_decoder_copy_frame_to_gl (decoder,
|
||||
GST_GL_CONTEXT (decoder->gl_context), surface,
|
||||
frame->output_buffer);
|
||||
break;
|
||||
#endif
|
||||
case GST_NV_DECODER_OUTPUT_TYPE_CUDA:
|
||||
copy_ret = gst_nv_decoder_copy_frame_to_cuda (decoder,
|
||||
surface, frame->output_buffer, stream);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
ret = GST_FLOW_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* FIXME: This is the case where OpenGL context of downstream glbufferpool
|
||||
* belongs to non-nvidia (or different device).
|
||||
* There should be enhancement to ensure nvdec has compatible OpenGL context
|
||||
*/
|
||||
if (!copy_ret && decoder->output_type == GST_NV_DECODER_OUTPUT_TYPE_GL) {
|
||||
GST_WARNING_OBJECT (videodec,
|
||||
"Couldn't copy frame to GL memory, fallback to system memory");
|
||||
decoder->output_type = GST_NV_DECODER_OUTPUT_TYPE_SYSTEM;
|
||||
|
||||
copy_ret = gst_nv_decoder_copy_frame_to_system (decoder, surface,
|
||||
frame->output_buffer);
|
||||
}
|
||||
|
||||
outbuf = gst_video_decoder_allocate_output_buffer (videodec);
|
||||
if (!outbuf) {
|
||||
GST_ERROR_OBJECT (videodec, "Couldn't allocate output buffer");
|
||||
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
switch (decoder->output_type) {
|
||||
case GST_NV_DECODER_OUTPUT_TYPE_SYSTEM:
|
||||
ret = gst_nv_decoder_copy_frame_to_system (decoder, surface, outbuf);
|
||||
break;
|
||||
#ifdef HAVE_CUDA_GST_GL
|
||||
case GST_NV_DECODER_OUTPUT_TYPE_GL:
|
||||
g_assert (decoder->gl_context != nullptr);
|
||||
|
||||
ret = gst_nv_decoder_copy_frame_to_gl (decoder,
|
||||
GST_GL_CONTEXT (decoder->gl_context), surface, outbuf);
|
||||
break;
|
||||
#endif
|
||||
case GST_NV_DECODER_OUTPUT_TYPE_CUDA:
|
||||
ret = gst_nv_decoder_copy_frame_to_cuda (decoder,
|
||||
surface, outbuf, stream);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
if (!copy_ret) {
|
||||
GST_WARNING_OBJECT (videodec, "Failed to copy frame");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: This is the case where OpenGL context of downstream glbufferpool
|
||||
* belongs to non-nvidia (or different device).
|
||||
* There should be enhancement to ensure nvdec has compatible OpenGL context
|
||||
*/
|
||||
if (!ret && decoder->output_type == GST_NV_DECODER_OUTPUT_TYPE_GL) {
|
||||
GST_WARNING_OBJECT (videodec,
|
||||
"Couldn't copy frame to GL memory, fallback to system memory");
|
||||
decoder->output_type = GST_NV_DECODER_OUTPUT_TYPE_SYSTEM;
|
||||
GST_BUFFER_FLAG_SET (frame->output_buffer, buffer_flags);
|
||||
gst_codec_picture_unref (picture);
|
||||
|
||||
ret = gst_nv_decoder_copy_frame_to_system (decoder, surface, outbuf);
|
||||
}
|
||||
|
||||
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
||||
gst_cuda_context_pop (nullptr);
|
||||
|
||||
if (!ret) {
|
||||
GST_WARNING_OBJECT (videodec, "Failed to copy frame");
|
||||
goto error;
|
||||
}
|
||||
|
||||
*buffer = outbuf;
|
||||
|
||||
return GST_FLOW_OK;
|
||||
return gst_video_decoder_finish_frame (videodec, frame);
|
||||
|
||||
error:
|
||||
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
||||
gst_clear_buffer (&outbuf);
|
||||
return GST_FLOW_ERROR;
|
||||
gst_codec_picture_unref (picture);
|
||||
gst_video_decoder_release_frame (videodec, frame);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/cuda/gstcuda.h>
|
||||
#include <gst/codecs/gstcodecpicture.h>
|
||||
#include "gstcuvidloader.h"
|
||||
#include "gstnvdecobject.h"
|
||||
|
||||
|
@ -57,17 +58,17 @@ gboolean gst_nv_decoder_configure (GstNvDecoder * decoder,
|
|||
guint init_max_width,
|
||||
guint init_max_height);
|
||||
|
||||
GstFlowReturn gst_nv_decoder_acquire_surface (GstNvDecoder * decoder,
|
||||
GstNvDecSurface ** surface);
|
||||
GstFlowReturn gst_nv_decoder_new_picture (GstNvDecoder * decoder,
|
||||
GstCodecPicture * picture);
|
||||
|
||||
gboolean gst_nv_decoder_decode (GstNvDecoder * decoder,
|
||||
CUVIDPICPARAMS * params);
|
||||
|
||||
GstFlowReturn gst_nv_decoder_finish_surface (GstNvDecoder * decoder,
|
||||
GstFlowReturn gst_nv_decoder_output_picture (GstNvDecoder * decoder,
|
||||
GstVideoDecoder * videodec,
|
||||
GstVideoCodecState * input_state,
|
||||
GstNvDecSurface *surface,
|
||||
GstBuffer ** buffer);
|
||||
GstVideoCodecFrame * frame,
|
||||
GstCodecPicture * picture,
|
||||
guint buffer_flags);
|
||||
|
||||
void gst_nv_decoder_set_flushing (GstNvDecoder * decoder,
|
||||
gboolean flushing);
|
||||
|
|
|
@ -694,20 +694,9 @@ gst_nv_h264_dec_new_picture (GstH264Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
||||
{
|
||||
GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret;
|
||||
|
||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
GST_LOG_OBJECT (self,
|
||||
"New decoder surface %p (index %d)", surface, surface->index);
|
||||
|
||||
gst_h264_picture_set_user_data (picture,
|
||||
surface, (GDestroyNotify) gst_nv_dec_surface_unref);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
return gst_nv_decoder_new_picture (self->decoder,
|
||||
GST_CODEC_PICTURE (picture));
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -736,45 +725,10 @@ gst_nv_h264_dec_output_picture (GstH264Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
||||
{
|
||||
GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
|
||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||
|
||||
GST_LOG_OBJECT (self,
|
||||
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
|
||||
|
||||
surface = (GstNvDecSurface *) gst_h264_picture_get_user_data (picture);
|
||||
if (!surface) {
|
||||
GST_ERROR_OBJECT (self, "No decoder surface in picture %p", picture);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = gst_nv_decoder_finish_surface (self->decoder,
|
||||
vdec, GST_CODEC_PICTURE (picture)->discont_state, surface,
|
||||
&frame->output_buffer);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto error;
|
||||
|
||||
if (picture->buffer_flags != 0) {
|
||||
gboolean interlaced =
|
||||
(picture->buffer_flags & GST_VIDEO_BUFFER_FLAG_INTERLACED) != 0;
|
||||
gboolean tff = (picture->buffer_flags & GST_VIDEO_BUFFER_FLAG_TFF) != 0;
|
||||
|
||||
GST_TRACE_OBJECT (self,
|
||||
"apply buffer flags 0x%x (interlaced %d, top-field-first %d)",
|
||||
picture->buffer_flags, interlaced, tff);
|
||||
GST_BUFFER_FLAG_SET (frame->output_buffer, picture->buffer_flags);
|
||||
}
|
||||
|
||||
gst_h264_picture_unref (picture);
|
||||
|
||||
return gst_video_decoder_finish_frame (vdec, frame);
|
||||
|
||||
error:
|
||||
gst_h264_picture_unref (picture);
|
||||
gst_video_decoder_release_frame (vdec, frame);
|
||||
|
||||
return ret;
|
||||
return gst_nv_decoder_output_picture (self->decoder,
|
||||
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture),
|
||||
picture->buffer_flags);
|
||||
}
|
||||
|
||||
static GstNvDecSurface *
|
||||
|
|
|
@ -647,20 +647,9 @@ gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
|
|||
GstVideoCodecFrame * cframe, GstH265Picture * picture)
|
||||
{
|
||||
GstNvH265Dec *self = GST_NV_H265_DEC (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret;
|
||||
|
||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
GST_LOG_OBJECT (self, "New decoder surface %p (index %d)",
|
||||
surface, surface->index);
|
||||
|
||||
gst_h265_picture_set_user_data (picture,
|
||||
surface, (GDestroyNotify) gst_nv_dec_surface_unref);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
return gst_nv_decoder_new_picture (self->decoder,
|
||||
GST_CODEC_PICTURE (picture));
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
|
@ -668,34 +657,10 @@ gst_nv_h265_dec_output_picture (GstH265Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstH265Picture * picture)
|
||||
{
|
||||
GstNvH265Dec *self = GST_NV_H265_DEC (decoder);
|
||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||
|
||||
GST_LOG_OBJECT (self,
|
||||
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
|
||||
|
||||
surface = (GstNvDecSurface *) gst_h265_picture_get_user_data (picture);
|
||||
if (!surface) {
|
||||
GST_ERROR_OBJECT (self, "No decoder surface in picture %p", picture);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = gst_nv_decoder_finish_surface (self->decoder,
|
||||
vdec, GST_CODEC_PICTURE (picture)->discont_state, surface,
|
||||
&frame->output_buffer);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto error;
|
||||
|
||||
gst_h265_picture_unref (picture);
|
||||
|
||||
return gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
|
||||
|
||||
error:
|
||||
gst_video_decoder_drop_frame (vdec, frame);
|
||||
gst_h265_picture_unref (picture);
|
||||
|
||||
return ret;
|
||||
return gst_nv_decoder_output_picture (self->decoder,
|
||||
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture),
|
||||
picture->buffer_flags);
|
||||
}
|
||||
|
||||
static GstNvDecSurface *
|
||||
|
|
|
@ -516,20 +516,9 @@ gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstVp8Picture * picture)
|
||||
{
|
||||
GstNvVp8Dec *self = GST_NV_VP8_DEC (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret;
|
||||
|
||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
GST_LOG_OBJECT (self,
|
||||
"New decoder frame %p (index %d)", surface, surface->index);
|
||||
|
||||
gst_vp8_picture_set_user_data (picture,
|
||||
surface, (GDestroyNotify) gst_nv_dec_surface_unref);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
return gst_nv_decoder_new_picture (self->decoder,
|
||||
GST_CODEC_PICTURE (picture));
|
||||
}
|
||||
|
||||
static GstNvDecSurface *
|
||||
|
@ -635,33 +624,9 @@ gst_nv_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstVp8Picture * picture)
|
||||
{
|
||||
GstNvVp8Dec *self = GST_NV_VP8_DEC (decoder);
|
||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||
|
||||
GST_LOG_OBJECT (self, "Outputting picture %p", picture);
|
||||
|
||||
surface = (GstNvDecSurface *) gst_vp8_picture_get_user_data (picture);
|
||||
if (!surface) {
|
||||
GST_ERROR_OBJECT (self, "No decoder frame in picture %p", picture);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = gst_nv_decoder_finish_surface (self->decoder,
|
||||
vdec, GST_CODEC_PICTURE (picture)->discont_state, surface,
|
||||
&frame->output_buffer);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto error;
|
||||
|
||||
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 ret;
|
||||
return gst_nv_decoder_output_picture (self->decoder,
|
||||
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture), 0);
|
||||
}
|
||||
|
||||
static guint
|
||||
|
|
|
@ -525,20 +525,9 @@ gst_nv_vp9_dec_new_picture (GstVp9Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstVp9Picture * picture)
|
||||
{
|
||||
GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret;
|
||||
|
||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
|
||||
GST_LOG_OBJECT (self,
|
||||
"New decoder frame %p (index %d)", surface, surface->index);
|
||||
|
||||
gst_vp9_picture_set_user_data (picture,
|
||||
surface, (GDestroyNotify) gst_nv_dec_surface_unref);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
return gst_nv_decoder_new_picture (self->decoder,
|
||||
GST_CODEC_PICTURE (picture));
|
||||
}
|
||||
|
||||
static GstNvDecSurface *
|
||||
|
@ -731,33 +720,9 @@ gst_nv_vp9_dec_output_picture (GstVp9Decoder * decoder,
|
|||
GstVideoCodecFrame * frame, GstVp9Picture * picture)
|
||||
{
|
||||
GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
|
||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
||||
GstNvDecSurface *surface;
|
||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
||||
|
||||
GST_LOG_OBJECT (self, "Outputting picture %p", picture);
|
||||
|
||||
surface = (GstNvDecSurface *) gst_vp9_picture_get_user_data (picture);
|
||||
if (!surface) {
|
||||
GST_ERROR_OBJECT (self, "No decoder frame in picture %p", picture);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = gst_nv_decoder_finish_surface (self->decoder,
|
||||
vdec, GST_CODEC_PICTURE (picture)->discont_state, surface,
|
||||
&frame->output_buffer);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto error;
|
||||
|
||||
gst_vp9_picture_unref (picture);
|
||||
|
||||
return gst_video_decoder_finish_frame (vdec, frame);
|
||||
|
||||
error:
|
||||
gst_video_decoder_drop_frame (vdec, frame);
|
||||
gst_vp9_picture_unref (picture);
|
||||
|
||||
return ret;
|
||||
return gst_nv_decoder_output_picture (self->decoder,
|
||||
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture), 0);
|
||||
}
|
||||
|
||||
static guint
|
||||
|
|
Loading…
Reference in a new issue