+ AM_MEDIA_TYPE *p_mt;
+
+ /*
+ ** Configure pin with a default compatible media if possible
+ */
+
+ IAMStreamConfig *pSC;
+ if( SUCCEEDED(p_output_pin->QueryInterface( IID_IAMStreamConfig,
+ (void **)&pSC )) )
+ {
+ int piCount, piSize;
+ if( SUCCEEDED(pSC->GetNumberOfCapabilities(&piCount, &piSize)) )
+ {
+ BYTE *pSCC= (BYTE *)CoTaskMemAlloc(piSize);
+ if( NULL != pSCC )
+ {
+ int i_priority = -1;
+ for( int i=0; i<piCount; ++i )
+ {
+ if( SUCCEEDED(pSC->GetStreamCaps(i, &p_mt, pSCC)) )
+ {
+ int i_current_fourcc = GetFourCCFromMediaType( *p_mt );
+ int i_current_priority = GetFourCCPriority(i_current_fourcc);
+
+ if( (i_fourcc && (i_current_fourcc != i_fourcc))
+ || (i_priority > i_current_priority) )
+ {
+ // unwanted chroma, try next media type
+ FreeMediaType( *p_mt );
+ CoTaskMemFree( (PVOID)p_mt );
+ continue;
+ }
+
+ if( MEDIATYPE_Video == p_mt->majortype
+ && FORMAT_VideoInfo == p_mt->formattype )
+ {
+ VIDEO_STREAM_CONFIG_CAPS *pVSCC = reinterpret_cast<VIDEO_STREAM_CONFIG_CAPS*>(pSCC);
+ VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(p_mt->pbFormat);
+
+ if( i_AvgTimePerFrame )
+ {
+ if( pVSCC->MinFrameInterval > i_AvgTimePerFrame
+ || i_AvgTimePerFrame > pVSCC->MaxFrameInterval )
+ {
+ // required frame rate not compatible, try next media type
+ FreeMediaType( *p_mt );
+ CoTaskMemFree( (PVOID)p_mt );
+ continue;
+ }
+ pVih->AvgTimePerFrame = i_AvgTimePerFrame;
+ }
+
+ if( i_width )
+ {
+ if( i_width % pVSCC->OutputGranularityX
+ || pVSCC->MinOutputSize.cx > i_width
+ || i_width > pVSCC->MaxOutputSize.cx )
+ {
+ // required width not compatible, try next media type
+ FreeMediaType( *p_mt );
+ CoTaskMemFree( (PVOID)p_mt );
+ continue;
+ }
+ pVih->bmiHeader.biWidth = i_width;
+ }
+
+ if( i_height )
+ {
+ if( i_height % pVSCC->OutputGranularityY
+ || pVSCC->MinOutputSize.cy > i_height
+ || i_height > pVSCC->MaxOutputSize.cy )
+ {
+ // required height not compatible, try next media type
+ FreeMediaType( *p_mt );
+ CoTaskMemFree( (PVOID)p_mt );
+ continue;
+ }
+ pVih->bmiHeader.biHeight = i_height;
+ }
+
+ // Set the sample size and image size.
+ // (Round the image width up to a DWORD boundary.)
+ p_mt->lSampleSize = pVih->bmiHeader.biSizeImage =
+ ((pVih->bmiHeader.biWidth + 3) & ~3) *
+ pVih->bmiHeader.biHeight * (pVih->bmiHeader.biBitCount>>3);
+
+ // no cropping, use full video input buffer
+ memset(&(pVih->rcSource), 0, sizeof(RECT));
+ memset(&(pVih->rcTarget), 0, sizeof(RECT));
+
+ // select this format as default
+ if( SUCCEEDED( pSC->SetFormat(p_mt) ) )
+ {
+ i_priority = i_current_priority;
+ if( i_fourcc )
+ // no need to check any more media types
+ i = piCount;
+ }
+ }
+ else if( p_mt->majortype == MEDIATYPE_Audio
+ && p_mt->formattype == FORMAT_WaveFormatEx )
+ {
+ AUDIO_STREAM_CONFIG_CAPS *pASCC = reinterpret_cast<AUDIO_STREAM_CONFIG_CAPS*>(pSCC);
+ WAVEFORMATEX *pWfx = reinterpret_cast<WAVEFORMATEX*>(p_mt->pbFormat);
+
+ if( i_current_fourcc && (WAVE_FORMAT_PCM == pWfx->wFormatTag) )
+ {
+ int val = i_channels;
+ if( ! val )
+ val = 2;
+
+ if( val % pASCC->ChannelsGranularity
+ || (unsigned int)val < pASCC->MinimumChannels
+ || (unsigned int)val > pASCC->MaximumChannels )
+ {
+ // required number channels not available, try next media type
+ FreeMediaType( *p_mt );
+ CoTaskMemFree( (PVOID)p_mt );
+ continue;
+ }
+ pWfx->nChannels = val;
+
+ val = i_samplespersec;
+ if( ! val )
+ val = 44100;
+
+ if( val % pASCC->SampleFrequencyGranularity
+ || (unsigned int)val < pASCC->MinimumSampleFrequency
+ || (unsigned int)val > pASCC->MaximumSampleFrequency )
+ {
+ // required sampling rate not available, try next media type
+ FreeMediaType( *p_mt );
+ CoTaskMemFree( (PVOID)p_mt );
+ continue;
+ }
+ pWfx->nSamplesPerSec = val;
+
+ val = i_bitspersample;
+ if( ! val )
+ {
+ if( VLC_FOURCC('f', 'l', '3', '2') == i_current_fourcc )
+ val = 32;
+ else
+ val = 16;
+ }
+
+ if( val % pASCC->BitsPerSampleGranularity
+ || (unsigned int)val < pASCC->MinimumBitsPerSample
+ || (unsigned int)val > pASCC->MaximumBitsPerSample )
+ {
+ // required sample size not available, try next media type
+ FreeMediaType( *p_mt );
+ CoTaskMemFree( (PVOID)p_mt );
+ continue;
+ }
+
+ pWfx->wBitsPerSample = val;
+ pWfx->nBlockAlign = (pWfx->wBitsPerSample * pWfx->nChannels)/8;
+ pWfx->nAvgBytesPerSec = pWfx->nSamplesPerSec * pWfx->nBlockAlign;
+
+ // select this format as default
+ if( SUCCEEDED( pSC->SetFormat(p_mt) ) )
+ {
+ i_priority = i_current_priority;
+ }
+ }
+ }
+ FreeMediaType( *p_mt );
+ CoTaskMemFree( (PVOID)p_mt );
+ }
+ }
+ CoTaskMemFree( (LPVOID)pSCC );
+ if( i_priority >= 0 )
+ msg_Dbg( p_this, "EnumDeviceCaps: input pin default format configured");
+ }
+ }
+ pSC->Release();
+ }
+
+ /*
+ ** Probe pin for available medias (may be a previously configured one)
+ */
+
+ if( FAILED( p_output_pin->EnumMediaTypes( &p_enummt ) ) )