- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'd appreciate a sanity check of my decode main loop. The problem is that on another machine although I'm calling DecodeFrameAsync, getting a sync point and calling SyncOperation, the frame still has locked = 1. I assumed after SyncOperation it would be 0 (hence I'm asserting there). I've tried with with AsyncDepth = 4 and AsyncDepth = 1.
Can someone spot my mistake?
// Check we've got the required components.
assert(My_QSV_Session != nullptr);
assert(My_QSV_Decoder != nullptr);
assert(My_QSV_Allocator != nullptr);
assert(MyCurrentGOP != nullptr);
{
// The sync point (semaphore) we'll use to synchronise tasks.
mfxSyncPoint sync_point = nullptr;
// Current working surface.
mfxFrameSurface1 * surface_output = nullptr;
auto status = MFX_ERR_NONE;
for (;;)
{
// Find a free surface.
auto surface_work = find_unlocked_surface();
if (surface_work)
{
// Do some decoding.
status = MFX_ERR_NONE;
while ((status = My_QSV_Decoder->DecodeFrameAsync(My_QSV_Input_Byte_Stream.get(), surface_work, &surface_output, &sync_point)) == MFX_WRN_DEVICE_BUSY)
{
// Busy, so sleep for a bit.
::Sleep(1);
}
if (status == MFX_WRN_DEVICE_BUSY)
{
// Device is busy so we need to sleep.
if (sync_point)
{
// ...except we have a sync point meaning frames are ready, so don't sleep. Reset the state so we pick up the encoded frames below.
status = MFX_ERR_NONE;
}
else
{
// No sync point so sleep for a bit.
::Sleep(1);
// Try again.
continue;
}
}
else if (status == MFX_ERR_MORE_DATA)
{
if (!My_QSV_Input_Byte_Stream)
{
// If status == more and we have no byte stream, we've geniunely finished decoding, though there may still be frames in the pipe, hence we won't return.
}
else
{
// Next time this function is called, it'll have no bit stream, which is our way of telling DecodeFrameAsync our input has finished.
My_QSV_Input_Byte_Stream.reset();
// Call decode again to get a sync point for the next frame as the above call "failed" so we won't have one yet.
continue;
}
}
}
// If we got a surface, call sync to release it.
if (sync_point)
{
status = mfxStatus::MFX_ERR_NONE;
// If this fails 32 times there really is something wrong.
for (auto i = 0; i < 32; i++)
{
status = My_QSV_Session->SyncOperation(sync_point, MyParameters.Fence_Wait /* this is the wait time for the sync point, i.e. the timeout. */);
if (status != MFX_WRN_IN_EXECUTION)
{
// MFX_WRN_IN_EXECUTION seen occassionally...
break;
}
}
// Should be none here.
if (status != mfxStatus::MFX_ERR_NONE)
{
// If sync fails, it's a catastrophe I suppose.
return E_DECODER_SYNC_FAILED;
}
// surface_output is the in-order output frame (I assume?)
assert(surface_output != nullptr);
assert(!surface_output->Data.Locked); // This fails on other machine.
assert(surface_output->Info.FourCC == MFX_FOURCC_NV12);
{
// Copy the frame over.
// ...
return E_DECODER_FRAME_DECODED;
}
}
// We did nothing, was that because we'd finished?
if (!My_QSV_Input_Byte_Stream && !surface_output && !sync_point && status == MFX_ERR_MORE_DATA)
{
return E_DECODER_FINISHED;
}
}
}
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So it's giving a UMC::h264_exception at memory location 0x06BBF920. First-chance exception at 0x75C6DAE8. Microsoft C++ exception: [rethrow] at memory location 0x00000000.
I suppose there's something seriously (on this PC, the other one is fine).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We fixed this by building and using the mfx_dispatch project shipped with the SDK (the one in the opensource folder) instead of just linking to the pre-built library. It turns out for whatever reason, that the "c++ - 'LIBCMT' conflicts with use of other libs" build warnings are important and should not be hidden or ignored.
Who knew.... ;).
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page