NVENC編碼

NVENC編碼流程

  1. 加載NVENCODE API
  2. 打開編碼會話
  3. 初始化編碼器
  4. 注冊輸入資源
  5. 映射注冊的輸入資源
  6. 創(chuàng)建輸出比特流緩沖
  7. 編碼一幀(同步方式)
  8. 獲取輸出(同步方式)

加載API

將NVENC lib中的接口導(dǎo)出邦蜜,供后續(xù)編碼流程使用帜乞。

NV_ENCODE_API_FUNCTION_LIST m_funList = { NV_ENCODE_API_FUNCTION_LIST_VER };
NVENC_API_CALL(NvEncodeAPICreateInstance(&m_funList));

打開編碼會話

編碼會話需要傳入D3D設(shè)備,在此之前需要創(chuàng)建好D3D設(shè)備。接口輸出的void* m_encoder;將會用于后續(xù)編碼接口的第一個參數(shù)中缚俏。

NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS encodeSessionExParams = { 0 };
encodeSessionExParams.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
encodeSessionExParams.device = (void*)m_device;
encodeSessionExParams.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX;
encodeSessionExParams.apiVersion = NVENCAPI_VERSION;
void* m_encoder;
NVENC_API_CALL(m_funList.nvEncOpenEncodeSessionEx(&encodeSessionExParams, &m_encoder));

初始化編碼器

可以使用nvEncInitializeEncoder傳入NV_ENC_INITIALIZE_PARAMS類型的實例,對編碼器進行初始化菱父。其中encodeGUID挣饥、encodeWidthencodeHeight三項是必填選項地回,encodeGUID表示使用H264編碼(NV_ENC_CODEC_H264_GUID)還是H265(NV_ENC_CODEC_HEVC_GUID)編碼扁远。另外,還可以在此設(shè)置使用同步編碼還是異步編碼模式刻像。
nvEncGetEncodePresetConfig可以獲取預(yù)置參數(shù)NV_ENC_PRESET_CONFIG畅买。可以設(shè)置碼率控制模式细睡、平均碼率等數(shù)據(jù)谷羞。

NV_ENC_PRESET_CONFIG presetConfig = { NV_ENC_PRESET_CONFIG_VER, { NV_ENC_CONFIG_VER } };
m_funList.nvEncGetEncodePresetConfig(m_encoder, NV_ENC_CODEC_H264_GUID, NV_ENC_PRESET_P3_GUID, &presetConfig);
NV_ENC_CONFIG config = { NV_ENC_CONFIG_VER };
memcpy(&config, &presetConfig.presetCfg, sizeof(config));
config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CBR;
config.rcParams.averageBitRate = 25000;
config.gopLength = 10;

NV_ENC_INITIALIZE_PARAMS encoder_init_params = { NV_ENC_INITIALIZE_PARAMS_VER };
encoder_init_params.encodeConfig = &config;
encoder_init_params.encodeGUID = NV_ENC_CODEC_H264_GUID;
encoder_init_params.presetGUID = NV_ENC_PRESET_P3_GUID;
encoder_init_params.tuningInfo = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY;
encoder_init_params.encodeWidth = m_encodeWidth;
encoder_init_params.encodeHeight = m_encodeHeight;
encoder_init_params.darWidth = m_encodeWidth;
encoder_init_params.darHeight = m_encodeHeight;
encoder_init_params.frameRateNum = m_frameRate;  // 幀率
encoder_init_params.frameRateDen = 1;
encoder_init_params.enablePTD = 1;
encoder_init_params.maxEncodeWidth = m_encodeWidth;
encoder_init_params.maxEncodeHeight = m_encodeHeight;
encoder_init_params.enableEncodeAsync = 0;  // 同步模式

NVENC_API_CALL(m_funList.nvEncInitializeEncoder(m_encoder, &encoder_init_params));

注冊輸入資源

將輸入的紋理指針注冊成輸入資源,即m_registerResource.resourceToRegister = m_inputTexture;

NV_ENC_REGISTER_RESOURCE m_registerResource;
m_registerResource.version = NV_ENC_REGISTER_RESOURCE_VER;
m_registerResource.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX;
m_registerResource.resourceToRegister = m_inputTexture;
m_registerResource.width = m_encodeWidth;
m_registerResource.height = m_encodeHeight;
m_registerResource.pitch = 0;
m_registerResource.bufferFormat = NV_ENC_BUFFER_FORMAT_NV12;
m_registerResource.bufferUsage = NV_ENC_INPUT_IMAGE;
m_registerResource.pInputFencePoint = NULL;
m_registerResource.pOutputFencePoint = NULL;
NVENC_API_CALL(m_funList.nvEncRegisterResource(m_encoder, &m_registerResource));

映射注冊的輸入資源

將注冊的輸入資源映射到編碼器溜徙。m_inputMapResource.registeredResource = m_registerResource.registeredResource;

NV_ENC_MAP_INPUT_RESOURCE m_inputMapResource;
m_inputMapResource.version = NV_ENC_MAP_INPUT_RESOURCE_VER;
m_inputMapResource.registeredResource = m_registerResource.registeredResource;
NVENC_API_CALL(m_funList.nvEncMapInputResource(m_encoder, &m_inputMapResource));

創(chuàng)建輸出比特流緩沖

創(chuàng)建接收編碼出的比特流緩沖洒宝。

NV_ENC_CREATE_BITSTREAM_BUFFER m_outputBuffer;
m_outputBuffer.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER;
NVENC_API_CALL(m_funList.nvEncCreateBitstreamBuffer(m_encoder, &m_outputBuffer));

編碼一幀

在編碼前需要更新輸入紋理數(shù)據(jù),即前面已經(jīng)注冊的紋理指針m_inputTexture萌京,更新后雁歌,填充NV_ENC_PIC_PARAMS結(jié)構(gòu),將NV_ENC_PIC_PARAMS.inputBuffer賦值為前面映射的資源知残,即m_inputMapResource.mappedResource靠瞎,再將NV_ENC_PIC_PARAMS.outputBitstream賦值為前面創(chuàng)建的輸出比特流緩沖,即m_outputBuffer.bitstreamBuffer,然后調(diào)用nvEncEncodePicture對數(shù)據(jù)進行編碼乏盐。

NV_ENC_PIC_PARAMS picParams = { 0 };
picParams.version = NV_ENC_PIC_PARAMS_VER;
picParams.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
picParams.inputBuffer = m_inputMapResource.mappedResource;
picParams.bufferFmt = NV_ENC_BUFFER_FORMAT_NV12;
picParams.inputWidth = m_encodeWidth;
picParams.inputHeight = m_encodeHeight;
picParams.outputBitstream = m_outputBuffer.bitstreamBuffer;
picParams.inputTimeStamp = 0;
NVENC_API_CALL(m_funList.nvEncEncodePicture(m_encoder, &picParams));

獲取輸出

使用nvEncLockBitstream將數(shù)據(jù)從編碼器中取出佳窑,即GPU到CPU。

NV_ENC_LOCK_BITSTREAM lockBitstreamData = { NV_ENC_LOCK_BITSTREAM_VER };
lockBitstreamData.outputBitstream = m_outputBuffer.bitstreamBuffer;
lockBitstreamData.doNotWait = 0;
NVENC_API_CALL(m_funList.nvEncLockBitstream(m_encoder, &lockBitstreamData));

unsigned char* outData = NULL;
int dataSize = lockBitstreamData.bitstreamSizeInBytes;
outData = new unsigned char[dataSize];
memcpy(outData, lockBitstreamData.bitstreamBufferPtr, dataSize);

NVENC_API_CALL(m_funList.nvEncUnlockBitstream(m_encoder, lockBitstreamData.outputBitstream));   
``



?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末父能,一起剝皮案震驚了整個濱河市神凑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌何吝,老刑警劉巖溉委,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異爱榕,居然都是意外死亡瓣喊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門黔酥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來藻三,“玉大人,你說我怎么就攤上這事跪者】妹保” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵渣玲,是天一觀的道長岖寞。 經(jīng)常有香客問我,道長柜蜈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任指巡,我火速辦了婚禮淑履,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘藻雪。我一直安慰自己秘噪,他們只是感情好,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布勉耀。 她就那樣靜靜地躺著指煎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪便斥。 梳的紋絲不亂的頭發(fā)上至壤,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天,我揣著相機與錄音枢纠,去河邊找鬼像街。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的镰绎。 我是一名探鬼主播脓斩,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼畴栖!你這毒婦竟也來了随静?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤吗讶,失蹤者是張志新(化名)和其女友劉穎燎猛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體关翎,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡扛门,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了纵寝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片论寨。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖爽茴,靈堂內(nèi)的尸體忽然破棺而出葬凳,到底是詐尸還是另有隱情,我是刑警寧澤室奏,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布火焰,位于F島的核電站,受9級特大地震影響胧沫,放射性物質(zhì)發(fā)生泄漏昌简。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一绒怨、第九天 我趴在偏房一處隱蔽的房頂上張望纯赎。 院中可真熱鬧,春花似錦南蹂、人聲如沸犬金。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晚顷。三九已至,卻和暖如春疗疟,著一層夾襖步出監(jiān)牢的瞬間该默,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工策彤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留权均,地道東北人顿膨。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像叽赊,于是被迫代替她去往敵國和親恋沃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容