AMF icon indicating copy to clipboard operation
AMF copied to clipboard

[Question]: ReInit or full Init does not work with encoder

Open KKcoodari opened this issue 2 months ago • 3 comments

Hello,

I have a need to change resolution while encoding a video stream. When the resolution changes, I flush the encoder and reinit with a new resolution. However, after reinitializing the encoder and submitting a new input, QueryOutput only gives AMF_REPEAT. Same problem occurs even when terminating encoder and context and creating encoder and context again with Init.

I am using DX9 and AMD Radeon 8060S with 25.10.25.10-250825a-418637C-AMD-Software-Adrenalin-Edition 32.0.21025.10016 driver version.

Below is some code to show what I am attempting with error checking and logging removed for brevity. I am using an intermediate texture and surface m_shrinkSurface and m_shrinkTexture to shrink the original rendertarget to a lower resolution, because using StretchRect directly to the AMFSurface did not seem to work. Also trying to create the AMFSurface with AMFContext::CreateSurfaceFromDX9Native did not work. I have tried with both H264 and H265 codecs. The video encoding works until I reinitialize. Thanks for help in advance!

  AMF_RESULT res;
  
  if (!m_surfaceIn) {
    res = m_context->AllocSurface(amf::AMF_MEMORY_DX9, m_inputSurfaceFormat, m_currentDynamicResolution.x, m_currentDynamicResolution.y, &m_surfaceIn);
  }
  
  IDirect3DSurface9* pRenderTarget = nullptr;
  auto dxRes = m_dx9Device->GetRenderTarget(0, &pRenderTarget);  

  D3DSURFACE_DESC desc;
  pRenderTarget->GetDesc(&desc);

  IDirect3DSurface9* sourceSurface = pRenderTarget;
  if (desc.Width != m_currentDynamicResolution.x || desc.Height != m_currentDynamicResolution.y) {
    if (!m_shrinkTexture || !m_shrinkSurface || (m_shrinkSurface->GetDesc(&desc) == 0 && (desc.Width != m_currentDynamicResolution.x || desc.Height != m_currentDynamicResolution.y))){
      if (m_shrinkSurface) {
        m_shrinkSurface->Release();
        m_shrinkSurface = nullptr;
      }
      if (m_shrinkTexture) {
        m_shrinkTexture->Release();
        m_shrinkTexture = nullptr;
      }
      auto hr = m_dx9Device->CreateTexture(m_currentDynamicResolution.x, m_currentDynamicResolution.y, 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, &m_shrinkTexture, nullptr);

      hr = m_shrinkTexture->GetSurfaceLevel(0, &m_shrinkSurface);
    }
    auto hr = m_dx9Device->StretchRect(pRenderTarget, nullptr, m_shrinkSurface, nullptr, D3DTEXF_LINEAR);

    sourceSurface = m_shrinkSurface;
  }
  
  sourceSurface->GetDesc(&desc);
  
  amf::AMFPlane* pPlane = m_surfaceIn->GetPlaneAt(0);
  IDirect3DSurface9* pSurfaceDX9 = (IDirect3DSurface9*)pPlane->GetNative();
  pSurfaceDX9->GetDesc(&desc);

  auto hr = m_dx9Device->StretchRect(sourceSurface, nullptr, pSurfaceDX9, nullptr, D3DTEXF_NONE);
  
  res = m_encoder->SubmitInput(m_surfaceIn);
  pRenderTarget->Release();

  m_surfaceIn = nullptr;

KKcoodari avatar Oct 21 '25 15:10 KKcoodari

You may want to share your code for flush, reinit and logic to re-create AMF surface. Also please enable AMF logging and share full log: AMFTraceSetPath(L"<my_folder_path>"); AMFTraceEnableWriter(AMF_TRACE_WRITER_FILE, true); AMFTraceSetWriterLevel(AMF_TRACE_WRITER_FILE, AMF_TRACE_DEBUG);

MikhailAMD avatar Oct 21 '25 15:10 MikhailAMD

amflog.txt

Reading the AMFTrace log, this seems to be the problem: 2025-10-22 14:26:25.054 4FF4 [AMFEncoderCoreH264] Error: C:\constructicon\builds\gfx\six\25.10\drivers\amf\stable\runtime\src\components\EncoderCore\EncoderCoreH264Impl.cpp(1326):Assertion failed:expected taskid=160 Feedback output: taskId=159, isFirst=1, isLast=1, hdcpEncrypted=0

AMF Surface m_surfaceIn is created each time it is used with allocsurface and destroyed by assigning it nullptr, since it is a amf::AMFSurfacePtr. Below is my Flush + ReInit.

  if (m_needResolutionChange) {
    m_currentDynamicResolution = m_requestedResolution;

    m_parameters.xRes = m_requestedResolution.x;
    m_parameters.yRes = m_requestedResolution.y;

    auto res = m_encoder->Flush();
    
    res = m_encoder->ReInit(m_requestedResolution.x, m_requestedResolution.y);
    
    m_needResolutionChange = false;
  }

KKcoodari avatar Oct 22 '25 11:10 KKcoodari

I have reproduced the issue and created an internal ticket to the corresponding team to address this issue.

rhutsAMD avatar Oct 23 '25 17:10 rhutsAMD