Wednesday, April 25, 2007

This pin cannot use the supplied media type and Cannot allocate a sample when the allocator is not active.

---------------------------
GraphEdit
---------------------------
The graph could not change state.

This pin cannot use the supplied media type. (Return code: 0x8004022a)
---------------------------
OK
---------------------------


9.00 - 9.30 - I tried to change the media type using SetMediaType() fn well ... I got an enough output window in GraphEdit

I got an error as

---------------------------
GraphEdit
---------------------------
The graph could not change state.

This pin cannot use the supplied media type. (Return code: 0x8004022a)
---------------------------
OK
---------------------------

One thing I noted in SetMediaType() fn's MediaType that is

I had the width and height and size of the VIDEOINFOHEADER as correct as output pin.( 400,400)..

But rcTarget and rcSource rectangle remains like as input pin... (240,320)


9.30 - 10.30 - Even though I set the rcTarget and rcSource rectangle I got an error...

Still I am not able to get the IMediaSample of an Output pin...

the process of getting IMediaSample of an output pin is failed...



10.30 - 11.30 - I tried several approaches all are failed...

-Output Pin's NonDelegatingAddRef() and NonDelegatingRelease() continuously called

I commented the DisplayHistogram() fn for Output pin...




AM_SAMPLE2_PROPERTIES * const pProps = m_ip[0]->SampleProps();
DWORD dwFlags = 0;


pProps->dwSampleFlags - 273
AM_SAMPLE_SPLICEPOINT - 1

AM_SAMPLE_TIMEVALID - 16
AM_SAMPLE_STOPVALID - 256


if ( ! (pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT ) )
{
//if the dwSampleFlags is Even number then only the condition will becomes true

}



GetBuffer() fn they tried the following :

HRESULT hr = m_op->m_pAllocator->GetBuffer(
&pOutSample
, pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID ?
&pProps->tStart : NULL
, pProps->dwSampleFlags & AM_SAMPLE_STOPVALID ?
&pProps->tStop : NULL
, dwFlags
);

dwFlags - 0


Flags passed to the GetBuffer() fn...

#define AM_GBF_PREVFRAMESKIPPED 1
#define AM_GBF_NOTASYNCPOINT 2
#define AM_GBF_NOWAIT 4
#define AM_GBF_NODDSURFACELOCK 8


//For Displaying the DirectShow Error...

void ShowError(HRESULT hr)
{
if (FAILED(hr))
{
TCHAR szErr[MAX_ERROR_TEXT_LEN];
DWORD res = AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
if (res == 0)
{
wsprintf(szErr, "Unknown Error: 0x%2x", hr);
}

MessageBox(0, szErr, TEXT("Error!"), MB_OK | MB_ICONERROR);
}
}

//For displaying Error With ErrorCode :
void ShowError(HRESULT hr)
{
if (FAILED(hr))
{
TCHAR szErr[MAX_ERROR_TEXT_LEN];
TCHAR szNumber[20];
DWORD res = AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN);
if (res == 0)
{
wsprintf(szErr, "Unknown Error: 0x%2x", hr);
}
wsprintf(szNumber," :0x%2x",hr);
strcat(szErr,szNumber);
MessageBox(0, szErr, TEXT("Error!"), MB_OK | MB_ICONERROR);
}
}





I got an error while try to get the output media sample...

---------------------------
Error!
---------------------------
Cannot allocate a sample when the allocator is not active. :0x80040211
---------------------------
OK
---------------------------
VFW_E_NOT_COMMITTED - Allocator is decommitted.

This is returned by the output pin's allocator's GetBuffer() fn...


For Solving this problem ... I looked the documentation Before getting the output pin's media sample using GetBuffer() we have to call the

Commit() fn of an allocator. This will be Done in Active () fn of an output pin and after calling the GetBuffer() fn we have to call the Decommit()

fn to decommit the media samples this is called in Inactive() fn of an output pin...

CMyFilter is the class derived from CBaseFilter.

CMyFilter :: Pause()
{
outputPin->Active()
}

CMyFilter::Stop()
{
outputPin->Inactive();
}


HRESULT COutputPin :: Active()
{
return outputAllocator->commit();
}


After calling Pause() we have to call the GetBuffer() fn of an output allocator to get the IMediaSample of an output pin...

while closing we have to call stop() decommit the allocated samples.

HRESULT COutputPin:: InActive()
{
return OutputAllocator->Decommit();
}


After solving this problem I got the previous error like

"this pin cannot use the specified media type..."

I specified the invalid values in rcSource and rcTarget rectangles in the media type.

we have to set this media type to the output pin...After setting the media type, we have to delete the media type

using DeleteMediaType() fn.

Now the output window has invalid video data ... it is like flickering...


and displayed the error " This pin can not use the specified media type ".I am not able to fi x the problem...


Now the problem is how to set the media type for an output pin ?

GetMediaType should create a media type for the output based on the input
format (and your known transformation characteristics). SetMediaType should
set the selected format and its buffer size, and then DecideBufferSize
should set the allocator's buffer size based on the type passed to
SetMediaType. But remember that if you want to work with the video
renderer, you may get a dynamic type change on the first buffer, typically
to change the stride, and you need to use that type.


CTransformOutput pin class:
1.CheckMediaType()
2.SetMediaType()
3.GetMediaType( )...

CTransformFilter class
1.GetMediaType() fn


"This pin can not use the specified media type"
To avoid this error...

Get the sample size of an Output Pins media sample size...
and remove the setMediatype() fn...


I get the sample size using the

OutputSample->GetMediaType(pmt);
VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;

long lSize;
lSize = pvi->bmiHeader.biSizeImage;

DeleteMediaType(pmt);


I am looking on Output Pin's media Type setting...

we can retrieve the Output pin's media sample's properties and its media type...

So I may try this approach to set the media type...

iMediaSample has properties AM_SAMPLE2_PROPERTIES like that...
we can set the Media Type to the pMediaType member of the AM_SAMPLE2_PROPERTIES obtained from Output pin's
media sample's mediatype.


I can change the media type in two ways..

1. Change the Mediatype using AM_SAMPLE2_PROPERTIES structure and Set it as a Output pin's media sample
media type

2.Another way is to imitate the GetMediaType() function of the CTransformFilter

( In my thought, This seems better option because The GetMediaType() executed only two or 3 times whereas

the first process will be executed for each Transform() fn )...


GetMediaType() is not getting executed.So I have to identify the reason.

Actually i didnt print the debug string in Outputpin's GetMediaType() fn..


GetMediaType() with EnumMediatypes() works well.. but the output window is same as input pin..

SetMediaType() fn with EnumMediaTypes() works well , but the output window can be different from input pin...

so the problem lies with the EnumMediaTypes() fn...


In the second approach I faced many problems and finally the Output pin's media type is not set properly.
So I got an error as follows :

---------------------------
GraphEdit
---------------------------
The graph could not change state.

This pin cannot use the supplied media type. (Return code: 0x8004022a)
---------------------------
OK
---------------------------


So change the media type in the first way...

Eventhough I changed the media type Still I got the same error...

But I didnt get an error anywhere in my program and output also some flickering due to invalid output pin's video size...




Look at the Working of CTransformOutputPin's GetMediaType() fn...

and check whether any EnumMediaTypes() function used in CTransformOutputPin class..

No comments: