FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ffmpeg_cuvid.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/hwcontext.h"
20 
21 #include "ffmpeg.h"
22 
23 typedef struct CUVIDContext {
25 } CUVIDContext;
26 
27 static void cuvid_uninit(AVCodecContext *avctx)
28 {
29  InputStream *ist = avctx->opaque;
31 
32  if (ctx) {
34  av_freep(&ctx);
35  }
36 
38 
39  ist->hwaccel_ctx = 0;
40  ist->hwaccel_uninit = 0;
41 }
42 
44 {
45  InputStream *ist = avctx->opaque;
47 
48  av_log(NULL, AV_LOG_TRACE, "Initializing cuvid hwaccel\n");
49 
50  if (!ctx) {
51  av_log(NULL, AV_LOG_ERROR, "CUVID transcoding is not initialized. "
52  "-hwaccel cuvid should only be used for one-to-one CUVID transcoding "
53  "with no (software) filters.\n");
54  return AVERROR(EINVAL);
55  }
56 
57  return 0;
58 }
59 
61 {
62  InputStream *ist;
63  const enum AVPixelFormat *pix_fmt;
64  AVHWFramesContext *hwframe_ctx;
65  AVBufferRef *device_ref = NULL;
67  int ret = 0;
68 
69  av_log(NULL, AV_LOG_TRACE, "Initializing cuvid transcoding\n");
70 
71  if (ost->source_index < 0)
72  return 0;
73 
74  ist = input_streams[ost->source_index];
75 
76  /* check if the encoder supports CUVID */
77  if (!ost->enc->pix_fmts)
78  goto cancel;
79  for (pix_fmt = ost->enc->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
80  if (*pix_fmt == AV_PIX_FMT_CUDA)
81  break;
82  if (*pix_fmt == AV_PIX_FMT_NONE)
83  goto cancel;
84 
85  /* check if the decoder supports CUVID */
86  if (ist->hwaccel_id != HWACCEL_CUVID || !ist->dec || !ist->dec->pix_fmts)
87  goto cancel;
88  for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
89  if (*pix_fmt == AV_PIX_FMT_CUDA)
90  break;
91  if (*pix_fmt == AV_PIX_FMT_NONE)
92  goto cancel;
93 
94  av_log(NULL, AV_LOG_VERBOSE, "Setting up CUVID transcoding\n");
95 
96  if (ist->hwaccel_ctx) {
97  ctx = ist->hwaccel_ctx;
98  } else {
99  ctx = av_mallocz(sizeof(*ctx));
100  if (!ctx) {
101  ret = AVERROR(ENOMEM);
102  goto error;
103  }
104  }
105 
106  if (!ctx->hw_frames_ctx) {
108  ist->hwaccel_device, NULL, 0);
109  if (ret < 0)
110  goto error;
111 
112  ctx->hw_frames_ctx = av_hwframe_ctx_alloc(device_ref);
113  if (!ctx->hw_frames_ctx) {
114  av_log(NULL, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n");
115  ret = AVERROR(ENOMEM);
116  goto error;
117  }
118  av_buffer_unref(&device_ref);
119 
121  if (!ist->hw_frames_ctx) {
122  av_log(NULL, AV_LOG_ERROR, "av_buffer_ref failed\n");
123  ret = AVERROR(ENOMEM);
124  goto error;
125  }
126 
127  ist->hwaccel_ctx = ctx;
130 
131  /* This is a bit hacky, av_hwframe_ctx_init is called by the cuvid decoder
132  * once it has probed the necessary format information. But as filters/nvenc
133  * need to know the format/sw_format, set them here so they are happy.
134  * This is fine as long as CUVID doesn't add another supported pix_fmt.
135  */
136  hwframe_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
137  hwframe_ctx->format = AV_PIX_FMT_CUDA;
138  hwframe_ctx->sw_format = AV_PIX_FMT_NV12;
139  }
140 
141  return 0;
142 
143 error:
144  av_freep(&ctx);
145  av_buffer_unref(&device_ref);
146  return ret;
147 
148 cancel:
149  if (ist->hwaccel_id == HWACCEL_CUVID) {
150  av_log(NULL, AV_LOG_ERROR, "CUVID hwaccel requested, but impossible to achieve.\n");
151  return AVERROR(EINVAL);
152  }
153 
154  return 0;
155 }
AVBufferRef * hw_frames_ctx
Definition: ffmpeg_cuvid.c:24
#define NULL
Definition: coverity.c:32
static enum AVPixelFormat pix_fmt
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
Definition: buffer.c:124
AVBufferRef * hw_frames_ctx
Definition: ffmpeg.h:343
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:202
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:252
int cuvid_transcode_init(OutputStream *ost)
Definition: ffmpeg_cuvid.c:60
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
Definition: hwcontext.c:459
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
AVCodec * dec
Definition: ffmpeg.h:270
int resample_pix_fmt
Definition: ffmpeg.h:300
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
void(* hwaccel_uninit)(AVCodecContext *s)
Definition: ffmpeg.h:338
#define AVERROR(e)
Definition: error.h:43
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:90
enum AVPixelFormat * pix_fmts
array of supported pixel formats, or NULL if unknown, array is terminated by -1
Definition: avcodec.h:3621
AVFormatContext * ctx
Definition: movenc.c:48
HW acceleration through CUDA.
Definition: pixfmt.h:249
AVCodecContext * enc
Definition: muxing.c:55
main external API structure.
Definition: avcodec.h:1676
uint8_t * data
The data buffer.
Definition: buffer.h:89
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:117
int cuvid_init(AVCodecContext *avctx)
Definition: ffmpeg_cuvid.c:43
int source_index
Definition: ffmpeg.h:410
A reference to a data buffer.
Definition: buffer.h:81
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:177
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:92
void * hwaccel_ctx
Definition: ffmpeg.h:337
char * hwaccel_device
Definition: ffmpeg.h:332
#define av_freep(p)
static void cuvid_uninit(AVCodecContext *avctx)
Definition: ffmpeg_cuvid.c:27
enum HWAccelID hwaccel_id
Definition: ffmpeg.h:331
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:215
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
void * opaque
Private data of the user, can be used to carry app specific stuff.
Definition: avcodec.h:1733
InputStream ** input_streams
Definition: ffmpeg.c:139