ffmpeg代码分析--h264的GPU加速

硬件选择

-hwaccel_device 0

{ "hwaccel_device",   OPT_VIDEO | OPT_STRING | HAS_ARG |OPT_EXPERT |

                          OPT_SPEC |OPT_INPUT,                                 { .off = OFFSET(hwaccel_devices) },

       "select a device for HW acceleration", "devicename"}

libavutil/hwcontex_cuda.c

cuda_device_create

可以看到使用的CUDA的函数,如cuda_device_init,cuDeviceGet等。

static intcuda_device_create(AVHWDeviceContext *ctx, const char *device,

                              AVDictionary*opts, int flags)

{

   AVCUDADeviceContext *hwctx = ctx->hwctx;

    CudaFunctions*cu;

   CUdevice cu_device;

   CUcontext dummy;

   CUresult err;

   int device_idx = 0;

   if (device)

       device_idx = strtol(device, NULL, 0);

   if (cuda_device_init(ctx) < 0)

       goto error;

   cu = hwctx->internal->cuda_dl;

   err = cu->cuInit(0);

   if (err != CUDA_SUCCESS) {

       av_log(ctx, AV_LOG_ERROR, "Could not initialize the CUDA driverAPI\n");

       goto error;

    }

    err = cu->cuDeviceGet(&cu_device, device_idx);

    if(err != CUDA_SUCCESS) {

       av_log(ctx, AV_LOG_ERROR, "Could not get the device number%d\n", device_idx);

       goto error;

    }

    err = cu->cuCtxCreate(&hwctx->cuda_ctx,CU_CTX_SCHED_BLOCKING_SYNC, cu_device);

   if (err != CUDA_SUCCESS) {

        av_log(ctx, AV_LOG_ERROR, "Errorcreating a CUDA context\n");

       goto error;

    }

    cu->cuCtxPopCurrent(&dummy);

   hwctx->internal->is_allocated = 1;

   return 0;

 error:

   cuda_device_uninit(ctx);

   return AVERROR_UNKNOWN;

}

加速解码

-hwaccel cuvid  -c:v h264_cuvid

    {"hwaccel",          OPT_VIDEO |OPT_STRING | HAS_ARG | OPT_EXPERT |

                          OPT_SPEC |OPT_INPUT,                                  { .off = OFFSET(hwaccels) },

       "use HW accelerated decoding", "hwaccel name" },

const HWAccel hwaccels[] = {

 ...

#if CONFIG_CUVID

    {"cuvid", cuvid_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA,

     AV_HWDEVICE_TYPE_NONE },

#endif

    {0 },

};

 

加速编码

-c:v  h264_nvenc

libavcodec/nvenc_h264.c

AVCodec ff_h264_nvenc_encoder = {

   .name           ="h264_nvenc",

   .long_name      =NULL_IF_CONFIG_SMALL("NVIDIA NVENC H.264 encoder"),

   .type           =AVMEDIA_TYPE_VIDEO,

   .id             =AV_CODEC_ID_H264,

   .init           =ff_nvenc_encode_init,

   .send_frame     =ff_nvenc_send_frame,

   .receive_packet = ff_nvenc_receive_packet,

   .encode2        = ff_nvenc_encode_frame,

   .close          =ff_nvenc_encode_close,

   .priv_data_size = sizeof(NvencContext),

   .priv_class     =&h264_nvenc_class,

   .defaults       = defaults,

   .capabilities   =AV_CODEC_CAP_DELAY,

   .caps_internal  =FF_CODEC_CAP_INIT_CLEANUP,

   .pix_fmts       =ff_nvenc_pix_fmts,

};

libavcodec/nvenc.c

例:ff_nvenc_encode_frame

可以看到库函数nvEncEncodePicture。

你可能感兴趣的:(ffmpeg--h264)