- 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