c++ - NVENC Nvidia Encoder D3D11 Wrong image dimension and other questions -


first few basic information:

os: win7 64bit | gpu: gtx970

i have staging id3d11texture2d wich encode.

i use texture directly via nvencregisterresource seems pass d3d9 , no d3d11 texture. otherwise nv_enc_err_unimplemented.

thefore, create input buffer , fill manually.

the texture in format dxgi_format_r8g8b8a8_unorm. format dxgi_format_nv12 possibly windows 8 onwards.

the input buffer format nv_enc_buffer_format_argb. should 8 bits per color channel. since alpha value interchanged expect wrong picture should still encoded.

my process far:

  • create id3d11texture2d render texture
  • create id3d11texture2d staging texture
  • create nvenc input buffer nvenccreateinputbuffer
  • create nvenc output buffer nvenccreatebitstreambuffer

:: update routine ::

  • render render texture
  • copyresource() staging texture
  • fill nvenc input buffer staging texture
  • encode frame
  • get data nvenc output buffer

as can see, encode 1 frame per update.

so far works without error, if @ frame picture size wrong.

enter image description here

that should 1280 x 720. if try pass more 1 frame broken file.

i understand in h.264 first frame i-frame , following should p-frame.

now code:

:: create input buffer

nvencstatus rendermanager::createinputbuffer() {     nvencstatus nvstatus = nv_enc_success;      nv_enc_create_input_buffer createinputbufferparams = {};     createinputbufferparams.version = nv_enc_create_input_buffer_ver;     createinputbufferparams.width = m_width;     createinputbufferparams.height = m_height;     createinputbufferparams.memoryheap = nv_enc_memory_heap_sysmem_cached;     createinputbufferparams.bufferfmt = nv_enc_buffer_format_argb;      nvstatus = m_pencodeapi->nvenccreateinputbuffer(m_pencoder, &createinputbufferparams);     if (nvstatus != nv_enc_success) return nvstatus;      m_pencoderinputbuffer = createinputbufferparams.inputbuffer;      return nvstatus; } 

:: create output buffer

nvencstatus rendermanager::createoutputbuffer() {     nvencstatus nvstatus = nv_enc_success;      nv_enc_create_bitstream_buffer createbitstreambufferparams = {};     createbitstreambufferparams.version = nv_enc_create_bitstream_buffer_ver;     createbitstreambufferparams.size = 2 * 1024 * 1024;     createbitstreambufferparams.memoryheap = nv_enc_memory_heap_sysmem_cached;      nvstatus = m_pencodeapi->nvenccreatebitstreambuffer(m_pencoder, &createbitstreambufferparams);     if (nvstatus != nv_enc_success) return nvstatus;      m_pencoderoutputbuffer = createbitstreambufferparams.bitstreambuffer;      return nvstatus; } 

:: fill input buffer

nvencstatus rendermanager::writeinputbuffer(id3d11texture2d* ptexture) {     nvencstatus nvstatus = nv_enc_success;     hresult result = s_ok;      // data staging texture     d3d11_mapped_subresource mappedresource;     result = m_pcontext->map(ptexture, 0, d3d11_map_read, 0, &mappedresource);     if (failed(result)) return nv_enc_err_generic;      m_pcontext->unmap(ptexture, 0);      // lock input buffer     nv_enc_lock_input_buffer lockinputbufferparams = {};     lockinputbufferparams.version = nv_enc_lock_input_buffer_ver;     lockinputbufferparams.inputbuffer = m_pencoderinputbuffer;      nvstatus = m_pencodeapi->nvenclockinputbuffer(m_pencoder, &lockinputbufferparams);     if (nvstatus != nv_enc_success) return nvstatus;      unsigned int pitch = lockinputbufferparams.pitch;      //todo: convert r8g8b8a8 a8r8g8b8      // write buffer     memcpy(lockinputbufferparams.bufferdataptr, mappedresource.pdata, m_height * mappedresource.rowpitch);      // unlock input buffer     nvstatus = m_pencodeapi->nvencunlockinputbuffer(m_pencoder, m_pencoderinputbuffer);      return nvstatus; } 

:: encode frame

nvencstatus rendermanager::encodeframe() {     nvencstatus nvstatus = nv_enc_success;      int8_t* qpdeltamaparray = null;     unsigned int qpdeltamaparraysize = 0;      nv_enc_pic_params encpicparams = {};     encpicparams.version = nv_enc_pic_params_ver;     encpicparams.inputwidth = m_width;     encpicparams.inputheight = m_height;     encpicparams.inputbuffer = m_pencoderinputbuffer;     encpicparams.outputbitstream = m_pencoderoutputbuffer;     encpicparams.bufferfmt = nv_enc_buffer_format_argb;     encpicparams.picturestruct = nv_enc_pic_struct_frame;     encpicparams.qpdeltamap = qpdeltamaparray;     encpicparams.qpdeltamapsize = qpdeltamaparraysize;      nvstatus = m_pencodeapi->nvencencodepicture(m_pencoder, &encpicparams);      return nvstatus; } 

:: read output buffer

nvencstatus rendermanager::readoutputbuffer() {     nvencstatus nvstatus = nv_enc_success;      // lock output buffer     nv_enc_lock_bitstream lockbitstreambufferparams = {};     lockbitstreambufferparams.version = nv_enc_lock_bitstream_ver;     lockbitstreambufferparams.donotwait = 0;     lockbitstreambufferparams.outputbitstream = m_pencoderoutputbuffer;      nvstatus = m_pencodeapi->nvenclockbitstream(m_pencoder, &lockbitstreambufferparams);     if (nvstatus != nv_enc_success) return nvstatus;      void* pdata = lockbitstreambufferparams.bitstreambufferptr;     unsigned int size = lockbitstreambufferparams.bitstreamsizeinbytes;      // read buffer     platformmanager::savetofile("test", static_cast<char*>(pdata), size);      // unlock output buffer     nvstatus = m_pencodeapi->nvencunlockbitstream(m_pencoder, m_pencoderoutputbuffer);      return nvstatus; } 

m_width , m_height 1280 , 720.

why image size wrong , how have fill input buffer more 1 frame ?

many help,

alexander


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -