Media (Intel® 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 Media SDK project is no longer active. For continued support and access to new features, Intel Media SDK users are encouraged to read the transition guide on upgrading from Intel® Media SDK to Intel® Video Processing Library (VPL), and to move to VPL as soon as possible.
For more information, see the VPL website.

Sanity check decode main loop.

Kamal_Devanga
Beginner
508 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
508 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).

0 Kudos
Kamal_Devanga
Beginner
508 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.... ;).

0 Kudos
Reply