Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

NVENCMgr.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr
00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the
00004 *cr University of Illinois
00005 *cr All Rights Reserved
00006 *cr
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 * RCS INFORMATION:
00011 *
00012 * $RCSfile: OptiXDisplayDevice.h
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.5 $ $Date: 2019年01月17日 21:21:00 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 * VMD interface for NVIDIA GPU hardware video encoding APIs
00019 *
00020 * The implementation here could in principal use either high level
00021 * libraries like NvPipe or GRID, or lower level video encode APIs 
00022 * like NvEnc, depending on what hardware the target platform has and
00023 * whether we want to use codecs not supported by certain APIs.
00024 *
00025 * NvPipe: 
00026 * https://github.com/NVIDIA/NvPipe/blob/master/README.md
00027 *
00028 ***************************************************************************/
00029 
00030 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 
00035 #include "NVENCMgr.h"
00036 #include "Inform.h"
00037 #include "vmddlopen.h"
00038 
00039 #include "cuda.h"
00040 
00041 #define DBG() printf("NVENCMgr) %s\n", __func__);
00042 
00043 typedef NVENCSTATUS (NVENCAPI* PNVENCODEAPICREATEINSTANCE)(NV_ENCODE_API_FUNCTION_LIST *functionList);
00044 
00045 class nvencfctns {
00046 PNVENCODEAPICREATEINSTANCE nvEncodeAPICreateInstance;
00047 NV_ENCODE_API_FUNCTION_LIST fctns; 
00048 };
00049 
00050 
00051 NVENCMgr::NVENCMgr(void) {
00052 DBG();
00053 
00054 nvenc_lib = NULL;
00055 enc_ready = 0;
00056 inbuf_count = 0;
00057 memset(&nvenc_fctns, 0, sizeof(nvenc_fctns));
00058 
00059 memset(&session_parms, 0, sizeof(session_parms));
00060 session_parms.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
00061 session_parms.apiVersion = NVENCAPI_VERSION;
00062 
00063 memset(&preset_conf, 0, sizeof(preset_conf));
00064 preset_conf.version = NV_ENC_PRESET_CONFIG_VER;
00065 preset_conf.presetCfg.version = NV_ENC_CONFIG_VER;
00066 
00067 memset(&init_parms, 0, sizeof(init_parms));
00068 init_parms.version = NV_ENC_INITIALIZE_PARAMS_VER;
00069 
00070 memset(&conf, 0, sizeof(conf));
00071 conf.version = NV_ENC_CONFIG_VER;
00072 
00073 memset(&create_inbuf, 0, sizeof(create_inbuf));
00074 create_inbuf.version = NV_ENC_CREATE_INPUT_BUFFER_VER;
00075 
00076 memset(&create_outbuf, 0, sizeof(create_outbuf));
00077 create_outbuf.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER;
00078 
00079 memset(&enc_preset, 0, sizeof(enc_preset));
00080 }
00081 
00082 
00083 NVENCMgr::~NVENCMgr(void) {
00084 DBG();
00085 
00086 if (nvenc_lib)
00087 vmddlclose(nvenc_lib);
00088 }
00089 
00090 
00091 int NVENCMgr::init(void) {
00092 DBG();
00093 
00094 nvenc_lib = vmddlopen("libnvidia-encode.so.1");
00095 if (!nvenc_lib) {
00096 msgInfo << "NVENCMgr) Failed to open NVENC hardware video encoder library." 
00097 << sendmsg;
00098 vmddlclose(nvenc_lib);
00099 return -1;
00100 } 
00101 
00102 nvenc_fctns.version = NV_ENCODE_API_FUNCTION_LIST_VER;
00103 
00104 nvEncodeAPICreateInstance = (PNVENCODEAPICREATEINSTANCE) vmddlsym(nvenc_lib, "NvEncodeAPICreateInstance");
00105 if (!nvEncodeAPICreateInstance) {
00106 msgInfo << "NVENCMgr) Failed to load NVENC hardware video encoder instance fctn." 
00107 << sendmsg;
00108 vmddlclose(nvenc_lib);
00109 return -1;
00110 }
00111 
00112 NVENCSTATUS rc;
00113 rc = nvEncodeAPICreateInstance(&nvenc_fctns);
00114 if (rc != NV_ENC_SUCCESS) {
00115 msgInfo << "NVENCMgr) Failed to load NVENC hardware video encoder instance fctn table." 
00116 << sendmsg;
00117 }
00118 
00119 return 0;
00120 }
00121 
00122 
00123 int NVENCMgr::open_session(void) {
00124 DBG();
00125 
00126 CUcontext cuctx = NULL;
00127 CUresult curc;
00128 CUcontext cuctxcurrent = NULL;
00129 int cudevcount = 0;
00130 CUdevice cudev = 0;
00131 
00132 #if 0
00133 if ((curc = cuInit(0)) != CUDA_SUCCESS) {
00134 printf("NVENCMgr) failed to initialize CUDA driver API\n");
00135 return -1;
00136 }
00137 #endif
00138 
00139 if ((curc = cuDeviceGetCount(&cudevcount)) != CUDA_SUCCESS) {
00140 printf("NVENCMgr) failed to query CUDA driver API device count\n");
00141 return -1;
00142 }
00143 
00144 if (cudevcount < 1) {
00145 printf("NVENCMgr) no CUDA devices found for NVENC video encoding\n");
00146 return -1;
00147 } else {
00148 printf("NVENCMgr) CUDA dev count: %d\n", cudevcount);
00149 }
00150 
00151 if ((curc = cuDeviceGet(&cudev, 0)) != CUDA_SUCCESS) {
00152 printf("NVENCMgr) Unable to bind CUDA device 0\n");
00153 return -1;
00154 }
00155 
00156 if ((curc = cuCtxCreate(&cuctx, 0, cudev)) != CUDA_SUCCESS) {
00157 printf("NVENCMgr) Unable create CUDA ctx\n");
00158 return -1;
00159 }
00160 
00161 if ((curc = cuCtxPopCurrent(&cuctxcurrent)) != CUDA_SUCCESS) {
00162 printf("NVENCMgr) Unable pop current CUDA ctx\n");
00163 return -1;
00164 }
00165 // curc = cuCtxGetCurrent(&cuctx);
00166 
00167 
00168 session_parms.device = cuctx;
00169 session_parms.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
00170 // XXX client keys are not presently required
00171 // session_parms.clientKeyPtr = &NV_CLIENT_KEY;
00172 
00173 // printf("NVENCMgr) Creating NVENC hardware encoder session...\n");
00174 
00175 NVENCSTATUS encstat;
00176 encstat = nvenc_fctns.nvEncOpenEncodeSessionEx(&session_parms, &nvenc_ctx);
00177 if (encstat != NV_ENC_SUCCESS) {
00178 printf("NVENCMgr) nvEncOpenEncodeSessionEx() returned an error!\n");
00179 return -1;
00180 }
00181 
00182 // setup encoder presets
00183 enc_preset = NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID;
00184 // enc_preset = NV_ENC_PRESET_LOW_LATENCY_HP_GUID;
00185 // enc_preset = NV_ENC_PRESET_LOW_LATENCY_HQ_GUID;
00186 // enc_preset = NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID;
00187 // enc_preset = NV_ENC_PRESET_LOSSLESS_HP_GUID;
00188 // enc_preset = NV_ENC_PRESET_HQ_GUID;
00189 // enc_preset = NV_ENC_PRESET_DEFAULT_GUID;
00190 
00191 #if 1
00192 codec = NV_ENC_CODEC_H264_GUID;
00193 #else
00194 codec = NV_ENC_CODEC_HEVC_GUID;
00195 #endif
00196 
00197 printf("NVENCMgr) establishing NVENC hardware encoder preset config\n");
00198 encstat = nvenc_fctns.nvEncGetEncodePresetConfig(nvenc_ctx, codec, 
00199 enc_preset, &preset_conf);
00200 if (encstat != NV_ENC_SUCCESS) {
00201 printf("NVENCMgr) nvEncGetEncodePresetConfig() returned an error!\n");
00202 return -1;
00203 }
00204 
00205 init_parms.version = NV_ENC_INITIALIZE_PARAMS_VER;
00206 init_parms.encodeWidth = 1920;
00207 init_parms.encodeHeight = 1080;
00208 init_parms.darWidth = 1920;
00209 init_parms.darHeight = 1080;
00210 init_parms.maxEncodeWidth = 1920;
00211 init_parms.maxEncodeHeight = 1080;
00212 init_parms.frameRateNum = 1;
00213 init_parms.frameRateDen = 30;
00214 init_parms.enableEncodeAsync = 0;
00215 init_parms.enablePTD = 1;
00216 
00217 init_parms.encodeGUID = codec;
00218 init_parms.presetGUID = enc_preset;
00219 init_parms.encodeConfig = &preset_conf.presetCfg;
00220 
00221 // printf("NVENCMgr) Initializing NVENC hardware encoder ...\n");
00222 encstat = nvenc_fctns.nvEncInitializeEncoder(nvenc_ctx, &init_parms);
00223 if (encstat != NV_ENC_SUCCESS) {
00224 printf("NVENCMgr) nvEncInitializeEncoder() returned an error!\n");
00225 return -1;
00226 }
00227 
00228 #if 0
00229 // setting refs to zero allows hardware encoder to decide
00230 conf.encodeCodecConfig.h264Config.maxNumRefFrames = 0;
00231 conf.encodeCodecConfig.hevcConfig.maxNumRefFramesInDPB = 0;
00232 
00233 // infinite GOP == 0, I-only == 1?
00234 conf.gopLength = 30;
00235 if (conf.gopLength > 0) {
00236 conf.frameIntervalP = 3; // 0=I only, 1=IP, 2=IBP, 3=IBBP, ...
00237 } else {
00238 conf.frameIntervalP = 0; // 0=I only, 1=IP, 2=IBP, 3=IBBP, ...
00239 conf.gopLength = 1;
00240 }
00241 
00242 conf.encodeCodecConfig.h264Config.idrPeriod = conf.gopLength;
00243 // H.264 only
00244 conf.encodeCodecConfig.h264Config.hierarchicalPFrames = 1;
00245 conf.encodeCodecConfig.h264Config.hierarchicalBFrames = 1;
00246 
00247 conf.rcParams.averageBitRate = 15000000; // 15Mbps
00248 conf.rcParams.maxBitRate = 20000000; // 20Mbps
00249 #endif
00250 
00251 // flag encoder as ready
00252 enc_ready = 1;
00253 printf("NVENCMgr) NVENC hardware encoder ready.\n");
00254 
00255 return 0;
00256 }
00257 
00258 
00259 int NVENCMgr::create_inbufs(int bufcount) {
00260 DBG();
00261 NVENCSTATUS encstat;
00262 
00263 if (!enc_ready) {
00264 printf("NVENCMgr) Error creating input buffers, encoder not ready!\n");
00265 return -1;
00266 }
00267 
00268 // must be multiples of 32
00269 create_inbuf.width = 1920;
00270 create_inbuf.height= 1080;
00271 create_inbuf.memoryHeap = NV_ENC_MEMORY_HEAP_SYSMEM_CACHED;
00272 create_inbuf.bufferFmt = NV_ENC_BUFFER_FORMAT_NV12_PL;
00273 
00274 inbuf_count = bufcount;
00275 int i;
00276 for (i=0; i<inbuf_count; i++) {
00277 encstat = nvenc_fctns.nvEncCreateInputBuffer(nvenc_ctx, &create_inbuf); 
00278 if (encstat != NV_ENC_SUCCESS) {
00279 printf("NVENCMgr) Failed to create input buffers!\n");
00280 return -1;
00281 }
00282 } 
00283 
00284 return 0;
00285 }
00286 

Generated on Wed Nov 19 02:46:38 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /