DirectShow H.264 encoder does not connects to BaseClasses from DX9 SDK

DirectShow H.264 encoder does not connects to BaseClasses from DX9 SDK

I made simple video transcoding application using Samples DirectShow filters from DX9 SDK. And found that almost no filters based on 'baseclasses' can connects to input of DirectShow Intel H.264 Encoder filter directly or via standard ColorSpaceConverter/aVI Decompressor. Some debugging shows that CheckMediaType passes, but CompleteConnect failes somewhere at final allocators negotiation.The samples I check are EZRGB24 that uses transform-and-copy (CTransformFilter)baseclass and RGBFilters that uses CTransInPlaceFilterbaseclass. Both failed.Software used - Windows 7, MSVC 6.0 SP5, DirectX SDK 9.0. Intel Media SDK 2012 R2.The only way I found to connect filter build from samples to H.264 encoder is to insert ffdshow raw process filter in between.What may be wrong ? May I need to use newer DirectShow baseclasses ?

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hi Andrey,

The Media SDK H.264 Encoder filter only supports color spaces: NV12, RGB32(4) and YUY2.If you are trying to use RGB24, the filter negotiation will fail. If you are required to perform additional color conversion you would have to create intermediate filter or modify the H.264 Encoder filter.

Regards,Petter

My filter is based on RGBFilters->TransSmpte filter from DX9 SDK. It processes dataas RGB32(4) samples and outputs RGB32(4) samples. So it must directly connects to Intel H.264 Encoder in theory.

The connection process passes mediatype and subtype verification ! But failes on completing connection.

More information:

If comment out >> lines in transip.cpp (from BaseClasses):

// CTransInPlaceOutputPin::CompleteConnect() calls CBaseOutputPin::CompleteConnect()
// and then calls CTransInPlaceFilter::CompleteConnect(). It does this because
// CTransInPlaceFilter::CompleteConnect() can reconnect a pin and we do not want to
// reconnect a pin if CBaseOutputPin::CompleteConnect() fails.
// CBaseOutputPin::CompleteConnect() often fails when our output pin is being connected
// to the Video Mixing Renderer.
HRESULT
CTransInPlaceOutputPin::CompleteConnect(IPin *pReceivePin)
{
// comment out and get connectionto Intel H.264 Encoder filter !
>> HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
>> if (FAILED(hr)) {
>> return hr;
>> }

return m_pTransformFilter->CompleteConnect(PINDIR_OUTPUT,pReceivePin);
} // CompleteConnect

I got direct connection of my filter to Intel H.264 Encoder succes, but when graph starts I got crash of 0 pointer in the Intel MP4 Mux (that connected to H.264 encoder).

The last function call that fails HR that I found in connection process is hr = pPin->NotifyAllocator(*ppAlloc, FALSE);
in the file amfilter.cpp of the BaseCalsses of DX9 SDK:

/* Decide on an allocator, override this if you want to use your own allocator
Override DecideBufferSize to call SetProperties. If the input pin fails
the GetAllocator call then this will construct a CMemAllocator and call
DecideBufferSize on that, and if that fails then we are completely hosed.
If the you succeed the DecideBufferSize call, we will notify the input
pin of the selected allocator. NOTE this is called during Connect() which
therefore looks after grabbing and locking the object's critical section */

// We query the input pin for its requested properties and pass this to
// DecideBufferSize to allow it to fulfill requests that it is happy
// with (eg most people don't care about alignment and are thus happy to
// use the downstream pin's alignment request).

HRESULT
CBaseOutputPin::DecideAllocator(IMemInputPin *pPin, IMemAllocator **ppAlloc)
{
HRESULT hr = NOERROR;
*ppAlloc = NULL;

// get downstream prop request
// the derived class may modify this in DecideBufferSize, but
// we assume that he will consistently modify it the same way,
// so we only get it once
ALLOCATOR_PROPERTIES prop;
ZeroMemory(&prop, sizeof(prop));

// whatever he returns, we assume prop is either all zeros
// or he has filled it out.
pPin->GetAllocatorRequirements(&prop);

// if he doesn't care about alignment, then set it to 1
if (prop.cbAlign == 0) {
prop.cbAlign = 1;
}

/* Try the allocator provided by the input pin */

hr = pPin->GetAllocator(ppAlloc);
if (SUCCEEDED(hr)) {

hr = DecideBufferSize(*ppAlloc, &prop);
if (SUCCEEDED(hr)) {
hr = pPin->NotifyAllocator(*ppAlloc, FALSE);
if (SUCCEEDED(hr)) {
return NOERROR;
}
}
}

/* If the GetAllocator failed we may not have an interface */

if (*ppAlloc) {
(*ppAlloc)->Release();
*ppAlloc = NULL;
}

/* Try the output pin's allocator by the same method */

hr = InitAllocator(ppAlloc);
if (SUCCEEDED(hr)) {

// note - the properties passed here are in the same
// structure as above and may have been modified by
// the previous call to DecideBufferSize
hr = DecideBufferSize(*ppAlloc, &prop);
if (SUCCEEDED(hr)) {
hr = pPin->NotifyAllocator(*ppAlloc, FALSE);
if (SUCCEEDED(hr)) {
return NOERROR;
}
}
}

/* Likewise we may not have an interface to release */

if (*ppAlloc) {
(*ppAlloc)->Release();
*ppAlloc = NULL;
}
return hr;
}

So I assume something is wrong with the allocators in the process of connection of Intel DirectShow filters with baseclasses of DirectShow (of DX9 SDK at least, I do not know how baseclasses in the MS SDK 7 are changed).
I have set MS VisualStudio 2008 that sets MS SDK 6.0A and still got the same error. Will try to set MS SDK 7.1 because in the current FAQ it says required MS SDK 6.1 or later.

Can you build RGBFilters (its TransSmpte filter)sample and check if it connects to Intel H.264 Encoder ? Or any other Directshow sample that uses CTransformFilter or CTransInPlaceFilter baseclass and outputs RGB32(4) samples ? Which version of DX/MS SDK is used for it if it works at all ?

Hi Andrey,

DX9 SDK and MS SDK 6.0 are very old and are not SDKs (including the samples) we have considered when implementing the Media SDK sample filters. My impression is that all DShow related samples moved away from DX9 SDK into MS SDK around the time of DX9 SDK release (in ~2004).

I suggest basing your development on MS SDK 7 or later. Hopefully that approach will lead to better integration with the Media SDK sample filters.

Regards,Petter

Well - I got MS SDK 7.1 and still no luck.
Intel Media SDK H.264 Encoder is hard to connect to almost anything from DirectX SDK'passthrough' filter samples:( . For example if creating simple transcoding graph for transcode DV AVI - the MS DV Decoder output canconnect to Intel Media SDK H.264 Encodervia color space converter (YUY2->RGB32). I try in Win 7 64 Eng SP1.

The only filter sample from MS SDK 7 that I got connected is InfTee sample, but it only connects in YUY2 mode and also uses additional color space converters to RGB32. If I try to limit supported formats of InfTee filter to RGB32 only I gotInfTee inputdisconnect (breaks connection) after connecting InfTee->Intel Media SDK H.264 Encoder.

I made extract of sampleTransSmpte filter and it builds with Visual Studio 2008 and MS SDK 7.1 - it is in the attach. It makes processing in RGB32 and outputs it. But Intel Media SDK H.264 Encoder 3.12.4.13 failes to connect to its output. Any more help available ?

Edit: I Add Files via forum post edit, but can not see download link in the post. How to add it ?

Hi Andrey,

We cannot really help you with filters (such as TransSmpte) based on very old DShow SDK samples. There may be framework pieces missing making it incompatible and that were not comprehended during Media SDK DShow sample design.

Not sure what may be the cause of the "Add Files" issue: Normally you would just: (1) Create folder (2) Choose file (3) Upload.

In general I would suggest debugging to try to find out exactly where the filter connection fails. The issue may somehow be related to videoinfo formats or buffer allocator requirements.

Regards,Petter

Leave a Comment

Please sign in to add a comment. Not a member? Join today