Media (Intel® oneAPI Video Processing Library, Intel Media SDK)
Access community support with transcoding, decoding, and encoding in applications using media tools like Intel® oneAPI Video Processing Library and Intel® Media SDK
Announcements
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.

Sanity check decode main loop.

Kamal_Devanga
Beginner
178 Views

 

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;
			
		}
	}
}

 

 

 

 

0 Kudos
2 Replies
Kamal_Devanga
Beginner
178 Views

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).

Kamal_Devanga
Beginner
178 Views

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.... ;).

Reply