- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
I'm trying to figure out why my HEVC encoder fails to convert 4K input video frames. There is no problem with 720p or 1080p encoding. But once I tried to encode the 4K video(big buck bunny 2160p 30 fps) in Release configuration it fails in this way: process starts, successully encodes part of the input video(5-20% of the total video duration) and then fails with error. This is the Release build, so I checked the SDK tracer generated logs. The SyncOperation returned the MFX_ERR_NOT_ENOUGH_BUFFER error code. According to docs(http://kavi.hotar.ru/system/files/private/media_server_studio_sdk_release_notes.pdf pages 17 and 18) MFX_ERR_NOT_ENOUGH_BUFFER is a possible error for HEVC encoding case. The buffer size is computed as in the tutorial:
const size_t uTaskMaxDataLength = selectedParameters.mfx.BufferSizeInKB * 1000;
I decided to increase the task data and multiplied it by 2000, so the task data became 2 times larger. With this change the problem has gone.
So, to avoid memory consumption, this should be OK to allocate larger buffer when error occured and try to Sync one more time. So, I've implemented this logic:
status = pSession->SyncOperation(pTask->syncPoint, 60000); // Synchronize. Wait until encoded frame is ready // Handle Buffer size error first. In this case we need to allocate larger buffer and try again while (status == MFX_ERR_NOT_ENOUGH_BUFFER) { if (!AllocateLargerBufferForTask(*pTask)) return false; // Try to encode the frame again with new allocated buufer status = pSession->SyncOperation(pTask->syncPoint, 60000); } bool AllocateLargerBufferForTask(LMFXTask& task) { const uint32_t uNewBufferSize = task.saData.GetSize() * 3 / 2; task.saData.SetArrayCapacityLarge(uNewBufferSize); if (!task.saData.IsValid()) { LFDEBUG("Can't allocate enough memory for task"); return false; } task.saData.SetSize(uNewBufferSize); // Update the bitstream members with new buffer size and data pointer task.mfxBS.MaxLength = uNewBufferSize; task.mfxBS.Data = task.saData.get(); return true; }
You can see the buffer would be increased until it would have enough size to get the bitstream data. But the problem it didn't worked. So, I can't handle the error and try to increase the buffer size. Also, I'm unable to compute the buffer size in the beginning, because there is no guarantee that the multiplication by 2000 instead of 1000 would never fail with the same bug. Also multiplication by 2000 consumes additional memory per each task(I set the async depth to 4).
Could you provide any advice how to solve this issue ? The logic
if (codec == HEVC) taskDataSize *= 2;
Looks wrong and I don't like to use it in the code.
Logs:
18552 2019-11-22 11:13:3:362 function: MFXVideoCORE_SyncOperation(mfxSession session=0118E488, mfxSyncPoint syncp=000CE400, mfxU32 wait=60000) +
18552 2019-11-22 11:13:3:362 mfxSession session=0AAD714C
18552 2019-11-22 11:13:3:362 mfxSyncPoint* syncp=000CE400
18552 2019-11-22 11:13:3:362 mfxU32 wait=60000
18552 2019-11-22 11:13:3:364 >> MFXVideoCORE_SyncOperation called
18552 2019-11-22 11:13:3:364 mfxSession session=0AAD714C
18552 2019-11-22 11:13:3:364 mfxSyncPoint* syncp=000CE400
18552 2019-11-22 11:13:3:364 mfxU32 wait=60000
18552 2019-11-22 11:13:3:364 function: MFXVideoCORE_SyncOperation(1.4252 msec, status=MFX_ERR_NONE) -
18552 2019-11-22 11:13:3:368 function: MFXVideoENCODE_EncodeFrameAsync(mfxSession session=0118E488, mfxEncodeCtrl *ctrl=00000000, mfxFrameSurface1 *surface=0A8B6878, mfxBitstream *bs=0AAD76C0, mfxSyncPoint *syncp=0AAD7700) +
18552 2019-11-22 11:13:3:368 mfxSession session=0AAD714C
...
18552 2019-11-22 11:13:3:371 mfxSyncPoint* syncp=000CF400
18552 2019-11-22 11:13:3:371 function: MFXVideoENCODE_EncodeFrameAsync(0.028 msec, status=MFX_ERR_NONE) -
18552 2019-11-22 11:13:3:383 function: MFXVideoCORE_SyncOperation(mfxSession session=0118E488, mfxSyncPoint syncp=000CE803, mfxU32 wait=60000) +
18552 2019-11-22 11:13:3:383 mfxSession session=0AAD714C
18552 2019-11-22 11:13:3:383 mfxSyncPoint* syncp=000CE803
18552 2019-11-22 11:13:3:384 mfxU32 wait=60000
18552 2019-11-22 11:13:3:408 >> MFXVideoCORE_SyncOperation called
18552 2019-11-22 11:13:3:408 mfxSession session=0AAD714C
18552 2019-11-22 11:13:3:409 mfxSyncPoint* syncp=000CE803
18552 2019-11-22 11:13:3:409 mfxU32 wait=60000
18552 2019-11-22 11:13:3:409 function: MFXVideoCORE_SyncOperation(24.7706 msec, status=MFX_ERR_NOT_ENOUGH_BUFFER) -
- Tags:
- Development Tools
- Graphics
- Intel® Media SDK
- Intel® Media Server Studio
- Media Processing
- Optimization
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
I've created the YUV input file from the H264 video with ffmpeg and used simple_encode_hevc10 tutorial(changed 10 bit settings to 8 bit) and encoding succeeded.
Also, The problem is not reproducible after I set the GOP options. So, I think the problem is solved. Thanks!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Andrey,
Could you run sampe_encode with this input stream and check if it has the same error?
https://github.com/Intel-Media-SDK/MediaSDK/tree/master/samples
If sample_encode works, you can check if simple_3_encode in our tutorial works; by default, it was coded as H.264, you can change it to HEVC for your input.
https://github.com/Intel-Media-SDK/MediaSDK/tree/master/tutorials
If the tutorial works, you can copy this code to yours.
Mark
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
No, I can't check sample_encode tutorial, because it takes raw YUV input stream and I have an input h264 video. Is it possible to get the YUV stream from the H264 encoded video ?
Also, I'm using async encoding with async depth = 4 + video memory. and the sample_encode uses system memory without async mode.
Anyway, I took the sample_encode as a reference to start implementing the encoder. The encoder works fine with AVC for any input video(720p, 1080p or 4K). But for HEVC encoder, 4K input video and task buffer size == BufferSizeInKB * 1000 I got this problem. No issue for Hevc and 4K input video in case task buffer size == BufferSizeInKB * 1000 * 2.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
I've created the YUV input file from the H264 video with ffmpeg and used simple_encode_hevc10 tutorial(changed 10 bit settings to 8 bit) and encoding succeeded.
Also, The problem is not reproducible after I set the GOP options. So, I think the problem is solved. Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Andrey,
Thanks so much for the update and apologized for not responding.
It looks like our documents is good enough to solve the problem but might not organized very well. If you agree, could you give us some suggestions?
Mark
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page