mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-16 19:25:18 +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)
|
GstVideoCodecFrame * frame, GstAV1Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvAV1Dec *self = GST_NV_AV1_DEC (decoder);
|
GstNvAV1Dec *self = GST_NV_AV1_DEC (decoder);
|
||||||
GstNvDecSurface *surface;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
return gst_nv_decoder_new_picture (self->decoder,
|
||||||
if (ret != GST_FLOW_OK)
|
GST_CODEC_PICTURE (picture));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstNvDecSurface *
|
static GstNvDecSurface *
|
||||||
|
@ -1019,33 +1008,9 @@ gst_nv_av1_dec_output_picture (GstAV1Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame, GstAV1Picture * picture)
|
GstVideoCodecFrame * frame, GstAV1Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvAV1Dec *self = GST_NV_AV1_DEC (decoder);
|
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);
|
return gst_nv_decoder_output_picture (self->decoder,
|
||||||
|
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture), 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
|
|
|
@ -361,9 +361,11 @@ gst_nv_decoder_configure (GstNvDecoder * decoder, cudaVideoCodec codec,
|
||||||
}
|
}
|
||||||
|
|
||||||
GstFlowReturn
|
GstFlowReturn
|
||||||
gst_nv_decoder_acquire_surface (GstNvDecoder * decoder,
|
gst_nv_decoder_new_picture (GstNvDecoder * decoder, GstCodecPicture * picture)
|
||||||
GstNvDecSurface ** surface)
|
|
||||||
{
|
{
|
||||||
|
GstNvDecSurface *surface;
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_NV_DECODER (decoder), GST_FLOW_ERROR);
|
g_return_val_if_fail (GST_IS_NV_DECODER (decoder), GST_FLOW_ERROR);
|
||||||
|
|
||||||
if (!decoder->object) {
|
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
|
gboolean
|
||||||
|
@ -710,38 +719,39 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
GstFlowReturn
|
GstFlowReturn
|
||||||
gst_nv_decoder_finish_surface (GstNvDecoder * decoder,
|
gst_nv_decoder_output_picture (GstNvDecoder * decoder,
|
||||||
GstVideoDecoder * videodec, GstVideoCodecState * input_state,
|
GstVideoDecoder * videodec, GstVideoCodecFrame * frame,
|
||||||
GstNvDecSurface * surface, GstBuffer ** buffer)
|
GstCodecPicture * picture, guint buffer_flags)
|
||||||
{
|
{
|
||||||
GstBuffer *outbuf = nullptr;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
gboolean ret = FALSE;
|
GstNvDecSurface *surface;
|
||||||
GstCudaStream *stream;
|
GstCudaStream *stream;
|
||||||
GstFlowReturn flow_ret;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_NV_DECODER (decoder), GST_FLOW_ERROR);
|
if (picture->discont_state) {
|
||||||
g_return_val_if_fail (GST_IS_VIDEO_DECODER (videodec), GST_FLOW_ERROR);
|
if (!gst_nv_decoder_negotiate (decoder, videodec, picture->discont_state)) {
|
||||||
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)) {
|
|
||||||
GST_ERROR_OBJECT (videodec, "Couldn't re-negotiate with updated 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)) {
|
if (!gst_cuda_context_push (decoder->context)) {
|
||||||
GST_ERROR_OBJECT (decoder, "Couldn't push context");
|
GST_ERROR_OBJECT (decoder, "Couldn't push context");
|
||||||
return GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream = decoder->stream;
|
stream = decoder->stream;
|
||||||
flow_ret = gst_nv_dec_object_map_surface (decoder->object, surface, stream);
|
ret = gst_nv_dec_object_map_surface (decoder->object, surface, stream);
|
||||||
if (flow_ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
gst_cuda_context_pop (nullptr);
|
gst_cuda_context_pop (nullptr);
|
||||||
return flow_ret;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoder->output_type == GST_NV_DECODER_OUTPUT_TYPE_CUDA &&
|
if (decoder->output_type == GST_NV_DECODER_OUTPUT_TYPE_CUDA &&
|
||||||
|
@ -752,13 +762,14 @@ gst_nv_decoder_finish_surface (GstNvDecoder * decoder,
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstVideoInfo *info = &decoder->info;
|
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);
|
surface, stream, &mem);
|
||||||
if (flow_ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
GST_WARNING_OBJECT (decoder, "Couldn't export surface");
|
GST_WARNING_OBJECT (decoder, "Couldn't export surface");
|
||||||
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
||||||
gst_cuda_context_pop (nullptr);
|
gst_cuda_context_pop (nullptr);
|
||||||
return flow_ret;
|
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_cuda_context_pop (nullptr);
|
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),
|
GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
|
||||||
cmem->info.offset, cmem->info.stride);
|
cmem->info.offset, cmem->info.stride);
|
||||||
|
|
||||||
*buffer = buf;
|
frame->output_buffer = buf;
|
||||||
return GST_FLOW_OK;
|
} 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_nv_dec_object_unmap_surface (decoder->object, surface);
|
||||||
gst_cuda_context_pop (nullptr);
|
gst_cuda_context_pop (nullptr);
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (decoder->output_type) {
|
if (!copy_ret) {
|
||||||
case GST_NV_DECODER_OUTPUT_TYPE_SYSTEM:
|
GST_WARNING_OBJECT (videodec, "Failed to copy frame");
|
||||||
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 ();
|
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: This is the case where OpenGL context of downstream glbufferpool
|
GST_BUFFER_FLAG_SET (frame->output_buffer, buffer_flags);
|
||||||
* belongs to non-nvidia (or different device).
|
gst_codec_picture_unref (picture);
|
||||||
* 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;
|
|
||||||
|
|
||||||
ret = gst_nv_decoder_copy_frame_to_system (decoder, surface, outbuf);
|
return gst_video_decoder_finish_frame (videodec, frame);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
gst_nv_dec_object_unmap_surface (decoder->object, surface);
|
gst_codec_picture_unref (picture);
|
||||||
gst_clear_buffer (&outbuf);
|
gst_video_decoder_release_frame (videodec, frame);
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/cuda/gstcuda.h>
|
#include <gst/cuda/gstcuda.h>
|
||||||
|
#include <gst/codecs/gstcodecpicture.h>
|
||||||
#include "gstcuvidloader.h"
|
#include "gstcuvidloader.h"
|
||||||
#include "gstnvdecobject.h"
|
#include "gstnvdecobject.h"
|
||||||
|
|
||||||
|
@ -57,17 +58,17 @@ gboolean gst_nv_decoder_configure (GstNvDecoder * decoder,
|
||||||
guint init_max_width,
|
guint init_max_width,
|
||||||
guint init_max_height);
|
guint init_max_height);
|
||||||
|
|
||||||
GstFlowReturn gst_nv_decoder_acquire_surface (GstNvDecoder * decoder,
|
GstFlowReturn gst_nv_decoder_new_picture (GstNvDecoder * decoder,
|
||||||
GstNvDecSurface ** surface);
|
GstCodecPicture * picture);
|
||||||
|
|
||||||
gboolean gst_nv_decoder_decode (GstNvDecoder * decoder,
|
gboolean gst_nv_decoder_decode (GstNvDecoder * decoder,
|
||||||
CUVIDPICPARAMS * params);
|
CUVIDPICPARAMS * params);
|
||||||
|
|
||||||
GstFlowReturn gst_nv_decoder_finish_surface (GstNvDecoder * decoder,
|
GstFlowReturn gst_nv_decoder_output_picture (GstNvDecoder * decoder,
|
||||||
GstVideoDecoder * videodec,
|
GstVideoDecoder * videodec,
|
||||||
GstVideoCodecState * input_state,
|
GstVideoCodecFrame * frame,
|
||||||
GstNvDecSurface *surface,
|
GstCodecPicture * picture,
|
||||||
GstBuffer ** buffer);
|
guint buffer_flags);
|
||||||
|
|
||||||
void gst_nv_decoder_set_flushing (GstNvDecoder * decoder,
|
void gst_nv_decoder_set_flushing (GstNvDecoder * decoder,
|
||||||
gboolean flushing);
|
gboolean flushing);
|
||||||
|
|
|
@ -694,20 +694,9 @@ gst_nv_h264_dec_new_picture (GstH264Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
|
GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
|
||||||
GstNvDecSurface *surface;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
return gst_nv_decoder_new_picture (self->decoder,
|
||||||
if (ret != GST_FLOW_OK)
|
GST_CODEC_PICTURE (picture));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -736,45 +725,10 @@ gst_nv_h264_dec_output_picture (GstH264Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
GstVideoCodecFrame * frame, GstH264Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
|
GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
|
||||||
GstNvDecSurface *surface;
|
|
||||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (self,
|
return gst_nv_decoder_output_picture (self->decoder,
|
||||||
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
|
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture),
|
||||||
|
picture->buffer_flags);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstNvDecSurface *
|
static GstNvDecSurface *
|
||||||
|
|
|
@ -647,20 +647,9 @@ gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
|
||||||
GstVideoCodecFrame * cframe, GstH265Picture * picture)
|
GstVideoCodecFrame * cframe, GstH265Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvH265Dec *self = GST_NV_H265_DEC (decoder);
|
GstNvH265Dec *self = GST_NV_H265_DEC (decoder);
|
||||||
GstNvDecSurface *surface;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
return gst_nv_decoder_new_picture (self->decoder,
|
||||||
if (ret != GST_FLOW_OK)
|
GST_CODEC_PICTURE (picture));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -668,34 +657,10 @@ gst_nv_h265_dec_output_picture (GstH265Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame, GstH265Picture * picture)
|
GstVideoCodecFrame * frame, GstH265Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvH265Dec *self = GST_NV_H265_DEC (decoder);
|
GstNvH265Dec *self = GST_NV_H265_DEC (decoder);
|
||||||
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
|
|
||||||
GstNvDecSurface *surface;
|
|
||||||
GstFlowReturn ret = GST_FLOW_ERROR;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (self,
|
return gst_nv_decoder_output_picture (self->decoder,
|
||||||
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
|
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture),
|
||||||
|
picture->buffer_flags);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstNvDecSurface *
|
static GstNvDecSurface *
|
||||||
|
|
|
@ -516,20 +516,9 @@ gst_nv_vp8_dec_new_picture (GstVp8Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame, GstVp8Picture * picture)
|
GstVideoCodecFrame * frame, GstVp8Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvVp8Dec *self = GST_NV_VP8_DEC (decoder);
|
GstNvVp8Dec *self = GST_NV_VP8_DEC (decoder);
|
||||||
GstNvDecSurface *surface;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
return gst_nv_decoder_new_picture (self->decoder,
|
||||||
if (ret != GST_FLOW_OK)
|
GST_CODEC_PICTURE (picture));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstNvDecSurface *
|
static GstNvDecSurface *
|
||||||
|
@ -635,33 +624,9 @@ gst_nv_vp8_dec_output_picture (GstVp8Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame, GstVp8Picture * picture)
|
GstVideoCodecFrame * frame, GstVp8Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvVp8Dec *self = GST_NV_VP8_DEC (decoder);
|
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);
|
return gst_nv_decoder_output_picture (self->decoder,
|
||||||
|
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture), 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
|
|
|
@ -525,20 +525,9 @@ gst_nv_vp9_dec_new_picture (GstVp9Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame, GstVp9Picture * picture)
|
GstVideoCodecFrame * frame, GstVp9Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
|
GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
|
||||||
GstNvDecSurface *surface;
|
|
||||||
GstFlowReturn ret;
|
|
||||||
|
|
||||||
ret = gst_nv_decoder_acquire_surface (self->decoder, &surface);
|
return gst_nv_decoder_new_picture (self->decoder,
|
||||||
if (ret != GST_FLOW_OK)
|
GST_CODEC_PICTURE (picture));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstNvDecSurface *
|
static GstNvDecSurface *
|
||||||
|
@ -731,33 +720,9 @@ gst_nv_vp9_dec_output_picture (GstVp9Decoder * decoder,
|
||||||
GstVideoCodecFrame * frame, GstVp9Picture * picture)
|
GstVideoCodecFrame * frame, GstVp9Picture * picture)
|
||||||
{
|
{
|
||||||
GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
|
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);
|
return gst_nv_decoder_output_picture (self->decoder,
|
||||||
|
GST_VIDEO_DECODER (decoder), frame, GST_CODEC_PICTURE (picture), 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
|
|
Loading…
Reference in a new issue