static int nvenc_check_codec_support(AVCodecContext *avctx) { NVENCContext *ctx = avctx->priv_data; NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs; int i, ret, count = 0; GUID *guids = NULL; ret = nv->nvEncGetEncodeGUIDCount(ctx->nvenc_ctx, &count); if (ret != NV_ENC_SUCCESS || !count) return AVERROR(ENOSYS); guids = av_malloc(count * sizeof(GUID)); if (!guids) return AVERROR(ENOMEM); ret = nv->nvEncGetEncodeGUIDs(ctx->nvenc_ctx, guids, count, &count); if (ret != NV_ENC_SUCCESS) { ret = AVERROR(ENOSYS); goto fail; } ret = AVERROR(ENOSYS); for (i = 0; i < count; i++) { if (!memcmp(&guids[i], &ctx->params.encodeGUID, sizeof(*guids))) { ret = 0; break; } } fail: av_free(guids); return ret; }
fcH264EncoderNVIDIA::fcH264EncoderNVIDIA(const fcH264EncoderConfig& conf, void *device, fcHWEncoderDeviceType type) : m_conf(conf) { if (!LoadNVENCModule()) { return; } NVENCSTATUS stat; { NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params; memset(¶ms, 0, sizeof(params)); params.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER; params.apiVersion = NVENCAPI_VERSION; params.device = device; switch (type) { case fcHWEncoderDeviceType::D3D9: case fcHWEncoderDeviceType::D3D10: case fcHWEncoderDeviceType::D3D11: case fcHWEncoderDeviceType::D3D12: params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX; break; case fcHWEncoderDeviceType::CUDA: params.deviceType = NV_ENC_DEVICE_TYPE_CUDA; break; } stat = nvenc.nvEncOpenEncodeSessionEx(¶ms, &m_encoder); if (!m_encoder) { return; } } std::vector<GUID> encode_guilds; std::vector<GUID> profile_guilds; std::vector<GUID> preset_guilds; { uint32_t num_encode_guilds = 0; uint32_t num_profile_guilds = 0; uint32_t num_preset_guilds = 0; nvenc.nvEncGetEncodeGUIDCount(m_encoder, &num_encode_guilds); encode_guilds.resize(num_encode_guilds); nvenc.nvEncGetEncodeGUIDs(m_encoder, encode_guilds.data(), num_encode_guilds, &num_encode_guilds); nvenc.nvEncGetEncodeProfileGUIDCount(m_encoder, NV_ENC_CODEC_H264_GUID, &num_profile_guilds); profile_guilds.resize(num_profile_guilds); nvenc.nvEncGetEncodeProfileGUIDs(m_encoder, NV_ENC_CODEC_H264_GUID, profile_guilds.data(), num_profile_guilds, &num_profile_guilds); nvenc.nvEncGetEncodePresetCount(m_encoder, NV_ENC_CODEC_H264_GUID, &num_preset_guilds); preset_guilds.resize(num_preset_guilds); nvenc.nvEncGetEncodePresetGUIDs(m_encoder, NV_ENC_CODEC_H264_GUID, preset_guilds.data(), num_preset_guilds, &num_preset_guilds); } { NV_ENC_INITIALIZE_PARAMS params = { 0 }; params.version = NV_ENC_INITIALIZE_PARAMS_VER; params.encodeGUID = NV_ENC_CODEC_H264_GUID; params.presetGUID = NV_ENC_PRESET_DEFAULT_GUID; params.encodeWidth = conf.width; params.encodeHeight = conf.height; params.darWidth = conf.width; params.darHeight = conf.height; params.frameRateNum = m_conf.target_framerate; params.frameRateDen = 1; params.enablePTD = 1; NV_ENC_PRESET_CONFIG preset_config = { 0 }; preset_config.version = NV_ENC_PRESET_CONFIG_VER; preset_config.presetCfg.version = NV_ENC_CONFIG_VER; stat = nvenc.nvEncGetEncodePresetConfig(m_encoder, params.encodeGUID, params.presetGUID, &preset_config); NV_ENC_CONFIG encode_config = { 0 }; encode_config.version = NV_ENC_CONFIG_VER; memcpy(&encode_config, &preset_config.presetCfg, sizeof(NV_ENC_CONFIG)); encode_config.profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID; params.encodeConfig = &encode_config; stat = nvenc.nvEncInitializeEncoder(m_encoder, ¶ms); } { memset(&m_input, 0, sizeof(m_input)); m_input.version = NV_ENC_CREATE_INPUT_BUFFER_VER; m_input.width = m_conf.width; m_input.height = m_conf.height; m_input.bufferFmt = NV_ENC_BUFFER_FORMAT_NV12; stat = nvenc.nvEncCreateInputBuffer(m_encoder, &m_input); } { memset(&m_output, 0, sizeof(m_output)); m_output.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER; m_output.size = roundup<16>(conf.width) * roundup<16>(conf.height) * 2; stat = nvenc.nvEncCreateBitstreamBuffer(m_encoder, &m_output); } }