下面是nvcodec解码案例,可以参考:
#include "nvcuvid.h"
#include <cuda_runtime.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "utils/demuxer.h"
#define START_CODE_ANNEXB 0x00000001
#define START_CODE_SIZE 4
typedef struct packet_t {
uint8_t* data;
int size;
int64_t pts;
} packet;
typedef struct nvcuvid_test_ctx_t {
CUvideodecoder cudecoder;
CUvideoparser cuparser;
CUVIDPARSERPARAMS cuparseinfo;
CUVIDDECODECAPS caps8;
CUVIDDECODECAPS caps10;
CUVIDDECODECAPS caps12;
CUcontext cu_ctx;
CUvideoctxlock cu_ctx_lock;
FFmpegDemuxer* demuxer;
uint64_t frame_count;
const char* in_file_name;
void* host_data;
void* tmp_data;
int tmp_data_size;
int coded_width;
int coded_height;
int out_width;
int out_height;
cudaVideoCodec codec_type;
int bit_depth_minus8; // 0-8bit, 2-10bit, 4-12bit
int decode_surface;
unsigned char progressive_sequence;
unsigned int bit_rate;
cudaVideoSurfaceFormat out_pix_fmt;
cudaVideoChromaFormat in_pix_fmt;
cudaVideoDeinterlaceMode deinter_lace_mode;
struct {
int left;
int top;
int right;
int bottom;
} crop;
struct {
int width;
int height;
} resize;
struct {
unsigned int num;
unsigned int den;
} framerate;
int eos;
int nb_surfaces;
int internal_error;
int need_resize;
int decoder_flushing;
int in_file_size;
int read_size;
FILE* in_file;
FILE* out_file;
} nvcuvid_test_ctx;
static void print_caps(CUVIDDECODECAPS* caps) {
printf("eCodecType: %d\n", caps->eCodecType);
printf("eChromaFormat: %d\n", caps->eChromaFormat);
printf("nBitDepthMinus8: %d\n", caps->nBitDepthMinus8);
printf("bIsSupported: %d\n", caps->bIsSupported);
printf("nNumNVDECs: %d\n", caps->nNumNVDECs);
printf("nMaxWidth: %d\n", caps->nMaxWidth);
printf("nMaxHeight: %d\n", caps->nMaxHeight);
printf("nMaxMBCount: %d\n", caps->nMaxMBCount);
printf("nMinWidth: %d\n", caps->nMinWidth);
printf("nMinHeight: %d\n", caps->nMinHeight);
printf("nMaxMBCount: %d\n", caps->nMaxMBCount);
}
static int handle_video_sequence(void* opaque, CUVIDEOFORMAT* format) {
nvcuvid_test_ctx* ctx = NULL;
CUVIDDECODECAPS* caps = NULL;
CUVIDDECODECREATEINFO cuinfo = {
0};
CUVIDRECONFIGUREDECODERINFO cf = {
0};
ctx = (nvcuvid_test_ctx*)opaque;
ctx->internal_error = 0;
// getcaps
caps = &ctx->caps8;
caps->eCodecType = format->codec;
caps->eChromaFormat = format->chroma_format;
caps->nBitDepthMinus8 =
format->bit_depth_luma_minus8; // 0-8bit, 2-10bit, 4-12bit
// cuCtxPushCurrent(ctx->cu_ctx);
ctx->internal_error = cuvidGetDecoderCaps(caps);
if (ctx->internal_error != 0) {
printf("cuvidGetDecoderCaps failed,ret=%d\n", ctx->internal_error);
goto err;
}
// cuCtxPopCurrent(NULL);
print_caps(caps);
if (!caps->bIsSupported) {
printf("Codec not supported on this GPU\n");
goto err;
}
// check if need to reinit decoder
ctx->bit_rate = format->bitrate;
ctx->codec_type = format->codec;
ctx->coded_width = format->coded_width;
ctx->coded_height = format->coded_height;
ctx->in_pix_fmt = format->chroma_format;
ctx->framerate.num = format->frame_rate.numerator;
ctx->framerate.den = format->frame_rate.denominator;
ctx->bit_depth_minus8 = format->bit_depth_luma_minus8;
ctx->progressive_sequence = format->progressive_sequence;
ctx->decode_surface = format->min_num_decode_surfaces;
printf(
"bitrate:%d,codec:%d,coded_width:%d,coded_height:%d,chroma_format:%d,"
"frame_rate:%d/%d,bit_depth_luma_minus8:%d,progressive_sequence:%d,"
"min_num_decode_surfaces:%d\n",
ctx->bit_rate, ctx->codec_type, ctx->coded_width, ctx->coded_height,
ctx->in_pix_fmt, ctx->framerate.num, ctx->framerate.den,
ctx->bit_depth_minus8, ctx->progressive_sequence, ctx->decode_surface);
// do some checks
// a.check max resolution supported
// b.check max mb count supported
// if the decoder is already created, reconfigure it
if (ctx->cudecoder) {
printf("Re-initializing decoder\n");
cf.ulWidth = ctx->coded_width;
cf.ulHeight = ctx->coded_height;
cf.ulTargetWidth = ctx->out_width;
cf.ulTargetHeight = ctx->out_height;
cf.display_area.left = format->display_area.left + ctx->crop.left;
cf.display_area.top = format->display_area.top + ctx->crop.top;
cf.display_area.right = format->display_area.right - ctx->crop.right;
cf.display_area.bottom = format->display_area.bottom - ctx->crop.bottom;
cf.ulNumDecodeSurfaces = ctx->decode_surface;
// reconfigure decoder
ctx->internal_error = cuvidReconfigureDecoder(ctx->cudecoder, &cf);
if (ctx->internal_error != 0) {
printf("cuvidReconfigureDecoder failed\n");
goto err;
}
printf("Re-initialized decoder\n");
}
// for the first time, create decoder
memset(&cuinfo, 0, sizeof(CUVIDDECODECREATEINFO));
cuinfo.CodecType = (cudaVideoCodec)ctx->codec_type;
cuinfo.ChromaFormat = ctx->in_pix_fmt;
cuinfo.OutputFormat = ctx->out_pix_fmt;
cuinfo.bitDepthMinus8 = ctx->bit_depth_minus8;
if (ctx->progressive_sequence)
cuinfo.DeinterlaceMode = cudaVideoDeinterlaceMode_Weave;
else
cuinfo.DeinterlaceMode = cudaVideoDeinterlaceMode_Adaptive;
cuinfo.ulNumOutputSurfaces = 2;
cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
cuinfo.ulNumDecodeSurfaces = ctx->decode_surface;
// cuinfo.vidLock = ctx->cu_ctx_lock;
cuinfo.ulWidth = ctx->coded_width;
cuinfo.ulHeight = ctx->coded_height;
printf(
"codec:%d,chroma_format:%d,width:%d,height:%d,output_format:%d,"
"num_decode_surfaces:%d,num_output_surfaces:%d,creation_flags:%d,"
"vidLock:%p,bitDepthMinus8:%d\n",
cuinfo.CodecType, cuinfo.ChromaFormat, cuinfo.ulWidth, cuinfo.ulHeight,
cuinfo.OutputFormat, cuinfo.ulNumDecodeSurfaces,
cuinfo.ulNumOutputSurfaces, cuinfo.ulCreationFlags, cuinfo.vidLock,
cuinfo.bitDepthMinus8);
printf("createdecoder,ulNumDecodeSurfaces:%d\n",
cuinfo.ulNumDecodeSurfaces);
// apply cropping
// cuinfo.display_area.left = format->display_area.left + ctx->crop.left;
// cuinfo.display_area.top = format->display_area.top + ctx->crop.top;
// cuinfo.display_area.right = format->display_area.right -
// ctx->crop.right; cuinfo.display_area.bottom = format->display_area.bottom
// - ctx->crop.bottom;
// printf("display_area:left:%d,top:%d,right:%d,bottom:%d\n",
// cuinfo.display_area.left, cuinfo.display_area.top,
// cuinfo.display_area.right, cuinfo.display_area.bottom);
ctx->out_width = ctx->coded_width; // cuinfo.display_area.right -
// cuinfo.display_area.left;
ctx->out_height = ctx->coded_height; // cuinfo.display_area.bottom -
// cuinfo.display_area.hecoded_height
printf("out_width:%d,out_height:%d\n", ctx->out_width, ctx->out_height);
// target width/height need to be multiples of two align to 2
cuinfo.ulTargetWidth = ctx->out_width;
cuinfo.ulTargetHeight = ctx->out_height;
// // aspect ratio conversion, 1:1, depends on scaled resolution
// cuinfo.target_rect.left = 0;
// cuinfo.target_rect.top = 0;
// cuinfo.target_rect.right = cuinfo.ulTargetWidth;
// cuinfo.target_rect.bottom = cuinfo.ulTargetHeight;
// printf("target_rect:left:%d,top:%d,right:%d,bottom:%d\n",
// cuinfo.target_rect.left, cuinfo.target_rect.top,
// cuinfo.target_rect.right, cuinfo.target_rect.bottom);
// max resolution
cuinfo.ulMaxWidth = cuinfo.ulTargetWidth;
cuinfo.ulMaxHeight = cuinfo.ulTargetHeight;
printf("max resolution:width:%d,height:%d\n", cuinfo.ulMaxWidth,
cuinfo.ulMaxHeight);
// cuCtxPushCurrent(ctx->cu_ctx);
ctx->internal_error = cuvidCreateDecoder(&ctx->cudecoder, &cuinfo);
if (ctx->internal_error < 0) {
printf("cuvidCreateDecoder failed\n");
goto err;
}
// cuCtxPopCurrent(NULL);
printf("cuvidCreateDecoder success, ret:%d\n", ctx->internal_error);
err:
return (0 == ctx->internal_error);
}
static int handle_picture_display(void* opaque, CUVIDPARSERDISPINFO* dispinfo) {
int ret = 0;
int bpp = 1;
void* dst_frame = NULL;
int dst_size = 0;
nvcuvid_test_ctx* ctx = NULL;
CUVIDGETDECODESTATUS s;
printf("<<<handle_picture_display\n");
ctx = (nvcuvid_test_ctx*)opaque;
ctx->internal_error = 0;
if (ctx->bit_depth_minus8 > 0) {
bpp = 2;
}
if (!dispinfo) {
printf("dispinfo is null\n");
return 0;
}
CUVIDPROCPARAMS map_info = {
0};
map_info.progressive_frame = dispinfo->progressive_frame;
map_info.second_field = dispinfo->repeat_first_field + 1;
map_info.top_field_first = dispinfo->top_field_first;
map_info.unpaired_field = dispinfo->repeat_first_field < 0;
map_info.output_stream = NULL;
CUdeviceptr map_frame = 0;
unsigned int map_pitch = 0; // for 8 bit pitch=1, for 10/12 bit pitch=2
ret = cuvidMapVideoFrame(ctx->cudecoder, dispinfo->picture_index,
&map_frame, &map_pitch

最低0.47元/天 解锁文章
8542

被折叠的 条评论
为什么被折叠?



