From d7c6d240b551bae8d674c46587e3b5027d1cc295 Mon Sep 17 00:00:00 2001 From: Fabricio Costa Alisedo Date: Wed, 10 Aug 2011 12:13:34 +0000 Subject: dshowsrcwrapper: Added Graph Builder and Capture Builder to correctly create upstream needed filters by Analog TV Capture Devices. --- sys/dshowsrcwrapper/gstdshowvideosrc.cpp | 112 ++++++++++++++++++++++++++++--- sys/dshowsrcwrapper/gstdshowvideosrc.h | 7 ++ 2 files changed, 108 insertions(+), 11 deletions(-) (limited to 'sys/dshowsrcwrapper') diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp index 659ad386d..52d8f2fc0 100644 --- a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp +++ b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp @@ -199,6 +199,12 @@ gst_dshowvideosrc_init (GstDshowVideoSrc * src, GstDshowVideoSrcClass * klass) src->pins_mediatypes = NULL; src->is_rgb = FALSE; + /*added for analog input*/ + src->graph_builder = NULL; + src->capture_builder = NULL; + src->pVC = NULL; + src->pVSC = NULL; + src->buffer_cond = g_cond_new (); src->buffer_mutex = g_mutex_new (); src->buffer = NULL; @@ -610,14 +616,37 @@ gst_dshowvideosrc_start (GstBaseSrc * bsrc) { HRESULT hres = S_FALSE; GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (bsrc); - - hres = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC, - IID_IFilterGraph, (LPVOID *) & src->filter_graph); - if (hres != S_OK || !src->filter_graph) { + + /* + The filter graph now is created via the IGraphBuilder Interface + Code added to build upstream filters, needed for USB Analog TV Tuners / DVD Maker, based on AMCap code. + by Fabrice Costa + */ + + hres = CoCreateInstance(CLSID_FilterGraph, NULL, + CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (LPVOID *) & src->graph_builder ); + if (hres != S_OK || !src->graph_builder ) { GST_ERROR - ("Can't create an instance of the dshow graph manager (error=0x%x)", + ("Can't create an instance of the dshow graph builder (error=0x%x)", hres); goto error; + } else { + /*graph builder is derived from IFilterGraph so we can assign it to the old src->filter_graph*/ + src->filter_graph = (IFilterGraph*) src->graph_builder; + } + + /*adding capture graph builder to correctly create upstream filters, Analog TV, TV Tuner */ + + hres = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, + CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, + (LPVOID *) & src->capture_builder); + if ( hres != S_OK || !src->capture_builder ) { + GST_ERROR + ("Can't create an instance of the dshow capture graph builder manager (error=0x%x)", + hres); + goto error; + } else { + src->capture_builder->SetFiltergraph(src->graph_builder); } hres = src->filter_graph->QueryInterface (IID_IMediaFilter, @@ -639,6 +668,34 @@ gst_dshowvideosrc_start (GstBaseSrc * bsrc) goto error; } + /* Finding interfaces really creates the upstream filters */ + + hres = src->capture_builder->FindInterface(&PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Interleaved, src->video_cap_filter, + IID_IAMVideoCompression, (LPVOID *)&src->pVC); + + if(hres != S_OK) + { + hres = src->capture_builder->FindInterface(&PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Video, src->video_cap_filter, + IID_IAMVideoCompression, (LPVOID *)&src->pVC); + } + + hres = src->capture_builder->FindInterface(&PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Interleaved, + src->video_cap_filter, IID_IAMStreamConfig, (LPVOID *)&src->pVSC); + if(hres != S_OK) + { + hres = src->capture_builder->FindInterface(&PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Video, src->video_cap_filter, + IID_IAMStreamConfig, (LPVOID *)&src->pVSC); + if (hres != S_OK) { + // this means we can't set frame rate (non-DV only) + GST_ERROR ("Error %x: Cannot find VCapture:IAMStreamConfig", hres); + goto error; + } + } + hres = src->filter_graph->AddFilter (src->dshow_fakesink, L"sink"); if (hres != S_OK) { GST_ERROR ("Can't add our fakesink filter to the graph (error=0x%x)", hres); @@ -657,9 +714,21 @@ error: src->media_filter->Release (); src->media_filter = NULL; } - if (src->filter_graph) { - src->filter_graph->Release (); - src->filter_graph = NULL; + if (src->graph_builder) { + src->graph_builder->Release (); + src->graph_builder = NULL; + } + if (src->capture_builder) { + src->capture_builder->Release (); + src->capture_builder = NULL; + } + if (src->pVC) { + src->pVC->Release (); + src->pVC = NULL; + } + if (src->pVSC) { + src->pVSC->Release (); + src->pVSC = NULL; } return FALSE; @@ -739,6 +808,7 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps) goto error; } + hres = src->filter_graph->ConnectDirect (pin_mediatype->capture_pin, input_pin, pin_mediatype->mediatype); input_pin->Release (); @@ -810,9 +880,29 @@ gst_dshowvideosrc_stop (GstBaseSrc * bsrc) src->media_filter->Release (); src->media_filter = NULL; - /* release the filter graph manager */ - src->filter_graph->Release (); - src->filter_graph = NULL; + /* release any upstream filter */ + if (src->pVC) { + src->pVC->Release (); + src->pVC = NULL; + } + + if (src->pVSC) { + src->pVSC->Release (); + src->pVSC = NULL; + } + +/* release the graph builder */ + if (src->graph_builder) { + src->graph_builder->Release (); + src->graph_builder = NULL; + src->filter_graph = NULL; + } + +/* release the capture builder */ + if (src->capture_builder) { + src->capture_builder->Release (); + src->capture_builder = NULL; + } /* reset caps */ if (src->caps) { diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.h b/sys/dshowsrcwrapper/gstdshowvideosrc.h index 747993509..9c0752846 100644 --- a/sys/dshowsrcwrapper/gstdshowvideosrc.h +++ b/sys/dshowsrcwrapper/gstdshowvideosrc.h @@ -72,6 +72,13 @@ struct _GstDshowVideoSrc IMediaFilter *media_filter; IFilterGraph *filter_graph; + IGraphBuilder *graph_builder; + ICaptureGraphBuilder2 *capture_builder; + IAMVideoCompression *pVC; + //IAMVfwCaptureDialogs *pDlg; + //IAMStreamConfig *pASC; // for audio cap + IAMStreamConfig *pVSC; // for video cap + /* the last buffer from DirectShow */ GCond *buffer_cond; GMutex *buffer_mutex; -- cgit v1.2.3