# HG changeset patch # User voroshil # Date 1195587207 0 # Node ID e27cb70d2302ec4effe74a6a12348705637aacee # Parent e701372dad8bc7cf263bdd2fed874a91932e8fbf Move code related to chain initialization and similar for different chains to separate routine. diff -r e701372dad8b -r e27cb70d2302 stream/tvi_dshow.c --- a/stream/tvi_dshow.c Tue Nov 20 17:19:16 2007 +0000 +++ b/stream/tvi_dshow.c Tue Nov 20 19:33:27 2007 +0000 @@ -145,6 +145,7 @@ typedef struct { stream_type type; ///< stream type const GUID* majortype; ///< GUID of major mediatype (video/audio/vbi) + const GUID* pin_category; ///< pin category (pointer to one of PIN_CATEGORY_*) IBaseFilter *pCaptureFilter; ///< capture device filter IAMStreamConfig *pStreamConfig; ///< for configuring stream @@ -2451,6 +2452,66 @@ } /** + * \brief common chain initialization routine + * \param chain chain data structure + * + * \note pCaptureFilter member should be initialized before call to this routine + */ +static HRESULT init_chain_common(ICaptureGraphBuilder2 *pBuilder, chain_t *chain) +{ + HRESULT hr; + int i; + + if(!chain->pCaptureFilter) + return E_POINTER; + + show_filter_info(chain->pCaptureFilter); + + hr = OLE_CALL_ARGS(pBuilder, FindPin, + (IUnknown *) chain->pCaptureFilter, + PINDIR_OUTPUT, chain->pin_category, + chain->majortype, FALSE, 0, &chain->pCapturePin); + + if (FAILED(hr)) { + mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: FindPin(pCapturePin) call failed. Error:0x%x\n", (unsigned int)hr); + return hr; + } + + hr = OLE_CALL_ARGS(pBuilder, FindInterface, + chain->pin_category, + chain->majortype, + chain->pCaptureFilter, + &IID_IAMStreamConfig, + (void **) &(chain->pStreamConfig)); + if (FAILED(hr)) + chain->pStreamConfig = NULL; + + /* + Getting available video formats (last pointer in array will be NULL) + First tryin to call IAMStreamConfig::GetStreamCaos. this will give us additional information such as + min/max picture dimensions, etc. If this call fails trying IPIn::EnumMediaTypes with default + min/max values. + */ + hr = get_available_formats_stream(chain); + if (FAILED(hr)) { + mp_msg(MSGT_TV, MSGL_DBG2, "Unable to use IAMStreamConfig for retriving available formats (Error:0x%x). Using EnumMediaTypes instead\n", (unsigned int)hr); + hr = get_available_formats_pin(pBuilder, chain); + if(FAILED(hr)){ + chain->arpmt = calloc(1, sizeof(AM_MEDIA_TYPE *)); + chain->arStreamCaps = calloc(1, sizeof(void*)); + } + } + chain->nFormatUsed = 0; + + //If argument to CreateMediaType is NULL then result will be NULL too. + chain->pmt = CreateMediaType(chain->arpmt[0]); + + for (i = 0; chain->arpmt[i]; i++) + DisplayMediaType("Available format", chain->arpmt[i]); + + return S_OK; +} +/** * \brief build video stream chain in graph * \param priv private data structure * @@ -2639,10 +2700,13 @@ priv->chains[0]->type=video; priv->chains[0]->majortype=&MEDIATYPE_Video; + priv->chains[0]->pin_category=&PIN_CATEGORY_CAPTURE; priv->chains[1]->type=audio; priv->chains[1]->majortype=&MEDIATYPE_Audio; + priv->chains[1]->pin_category=&PIN_CATEGORY_CAPTURE; priv->chains[2]->type=vbi; priv->chains[2]->majortype=&MEDIATYPE_VBI; + priv->chains[2]->pin_category=&PIN_CATEGORY_VBI; do{ hr = CoCreateInstance((GUID *) & CLSID_FilterGraph, NULL, @@ -2720,28 +2784,6 @@ priv->pCrossbar = NULL; } - hr = OLE_CALL_ARGS(priv->pBuilder, FindInterface, - &PIN_CATEGORY_CAPTURE, - priv->chains[0]->majortype, - priv->chains[0]->pCaptureFilter, - &IID_IAMStreamConfig, - (void **) &(priv->chains[0]->pStreamConfig)); - if (FAILED(hr)) { - mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TVI_DS_ChangingWidthHeightNotSupported); - priv->chains[0]->pStreamConfig = NULL; - } - - hr = OLE_CALL_ARGS(priv->pBuilder, FindInterface, - &PIN_CATEGORY_CAPTURE, - priv->chains[1]->majortype, - priv->chains[1]->pCaptureFilter, - &IID_IAMStreamConfig, - (void **) &(priv->chains[1]->pStreamConfig)); - if (FAILED(hr)) { - mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Get IAMStreamConfig(audio) failed (0x%x).\n", (unsigned int)hr); - priv->chains[1]->pStreamConfig = NULL; - } - if (priv->tv_param->amode >= 0) { IAMTVAudio *pTVAudio; hr = OLE_CALL_ARGS(priv->pBuilder, FindInterface, NULL, NULL,priv->chains[0]->pCaptureFilter,&IID_IAMTVAudio, (void *) &pTVAudio); @@ -2767,23 +2809,20 @@ mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TVI_DS_UnableSetAudioMode, priv->tv_param->amode,(unsigned int)hr); } } - /* - Getting available video formats (last pointer in array will be NULL) - First tryin to call IAMStreamConfig::GetStreamCaos. this will give us additional information such as - min/max picture dimensions, etc. If this call fails trying IPIn::EnumMediaTypes with default - min/max values. - */ - - hr = get_available_formats_stream(priv->chains[0]); - if (FAILED(hr)) { - mp_msg(MSGT_TV, MSGL_DBG2, "Unable to use IAMStreamConfig for retriving available video formats (Error:0x%x). Using EnumMediaTypes instead\n", (unsigned int)hr); - hr = get_available_formats_pin(priv->pBuilder, priv->chains[0]); - if(FAILED(hr)){ - mp_msg(MSGT_TV,MSGL_ERR, MSGTR_TVI_DS_UnableGetsupportedVideoFormats, (unsigned int)hr); - break; - } - } - priv->chains[0]->nFormatUsed = 0; + + // Video chain initialization + hr = init_chain_common(priv->pBuilder, priv->chains[0]); + if(FAILED(hr)) + break; + + // Audio chain initialization + init_chain_common(priv->pBuilder, priv->chains[1]); + + // VBI chain initialization + init_chain_common(priv->pBuilder, priv->chains[2]); + + if (!priv->chains[0]->pStreamConfig) + mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TVI_DS_ChangingWidthHeightNotSupported); if (!priv->chains[0]->arpmt[priv->chains[0]->nFormatUsed] || !extract_video_format(priv->chains[0]->arpmt[priv->chains[0]->nFormatUsed], @@ -2792,55 +2831,14 @@ mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_ErrorParsingVideoFormatStruct); break; } - priv->chains[0]->pmt = CreateMediaType(priv->chains[0]->arpmt[priv->chains[0]->nFormatUsed]); - /* - Getting available audio formats (last pointer in array will be NULL) - */ - hr = get_available_formats_stream(priv->chains[1]); - if (FAILED(hr)) { - mp_msg(MSGT_TV, MSGL_DBG2, "Unable to use IAMStreamConfig for retriving available audio formats (Error:0x%x). Using EnumMediaTypes instead\n", (unsigned int)hr); - hr = get_available_formats_pin(priv->pBuilder, priv->chains[1]); - if (FAILED(hr)) { - mp_msg(MSGT_TV,MSGL_WARN, MSGTR_TVI_DS_UnableGetsupportedAudioFormats, (unsigned int)hr); - /* - Following combination will disable sound - */ - priv->chains[1]->arpmt = (AM_MEDIA_TYPE **) malloc(sizeof(AM_MEDIA_TYPE *)); - priv->chains[1]->arpmt[0] = NULL; - priv->chains[1]->pmt = NULL; - priv->chains[1]->pStreamConfig = NULL; - } - } - /* - Getting formats for VBI stream - */ - priv->chains[2]->nFormatUsed = 0; - priv->chains[2]->arpmt = calloc(2, sizeof(AM_MEDIA_TYPE*)); - priv->chains[2]->arpmt[0] = calloc(1, sizeof(AM_MEDIA_TYPE)); - priv->chains[2]->arpmt[0]->majortype = MEDIATYPE_VBI; - - priv->chains[2]->pmt = CreateMediaType(priv->chains[2]->arpmt[priv->chains[2]->nFormatUsed]); - - /* debug */ - { - int i; - for (i = 0; priv->chains[0]->arpmt[i]; i++) { - DisplayMediaType("Available video format", priv->chains[0]->arpmt[i]); - } - for (i = 0; priv->chains[1]->arpmt[i]; i++) { - DisplayMediaType("Available audio format", priv->chains[1]->arpmt[i]); - } - } - priv->chains[1]->nFormatUsed = 0; + if (priv->chains[1]->arpmt[priv->chains[1]->nFormatUsed]) { - priv->chains[1]->pmt = CreateMediaType(priv->chains[1]->arpmt[priv->chains[1]->nFormatUsed]); if (!extract_audio_format(priv->chains[1]->pmt, &(priv->samplerate), NULL, NULL)) { mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_ErrorParsingAudioFormatStruct); DisplayMediaType("audio format failed",priv->chains[1]->arpmt[priv->chains[1]->nFormatUsed]); break; } } - show_filter_info(priv->chains[0]->pCaptureFilter); hr = OLE_QUERYINTERFACE(priv->pGraph, IID_IMediaControl,priv->pMediaControl); if(FAILED(hr)){