34 #define MAX_FRAME_COUNT 20
57 const char *err_string;
64 cuGetErrorName(err, &err_name);
65 cuGetErrorString(err, &err_string);
68 if (err_name && err_string)
75 #define CHECK_CU(x) check_cu(avctx, (x), #x)
82 CUVIDDECODECREATEINFO cuinfo;
88 avctx->
width = format->display_area.right;
89 avctx->
height = format->display_area.bottom;
92 (
AVRational){ format->display_aspect_ratio.x, format->display_aspect_ratio.y },
95 if (!format->progressive_sequence)
100 if (format->video_signal_description.video_full_range_flag)
105 avctx->
color_primaries = format->video_signal_description.color_primaries;
106 avctx->
color_trc = format->video_signal_description.transfer_characteristics;
107 avctx->
colorspace = format->video_signal_description.matrix_coefficients;
112 if (format->frame_rate.numerator && format->frame_rate.denominator) {
130 if (hwframe_ctx->
pool) {
141 memset(&cuinfo, 0,
sizeof(cuinfo));
143 cuinfo.CodecType = ctx->
codec_type = format->codec;
144 cuinfo.ChromaFormat = format->chroma_format;
145 cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
149 cuinfo.ulTargetWidth = cuinfo.ulWidth;
150 cuinfo.ulTargetHeight = cuinfo.ulHeight;
152 cuinfo.target_rect.left = 0;
153 cuinfo.target_rect.top = 0;
154 cuinfo.target_rect.right = cuinfo.ulWidth;
155 cuinfo.target_rect.bottom = cuinfo.ulHeight;
158 cuinfo.ulNumOutputSurfaces = 1;
159 cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
161 cuinfo.DeinterlaceMode = cudaVideoDeinterlaceMode_Weave;
215 CUVIDSOURCEDATAPACKET cupkt;
219 int ret = 0, eret = 0;
221 if (
ctx->bsf && avpkt->size) {
238 avpkt = &filtered_packet;
241 ret =
CHECK_CU(cuCtxPushCurrent(cuda_ctx));
247 memset(&cupkt, 0,
sizeof(cupkt));
250 cupkt.payload_size = avpkt->size;
251 cupkt.payload = avpkt->data;
254 cupkt.flags = CUVID_PKT_TIMESTAMP;
258 cupkt.flags = CUVID_PKT_ENDOFSTREAM;
261 ret =
CHECK_CU(cuvidParseVideoData(
ctx->cuparser, &cupkt));
266 if (
ctx->internal_error)
267 ret =
ctx->internal_error;
272 CUVIDPARSERDISPINFO dispinfo;
274 unsigned int pitch = 0;
280 memset(¶ms, 0,
sizeof(params));
281 params.progressive_frame = dispinfo.progressive_frame;
282 params.second_field = 0;
283 params.top_field_first = dispinfo.top_field_first;
285 ret =
CHECK_CU(cuvidMapVideoFrame(
ctx->cudecoder, dispinfo.picture_index, &mapped_frame, &pitch, ¶ms));
302 for (i = 0; i < 2; i++) {
303 CUDA_MEMCPY2D cpy = {
304 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
305 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
306 .srcDevice = mapped_frame,
312 .Height = avctx->coded_height >> (i ? 1 : 0),
319 offset += avctx->coded_height;
333 tmp_frame->
data[1] = (
uint8_t*)(mapped_frame + avctx->coded_height * pitch);
335 tmp_frame->
width = avctx->width;
336 tmp_frame->
height = avctx->height;
372 if (!dispinfo.progressive_frame)
382 eret =
CHECK_CU(cuvidUnmapVideoFrame(
ctx->cudecoder, mapped_frame));
402 cuvidDestroyVideoParser(ctx->
cuparser);
421 CUVIDDECODECREATEINFO cuinfo;
422 CUvideodecoder cudec = 0;
425 memset(&cuinfo, 0,
sizeof(cuinfo));
427 cuinfo.CodecType = cuparseinfo->CodecType;
428 cuinfo.ChromaFormat = cudaVideoChromaFormat_420;
429 cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
431 cuinfo.ulWidth = 1280;
432 cuinfo.ulHeight = 720;
433 cuinfo.ulTargetWidth = cuinfo.ulWidth;
434 cuinfo.ulTargetHeight = cuinfo.ulHeight;
436 cuinfo.target_rect.left = 0;
437 cuinfo.target_rect.top = 0;
438 cuinfo.target_rect.right = cuinfo.ulWidth;
439 cuinfo.target_rect.bottom = cuinfo.ulHeight;
442 cuinfo.ulNumOutputSurfaces = 1;
443 cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
445 cuinfo.DeinterlaceMode = cudaVideoDeinterlaceMode_Weave;
447 ret =
CHECK_CU(cuvidCreateDecoder(&cudec, &cuinfo));
451 ret =
CHECK_CU(cuvidDestroyDecoder(cudec));
464 CUVIDPARSERPARAMS cuparseinfo;
465 CUVIDEOFORMATEX cuparse_ext;
466 CUVIDSOURCEDATAPACKET seq_pkt;
507 device_hwctx = device_ctx->
hwctx;
521 ret =
CHECK_CU(cuDeviceGet(&device, 0));
525 ret =
CHECK_CU(cuCtxCreate(&cuda_ctx, CU_CTX_SCHED_BLOCKING_SYNC, device));
532 device_hwctx = device_ctx->
hwctx;
535 ret =
CHECK_CU(cuCtxPopCurrent(&dummy));
553 memset(&cuparseinfo, 0,
sizeof(cuparseinfo));
554 memset(&cuparse_ext, 0,
sizeof(cuparse_ext));
555 memset(&seq_pkt, 0,
sizeof(seq_pkt));
557 cuparseinfo.pExtVideoInfo = &cuparse_ext;
560 #if CONFIG_H264_CUVID_DECODER
562 cuparseinfo.CodecType = cudaVideoCodec_H264;
565 #if CONFIG_HEVC_CUVID_DECODER
567 cuparseinfo.CodecType = cudaVideoCodec_HEVC;
570 #if CONFIG_VP8_CUVID_DECODER
572 cuparseinfo.CodecType = cudaVideoCodec_VP8;
575 #if CONFIG_VP9_CUVID_DECODER
577 cuparseinfo.CodecType = cudaVideoCodec_VP9;
580 #if CONFIG_VC1_CUVID_DECODER
582 cuparseinfo.CodecType = cudaVideoCodec_VC1;
609 memcpy(cuparse_ext.raw_seqhdr_data,
614 memcpy(cuparse_ext.raw_seqhdr_data,
620 cuparseinfo.ulMaxDisplayDelay = 4;
621 cuparseinfo.pUserData = avctx;
626 ret =
CHECK_CU(cuCtxPushCurrent(cuda_ctx));
638 seq_pkt.payload = cuparse_ext.raw_seqhdr_data;
639 seq_pkt.payload_size = cuparse_ext.format.seqhdr_data_length;
641 if (seq_pkt.payload && seq_pkt.payload_size) {
647 ret =
CHECK_CU(cuCtxPopCurrent(&dummy));
658 #define DEFINE_CUVID_CODEC(x, X) \
659 AVHWAccel ff_##x##_cuvid_hwaccel = { \
660 .name = #x "_cuvid", \
661 .type = AVMEDIA_TYPE_VIDEO, \
662 .id = AV_CODEC_ID_##X, \
663 .pix_fmt = AV_PIX_FMT_CUDA, \
665 AVCodec ff_##x##_cuvid_decoder = { \
666 .name = #x "_cuvid", \
667 .long_name = NULL_IF_CONFIG_SMALL("Nvidia CUVID " #X " decoder"), \
668 .type = AVMEDIA_TYPE_VIDEO, \
669 .id = AV_CODEC_ID_##X, \
670 .priv_data_size = sizeof(CuvidContext), \
671 .init = cuvid_decode_init, \
672 .close = cuvid_decode_end, \
673 .decode = cuvid_decode_frame, \
674 .capabilities = AV_CODEC_CAP_DELAY, \
675 .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
680 #if CONFIG_HEVC_CUVID_DECODER
684 #if CONFIG_H264_CUVID_DECODER
688 #if CONFIG_VP8_CUVID_DECODER
692 #if CONFIG_VP9_CUVID_DECODER
696 #if CONFIG_VC1_CUVID_DECODER
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
void av_bsf_free(AVBSFContext **ctx)
Free a bitstream filter context and everything associated with it; write NULL into the supplied point...
const struct AVCodec * codec
AVCodecParameters * par_out
Parameters of the output stream.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
int coded_width
Bitstream width / height, may be different from width/height e.g.
int64_t bit_rate
the average bitrate
enum AVColorRange color_range
MPEG vs JPEG YUV range.
The bitstream filter state.
static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT *format)
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
int width
The allocated dimensions of the frames in this pool.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
void av_frame_set_pkt_duration(AVFrame *frame, int64_t val)
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
#define DEFINE_CUVID_CODEC(x, X)
void av_frame_set_pkt_size(AVFrame *frame, int val)
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set.
static int check_cu(AVCodecContext *avctx, CUresult err, const char *func)
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx)
Allocate a context for a given bitstream filter.
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
static void cuvid_ctx_free(AVHWDeviceContext *ctx)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
static av_cold int cuvid_decode_init(AVCodecContext *avctx)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
AVFifoBuffer * frame_queue
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
static av_cold int cuvid_decode_end(AVCodecContext *avctx)
int ff_set_sar(AVCodecContext *avctx, AVRational sar)
Check that the provided sample aspect ratio is valid and set it on the codec context.
int interlaced_frame
The content of the picture is interlaced.
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
An API-specific header for AV_HWDEVICE_TYPE_CUDA.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
cudaVideoChromaFormat chroma_format
int width
width and height of the video frame
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
cudaVideoCodec codec_type
void(* free)(struct AVHWDeviceContext *ctx)
This field may be set by the caller before calling av_hwdevice_ctx_init().
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
int flags
AV_CODEC_FLAG_*.
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
static const uint8_t offset[127][2]
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
int extradata_size
Size of the extradata content in bytes.
static int cuvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
int width
picture width / height.
static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
AVBufferRef * hw_frames_ctx
Encoding only.
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
void av_frame_set_pkt_pos(AVFrame *frame, int64_t val)
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
#define AVERROR_BSF_NOT_FOUND
Bitstream filter not found.
static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINFO *dispinfo)
HW acceleration through CUDA.
the normal 2^n-1 "JPEG" YUV ranges
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given pixel format.
static int cuvid_test_dummy_decoder(AVCodecContext *avctx, CUVIDPARSERPARAMS *cuparseinfo)
Libavcodec external API header.
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
uint8_t * data
The data buffer.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
a very simple circular buffer FIFO implementation
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
This struct is allocated as AVHWDeviceContext.hwctx.
static const char * format
enum AVColorSpace colorspace
YUV colorspace type.
rational number numerator/denominator
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec)
Fill the parameters struct based on the values from the supplied codec context.
This struct describes a set or pool of "hardware" frames (i.e.
int(* func)(AVBPrint *dst, const char *in, const char *arg)
refcounted data buffer API
static enum AVPixelFormat pix_fmts[]
int64_t pkt_pts
PTS copied from the AVPacket that was decoded to produce this frame.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
the normal 219*2^(n-8) "MPEG" YUV ranges
A reference to a data buffer.
common internal api header.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
static int CUDAAPI cuvid_handle_picture_decode(void *opaque, CUVIDPICPARAMS *picparams)
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
int top_field_first
If the content is interlaced, is top field displayed first.
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
void av_fifo_freep(AVFifoBuffer **f)
Free an AVFifoBuffer and reset pointer to NULL.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
#define AVERROR_EXTERNAL
Generic error in an external library.
AVPixelFormat
Pixel format.
This structure stores compressed data.
AVCodecParameters * par_in
Parameters of the input stream.
#define AV_NOPTS_VALUE
Undefined timestamp value.