GPUOpen-LibrariesAndSDKs / AMF

The Advanced Media Framework (AMF) SDK provides developers with optimal access to AMD devices for multimedia processing
Other
616 stars 151 forks source link

How can i reninit decoder when frame width|height changed? #486

Open MemeTao opened 5 months ago

MemeTao commented 5 months ago

I call 'Reinit' when frame width|height changed, but the output texture still keep the old dimension:

// when changed
amf_decoder_->ReInit(new_width, new_height);
amf_decoder_->SubmitInput(image);
 amf::AMFDataPtr new_packet;
amf_decoder_->QueryOutput(&new_packet);
 amf::AMFSurfacePtr input(new_packet);
// recevie decoded frame
ID3D11Texture2D* src_texture = (ID3D11Texture2D*)input->GetPlaneAt(0)->GetNative();
D3D11_TEXTURE2D_DESC desc;
src_texture->GetDesc(&desc); // **desc.width == old_width; desc.height == old_height;**
MikhailAMD commented 5 months ago

The decoder would keep allocation and call SetCrop on the output surface to indicate decoded size. Note, that the same happens when H264 or HEVC stream resolution is not aligned to 16 (or 32 in interlace case). AMF allocates aligned texture and calls SetCrop.

MemeTao commented 5 months ago

The decoder would keep allocation and call SetCrop on the output surface to indicate decoded size. Note, that the same happens when H264 or HEVC stream resolution is not aligned to 16 (or 32 in interlace case). AMF allocates aligned texture and calls SetCrop.

Maybe I didn't express it clearly. When frame size changed from {w1,h1} to {w2,h2}, I expect the output texture size will changes from {w1,h1} to {w2,h2} after 'reinit' called. Here is my code:

// init with {w1,h1}
amf_decoder_->Init(codec, width1, height1);
// decode frams
amf::AMFDataPtr new_packet;
amf_decoder_->QueryOutput(&new_packet);
ID3D11Texture2D* output= (ID3D11Texture2D*)new_packet->GetPlaneAt(0)->GetNative();
D3D11_TEXTURE2D_DESC desc1;
output->GetDesc(&desc1);   // {width1, height1}

// when {w1,h1} changed to {w2, h2}
amf_decoder_->reinit(codec, width2, height2);
...
D3D11_TEXTURE2D_DESC desc2;
output->GetDesc(&desc2);   // still {width1, height1}, **I expect the output desc is {w2,h2}**

The Vs output window: "Assertion failed:y=0, height=1576, m_pSurfaceData->pPlanesHeight[0]=1056"

It seems like the 'reinit' isn't works.

MikhailAMD commented 5 months ago

I expect the output texture size will changes from {w1,h1} to {w2,h2} after 'reinit' called. The expectation is incorrect. The whole point of ReInit is to avoid texture reallocation as it is expensive. Crop is much less expensive and, as I said, it should be taken into account for many clips even without reinit. If you want texture reallocation, you should use Terminate/Init sequence.