HRESULT GetPinCountForOneType(IUnknown* pUnk, PIN_DIRECTION direction, LPDWORD pPinCount) { (*pPinCount) = 0; IBaseFilter* pBaseFilter = NULL; HRESULT hr = pUnk->QueryInterface(IID_IBaseFilter, (VOID**)&pBaseFilter); if (SUCCEEDED(hr)) { IEnumPins* pEnumPins = NULL; hr = pBaseFilter->EnumPins(&pEnumPins); if (SUCCEEDED(hr)) { pEnumPins->Reset(); if (SUCCEEDED(hr)) { IPin* pPin = NULL; BOOL bFound = FALSE; DWORD dwFetched = 0; while (((pEnumPins->Next(1, &pPin, &dwFetched)) == S_OK) && !bFound) { PIN_DIRECTION fetchedDir; hr = pPin->QueryDirection(&fetchedDir); if (SUCCEEDED(hr) && (fetchedDir == direction)) { (*pPinCount)++; } pPin->Release(); } } pEnumPins->Release(); } pBaseFilter->Release(); } return hr; }
HRESULT GetAMConfigForSinglePin(IUnknown* pUnk, PIN_DIRECTION direction, IAMStreamConfig** ppConfig) { IBaseFilter* pBaseFilter = NULL; HRESULT hr = pUnk->QueryInterface(IID_IBaseFilter, (void**)&pBaseFilter); if (SUCCEEDED(hr)) { IEnumPins* pEnumPins = NULL; hr = pBaseFilter->EnumPins(&pEnumPins); if (SUCCEEDED(hr)) { pEnumPins->Reset(); if (SUCCEEDED(hr)) { IPin* pPin = NULL; BOOL bFound = FALSE; while (((pEnumPins->Next(1, &pPin, NULL)) == S_OK) && !bFound) { PIN_DIRECTION fetchedDir; hr = pPin->QueryDirection(&fetchedDir); if (SUCCEEDED(hr) && (fetchedDir == direction)) { hr = pPin->QueryInterface(IID_IAMStreamConfig, (void**)ppConfig); bFound = SUCCEEDED(hr); } pPin->Release(); } } pEnumPins->Release(); } pBaseFilter->Release(); } return hr; }
HRESULT FindSourceFilter(IFilterGraph* filterGraph,IBaseFilter*& result) { HRESULT hr; IEnumFilters *enumFilters; hr = filterGraph->EnumFilters(&enumFilters); if (FAILED(hr)) { ErrorPrint("Get enum filters error",hr); return hr; } ComReleaser enumFilterReleaser(enumFilters); IBaseFilter* filter; while (S_OK == enumFilters->Next(1, &filter, NULL)) { ComReleaser filterReleaser(filter); IEnumPins *enumPins; hr = filter->EnumPins(&enumPins); if (FAILED(hr)) { ErrorPrint("Get enum pins error",hr); return hr; } ComReleaser enumPinsReleaser(enumPins); IPin* pin; bool isSourceFilter = true; while (S_OK == enumPins->Next(1, &pin, NULL)) { ComReleaser pinReleaser(pin); PIN_INFO pinInfo; hr = pin->QueryPinInfo(&pinInfo); if (FAILED(hr)) { ErrorPrint("Get pin info error",hr); continue; } if (pinInfo.dir == PINDIR_INPUT) //认为没有输入pin的就是source filter,这其实是有些问题的,特别是当捕获(如声卡的音频)的filter有时候有很多输入PIN { isSourceFilter = false; break; } } if (isSourceFilter) { filter->AddRef(); //存在一个资源管理的释放类,必须增加一个引用,否则会被释放掉 result = filter; return S_OK; } } return E_FAIL; }
// Very basic setup of capture filter, we should do error checking bool DsCaptureFilter::initialize() { IBaseFilter* sourceFilter = NULL; IPin* sourcePin = NULL; HRESULT hr = CoInitialize(0); hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC,IID_IGraphBuilder, (void **)&graph); hr = graph->QueryInterface(IID_IMediaControl, (void **)&mediaControl); //sampler = new Sampler(0, &hr); IPin* renderPin = NULL; hr = this->FindPin(L"In", &renderPin); hr = graph->AddFilter((IBaseFilter*)this, L"Sampler"); if(strcmp(source, "cam") == 0) // Capture from camera { ICreateDevEnum* devs = NULL; hr = CoCreateInstance (CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &devs); IEnumMoniker* cams = NULL; hr = devs?devs->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &cams, 0):0; IMoniker* mon = NULL; hr = cams?cams->Next (1, &mon, 0):0; hr = mon?mon->BindToObject(0,0,IID_IBaseFilter, (void**)&sourceFilter):0; hr = graph->AddFilter(sourceFilter, L"Capture Source"); } else // Capture from AVI { WCHAR filename[256]; MultiByteToWideChar(0, 0, source, -1, filename, sizeof(filename)); hr = graph->AddSourceFilter(filename, L"File Source", &sourceFilter); hr = sourceFilter?sourceFilter->FindPin(L"Output", &sourcePin):0; hr = graph?graph->QueryInterface(IID_IMediaEvent, (void **)&mediaEvent):0; hr = graph?graph->QueryInterface(IID_IMediaSeeking, (void **)&mediaSeek):0; } IEnumPins* pins = NULL; hr = sourceFilter?sourceFilter->EnumPins(&pins):0; hr = pins?pins->Next(1,&sourcePin, 0):0; hr = graph->Connect(sourcePin, renderPin); newFrameEvent = CreateEvent(0, FALSE, FALSE, "NewFrameEvent"); return true; }
Camera::Camera(bool Show,bool Start) : eHandler(this),_realData(false),_UpdateWindow(Show),_LastData(0),_CurData(0) { DWORD no; IGraphBuilder *graph = 0; ctrl = 0; ICreateDevEnum *devs = 0; IEnumMoniker *cams = 0; IMoniker *mon = 0; IBaseFilter *cam = 0; IEnumPins *pins = 0; IPin *pin = 0; IEnumFilters *fil = 0; IBaseFilter *rnd = 0; IMemInputPin *mem = 0; curCamera = this; _isOn = Start; CoCreateInstance( CLSID_FilterGraph, 0, CLSCTX_INPROC,IID_IGraphBuilder, (void **)&graph ); graph->QueryInterface( IID_IMediaControl, (void **)&ctrl ); CoCreateInstance (CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &devs); devs->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &cams, 0); cams->Next (1,&mon,0); // get first found capture device (webcam) mon->BindToObject(0,0,IID_IBaseFilter, (void**)&cam); graph->AddFilter(cam, L"Capture Source"); // add web cam to graph as source cam->EnumPins(&pins); // we need output pin to autogenerate rest of the graph pins->Next(1,&pin, 0); // via graph->Render graph->Render(pin); // graph builder now builds whole filter chain including MJPG decompression on some webcams graph->EnumFilters(&fil); // from all newly added filters fil->Next(1,&rnd,0); // we find last one (renderer) rnd->EnumPins(&pins); // because data we are intersted in are pumped to renderers input pin pins->Next(1,&pin, 0); // via Receive member of IMemInputPin interface pin->QueryInterface(IID_IMemInputPin,(void**)&mem); DsHook(mem,6,Receive); // so we redirect it to our own proc to grab image data if (Start) this->Start(); }
HRESULT CTMReceiverGraph::Destroy() { HRESULT hr = S_OK; m_pMediaEvent = NULL; m_pMeidaSeeking = NULL; m_pRecordStream = NULL; m_pSetCallBack = NULL; m_pVideoWindow = NULL; m_pBasicVideo = NULL; if(m_pGraphBuilder && m_pMediaControl) { m_pMediaControl->Stop(); CComPtr<IEnumFilters> pEnum = NULL; hr = m_pGraphBuilder->EnumFilters(&pEnum); if(SUCCEEDED(hr)) { IBaseFilter *pFilter = NULL; while(S_OK == pEnum->Next(1, &pFilter, NULL)) { FILTER_INFO filterInfo; if(SUCCEEDED(pFilter->QueryFilterInfo(&filterInfo))) { SAFE_RELEASE(filterInfo.pGraph); CComPtr<IEnumPins> pIEnumPins = NULL; hr = pFilter->EnumPins(&pIEnumPins); if(SUCCEEDED(hr)) { IPin *pIPin = NULL; while(S_OK == pIEnumPins->Next(1, &pIPin, NULL)) { m_pGraphBuilder->Disconnect(pIPin); SAFE_RELEASE(pIPin); } } } SAFE_RELEASE(pFilter); } } } else { hr = S_FALSE; } return hr; }
// // Does not AddRef the returned *Pin // HRESULT CCrossbar::GetCrossbarIPinAtIndex( IAMCrossbar *pXbar, LONG PinIndex, BOOL IsInputPin, IPin ** ppPin) { LONG cntInPins, cntOutPins; IPin *pP = 0; IBaseFilter *pFilter = NULL; IEnumPins *pins=0; ULONG n; HRESULT hr; if (!pXbar || !ppPin) return E_POINTER; *ppPin = 0; if(S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins)) return E_FAIL; LONG TrueIndex = IsInputPin ? PinIndex : PinIndex + cntInPins; hr = pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter); if (hr == S_OK) { if(SUCCEEDED(pFilter->EnumPins(&pins))) { LONG i=0; while(pins->Next(1, &pP, &n) == S_OK) { pP->Release(); if (i == TrueIndex) { *ppPin = pP; break; } i++; } pins->Release(); } pFilter->Release(); } return *ppPin ? S_OK : E_FAIL; }
// // Find corresponding index of an IPin on a crossbar // HRESULT CCrossbar::GetCrossbarIndexFromIPin ( IAMCrossbar * pXbar, LONG * PinIndex, BOOL IsInputPin, IPin * pPin) { LONG cntInPins, cntOutPins; IPin *pP = 0; IBaseFilter *pFilter = NULL; IEnumPins *pins = 0; ULONG n; BOOL fOK = FALSE; HRESULT hr; if (!pXbar || !PinIndex || !pPin) return E_POINTER; if(S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins)) return E_FAIL; hr = pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter); if (hr == S_OK) { if(SUCCEEDED(pFilter->EnumPins(&pins))) { LONG i=0; while(pins->Next(1, &pP, &n) == S_OK) { pP->Release(); if (pPin == pP) { *PinIndex = IsInputPin ? i : i - cntInPins; fOK = TRUE; break; } i++; } pins->Release(); } pFilter->Release(); } return fOK ? S_OK : E_FAIL; }
HRESULT GetAMConfigForMultiPin(IUnknown* pUnk, PIN_DIRECTION direct, IAMStreamConfig** ppConfig) { IBaseFilter* pBaseFilter = NULL; HRESULT hr = pUnk->QueryInterface(IID_IBaseFilter, (void**)&pBaseFilter); if (SUCCEEDED(hr)) { IEnumPins* pEnumPins = NULL; hr = pBaseFilter->EnumPins(&pEnumPins); if (SUCCEEDED(hr)) { pEnumPins->Reset(); if (SUCCEEDED(hr)) { IPin* pPin = NULL; BOOL bFound = FALSE; while ((pEnumPins->Next(1, &pPin, NULL) == S_OK) && !bFound) { PIN_DIRECTION fetchedDir; hr = pPin->QueryDirection(&fetchedDir); if (SUCCEEDED(hr) && (fetchedDir == direct)) { IKsPropertySet* pPS; hr = pPin->QueryInterface(IID_IKsPropertySet, (void**)&pPS); if (SUCCEEDED(hr)) { GUID guid = { 0 }; DWORD dwReturn = 0; hr = pPS->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, 0, 0, &guid, sizeof(guid), &dwReturn); if (SUCCEEDED(hr) && ::IsEqualGUID(guid, PIN_CATEGORY_CAPTURE)) { hr = pPin->QueryInterface(IID_IAMStreamConfig, (void**)ppConfig); bFound = SUCCEEDED(hr); } pPS->Release(); } } pPin->Release(); } } pEnumPins->Release(); } pBaseFilter->Release(); } return hr; }
//----------------------------------------------------------------------------- // DisconnectAllPins // Disconnect all the pins of the filters in a graph HRESULT CDSUtils::DisconnectAllPins(IGraphBuilder* pGraph) { HRESULT hr = S_OK; if (pGraph) { CComPtr<IEnumFilters> pIEnumFilters = NULL; hr = pGraph->EnumFilters(&pIEnumFilters); if (SUCCEEDED(hr)) { IBaseFilter* pFilter = NULL; while (S_OK == pIEnumFilters->Next(1, &pFilter, NULL)) { CComPtr<IEnumPins> pIEnumPins = NULL; hr = pFilter->EnumPins(&pIEnumPins); if (SUCCEEDED(hr)) { IPin* pIPin = NULL; while (S_OK == pIEnumPins->Next(1, &pIPin, NULL)) { IPin* pIPinConnection = NULL; if (S_OK == pIPin->ConnectedTo(&pIPinConnection)) { // pins are connected, to disconnect filters, both pins must be disconnected hr = pGraph->Disconnect(pIPin); hr = pGraph->Disconnect(pIPinConnection); SAFE_RELEASE(pIPinConnection); } SAFE_RELEASE(pIPin); } } SAFE_RELEASE(pFilter); } } } else { hr = E_INVALIDARG; } return hr; }
int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const { QVarLengthArray<IBaseFilter *, 16> filters; source->AddRef(); filters.append(source); int streamTypes = 0; while (!filters.isEmpty()) { IEnumPins *pins = 0; IBaseFilter *filter = filters[filters.size() - 1]; filters.removeLast(); if (SUCCEEDED(filter->EnumPins(&pins))) { for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { PIN_DIRECTION direction; if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { AM_MEDIA_TYPE connectionType; if (SUCCEEDED(pin->ConnectionMediaType(&connectionType))) { IPin *peer = 0; if (connectionType.majortype == MEDIATYPE_Audio) { streamTypes |= AudioStream; } else if (connectionType.majortype == MEDIATYPE_Video) { streamTypes |= VideoStream; } else if (SUCCEEDED(pin->ConnectedTo(&peer))) { PIN_INFO peerInfo; if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) filters.append(peerInfo.pFilter); peer->Release(); } } else { streamTypes |= findStreamType(pin); } } } } filter->Release(); } return streamTypes; }
int _tmain(int argc, _TCHAR* argv[]) { int y; cin>>y; // IGraphBuilder* locGraphBuilder = NULL; IMediaControl* locMediaControl = NULL; IBaseFilter* locDemuxer = NULL; ICustomSource* locCustomSourceSetter = NULL; HRESULT locHR = S_FALSE;; CoInitialize(NULL); locHR = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&locGraphBuilder); locHR = CoCreateInstance(CLSID_OggDemuxPacketSourceFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&locDemuxer); locGraphBuilder->AddFilter(locDemuxer, L"Custom Ogg Source"); locDemuxer->QueryInterface(IID_ICustomSource, (void**)&locCustomSourceSetter); CustomSourceClass* locCustomFileSourceInterface = new CustomSourceClass; locCustomFileSourceInterface->open("D:\\testfile.ogg"); locCustomSourceSetter->setCustomSourceAndLoad(locCustomFileSourceInterface); //Do not release, it's not really a COM interface //locCustomSourceSetter->Release(); IEnumPins* locPinEnum = NULL; locDemuxer->EnumPins(&locPinEnum); IPin* locPin = NULL; ULONG locHowMany = 0; while (locPinEnum->Next(1, &locPin, &locHowMany) == S_OK) { locHR = locGraphBuilder->Render(locPin); locPin->Release(); locPin = NULL; } //locHR = locGraphBuilder->RenderFile(L"g:\\a.ogg", NULL); locHR = locGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&locMediaControl); locHR = locMediaControl->Run(); IMediaEvent* locMediaEvent = NULL; locHR = locGraphBuilder->QueryInterface(IID_IMediaEvent, (void**)&locMediaEvent); HANDLE hEvent; long evCode, param1, param2; BOOLEAN bDone = FALSE; HRESULT hr = S_OK; hr = locMediaEvent->GetEventHandle((OAEVENT*)&hEvent); if (FAILED(hr)) { /* Insert failure-handling code here. */ } while(!bDone) { if (WAIT_OBJECT_0 == WaitForSingleObject(hEvent, 100)) { while (hr = locMediaEvent->GetEvent(&evCode, ¶m1, ¶m2, 0), SUCCEEDED(hr)) { //printf("Event code: %#04x\n Params: %d, %d\n", evCode, param1, param2); cout<<"Event : "<<evCode<<" Params : "<<param1<<", "<<param2<<endl; locMediaEvent->FreeEventParams(evCode, param1, param2); bDone = (EC_COMPLETE == evCode); } } } cout<<"Finished..."<<endl; int x; cin>>x; locMediaControl->Release(); locGraphBuilder->Release(); CoUninitialize(); return 0; }
void gui::dx::audio_playerX::initialize_speedup_filter() { if (speedup_filter_available_valid && !speedup_filter_available) { // We don't seem to have the filter. Too bad. return; } // Either the filter exists or we haven't tried yet. Let's try to create // it and remember whether it worked. IBaseFilter *pNewFilter = NULL; HRESULT res; res = CoCreateInstance(CLSID_TPBVupp69, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNewFilter); if (res != S_OK) { traceX("dx_audio_player: Speedup filter not available, error 0x%x", res); speedup_filter_available = false; speedup_filter_available_valid = true; return; } res = m_graph_builder->AddFilter(pNewFilter, NULL); if (res != S_OK) { traceX("dx_audio_player: AddFilter(Speedup filter): error 0x%x", res); pNewFilter->Release(); return; } speedup_filter_available = true; speedup_filter_available_valid = true; // AM_DBG lib::debugX("dx_audio_player: added speedup filter to graph"); // Next step: find out where we want to add the filter to the graph. // We iterate over the filter graph, then for each item in the graph // we iterate over the connected output pins util we find one we like. IPin *pOutputPin = NULL; IPin *pInputPin = NULL; IEnumFilters *pEnumFilters = NULL; res = m_graph_builder->EnumFilters(&pEnumFilters); if (res != S_OK) { traceX("dx_audio_filter: EnumFilters: error 0x%x", res); return; } IBaseFilter *pCurFilter; while (pOutputPin == NULL && (res=pEnumFilters->Next(1, &pCurFilter, NULL)) == S_OK) { AM_DBG { FILTER_INFO info; LPWSTR vendorInfo; res = pCurFilter->QueryFilterInfo(&info); if (res != S_OK) info.achName[0] = 0; res = pCurFilter->QueryVendorInfo(&vendorInfo); if (res != S_OK) vendorInfo = L""; //ambulant::lib::textptr tInfo(info.achName); //ambulant::lib::textptr tVendorInfo(vendorInfo); //lib::debugX("dx_audio_filter: filter found: '%s' vendor '%s'", tInfo.c_str(), tVendorInfo.c_str()); } IEnumPins *pEnumPins; res = pCurFilter->EnumPins(&pEnumPins); IPin *pCurPin; while (pOutputPin == NULL && (res=pEnumPins->Next(1, &pCurPin, NULL)) == S_OK) { AM_MEDIA_TYPE mediaType; PIN_DIRECTION curPinDir; res = pCurPin->QueryDirection(&curPinDir); HRESULT res2 = pCurPin->ConnectionMediaType(&mediaType); if (res == S_OK && res2 == S_OK && curPinDir == PINDIR_OUTPUT && mediaType.majortype == MEDIATYPE_Audio&& mediaType.subtype == MEDIASUBTYPE_PCM){ pOutputPin = pCurPin; res = pOutputPin->ConnectedTo(&pInputPin); if (res != S_OK) { // This output pin was the correct type, but not connected. // So it cannot be the one we're looking for. pOutputPin = pInputPin = NULL; } else { // Found it! pOutputPin->AddRef(); pInputPin->AddRef(); } } if (res2 == S_OK) { if (mediaType.cbFormat != 0) { CoTaskMemFree((PVOID)mediaType.pbFormat); } } pCurPin->Release(); } if (res != S_FALSE && res != S_OK) traceX("dx_audio_filter: enumerating pins: error 0x%x", res); pEnumPins->Release(); pCurFilter->Release(); } if (res != S_FALSE && res != S_OK) traceX("dx_audio_filter: enumerating filters: error 0x%x", res); pEnumFilters->Release(); // We have the correct pins now. if (pOutputPin) { traceX("dx_audio_filter: found the right pins!"); } else { traceX("dx_audio_filter: could not find a good pin"); pOutputPin->Release(); pInputPin->Release(); return; } // Now we need to find the pins on our speedup filter. IPin *pFilterInputPin = NULL; IPin *pFilterOutputPin = NULL; IEnumPins *pEnumPins; res = pNewFilter->EnumPins(&pEnumPins); IPin *pCurPin; while (res=pEnumPins->Next(1, &pCurPin, NULL) == S_OK) { PIN_DIRECTION pinDir; res = pCurPin->QueryDirection(&pinDir); //assert(res == S_OK); if (pinDir == PINDIR_INPUT) { if (pFilterInputPin) { traceX("dx_audio_filter: multiple input pins on filter"); goto bad; } pFilterInputPin = pCurPin; pFilterInputPin->AddRef(); } else { if (pFilterOutputPin) { traceX("dx_audio_filter: multiple output pins on filter"); goto bad; } pFilterOutputPin = pCurPin; pFilterOutputPin->AddRef(); } } if (!pFilterInputPin) { traceX("dx_audio_filter: no input pin on filter"); goto bad; } if (!pFilterOutputPin) { traceX("dx_audio_filter: no output pin on filter"); goto bad; } // We have everything. Sever the old connection and insert the filter. res = m_graph_builder->Disconnect(pOutputPin); if (res) { traceX("dx_audio_filter: Severing old connection: error 0x%x", res); goto bad; } res = m_graph_builder->Disconnect(pInputPin); if (res) { traceX("dx_audio_filter: Severing old connection: error 0x%x", res); goto bad; } res = m_graph_builder->Connect(pOutputPin, pFilterInputPin); if (res) { traceX("dx_audio_filter: Creating filter input connection: error 0x%x", res); goto bad; } res = m_graph_builder->Connect(pFilterOutputPin, pInputPin); if (res) { traceX("dx_audio_filter: Creating filter output connection: error 0x%x", res); goto bad; } // Finally remember the interface to set speedup/slowdown, and register ourselves // in the global pool (so Amis can change our speed). res = pNewFilter->QueryInterface(IID_IVuppInterface, (void**) &m_audio_speedup); if (res != S_OK) { traceX("dx_audio_filter: filter does not provide IVuppInterface"); goto bad; } set_rate(s_current_playback_rate); bad: if (pOutputPin) pOutputPin->Release(); if (pInputPin) pInputPin->Release(); if (pFilterOutputPin) pFilterOutputPin->Release(); if (pFilterInputPin) pFilterInputPin->Release(); return; }
void DirectShowPlayerService::doRender(QMutexLocker *locker) { m_pendingTasks |= m_executedTasks & (Play | Pause); if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { control->Stop(); control->Release(); } if (m_pendingTasks & SetAudioOutput) { m_graph->AddFilter(m_audioOutput, L"AudioOutput"); m_pendingTasks ^= SetAudioOutput; m_executedTasks |= SetAudioOutput; } if (m_pendingTasks & SetVideoOutput) { m_graph->AddFilter(m_videoOutput, L"VideoOutput"); m_pendingTasks ^= SetVideoOutput; m_executedTasks |= SetVideoOutput; } IFilterGraph2 *graph = m_graph; graph->AddRef(); QVarLengthArray<IBaseFilter *, 16> filters; m_source->AddRef(); filters.append(m_source); bool rendered = false; HRESULT renderHr = S_OK; while (!filters.isEmpty()) { IEnumPins *pins = 0; IBaseFilter *filter = filters[filters.size() - 1]; filters.removeLast(); if (!(m_pendingTasks & ReleaseFilters) && SUCCEEDED(filter->EnumPins(&pins))) { int outputs = 0; for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { PIN_DIRECTION direction; if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { ++outputs; IPin *peer = 0; if (pin->ConnectedTo(&peer) == S_OK) { PIN_INFO peerInfo; if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) filters.append(peerInfo.pFilter); peer->Release(); } else { locker->unlock(); HRESULT hr; if (SUCCEEDED(hr = graph->RenderEx( pin, /*AM_RENDEREX_RENDERTOEXISTINGRENDERERS*/ 1, 0))) { rendered = true; } else if (renderHr == S_OK || renderHr == VFW_E_NO_DECOMPRESSOR){ renderHr = hr; } locker->relock(); } } } pins->Release(); if (outputs == 0) rendered = true; } filter->Release(); } if (m_audioOutput && !isConnected(m_audioOutput, PINDIR_INPUT)) { graph->RemoveFilter(m_audioOutput); m_executedTasks &= ~SetAudioOutput; } if (m_videoOutput && !isConnected(m_videoOutput, PINDIR_INPUT)) { graph->RemoveFilter(m_videoOutput); m_executedTasks &= ~SetVideoOutput; } graph->Release(); if (!(m_pendingTasks & ReleaseFilters)) { if (rendered) { if (!(m_executedTasks & FinalizeLoad)) m_pendingTasks |= FinalizeLoad; } else { m_pendingTasks = 0; m_graphStatus = InvalidMedia; if (!m_audioOutput && !m_videoOutput) { m_error = QMediaPlayer::ResourceError; m_errorString = QString(); } else { switch (renderHr) { case VFW_E_UNSUPPORTED_AUDIO: case VFW_E_UNSUPPORTED_VIDEO: case VFW_E_UNSUPPORTED_STREAM: m_error = QMediaPlayer::FormatError; m_errorString = QString(); break; default: m_error = QMediaPlayer::ResourceError; m_errorString = QString(); qWarning("DirectShowPlayerService::doRender: Unresolved error code %x", uint(renderHr)); } } QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); } m_executedTasks |= Render; } m_loop->wake(); }
/* * Class: sage_DShowMediaPlayer * Method: getColorKey0 * Signature: (J)Ljava/awt/Color; */ JNIEXPORT jobject JNICALL Java_sage_DShowMediaPlayer_getColorKey0 (JNIEnv *env, jobject jo, jlong dataPtr) { if (!dataPtr) return 0; CPlayerData* playData = (CPlayerData*) dataPtr; IGraphBuilder* pGraph = playData->GetGraph(); if (!pGraph) return 0; BOOL forceColorKey = FALSE; HRESULT hr; DWORD holder; HKEY myKey; DWORD readType; DWORD hsize = sizeof(holder); DWORD keyedColor = RGB(1,1,1); if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Frey Technologies\\Common\\DirectShow", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &myKey, 0) == ERROR_SUCCESS) { if (RegQueryValueEx(myKey, "TransparentColorKey", 0, &readType, (LPBYTE) &holder, &hsize) == ERROR_SUCCESS) { keyedColor = holder; forceColorKey = TRUE; } RegCloseKey(myKey); } COLORKEY overlayKey; overlayKey.KeyType = CK_RGB; overlayKey.PaletteIndex = 0; overlayKey.LowColorValue = keyedColor; overlayKey.HighColorValue = keyedColor; COLORKEY defaultKey; BOOL overlayIsUsed = FALSE; IEnumFilters *pEnum = NULL; if (!forceColorKey) { // Find the default color key hr = pGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *currFilt = NULL; while (pEnum->Next(1, &currFilt, NULL) == S_OK) { IPin *overlayPin = NULL; IEnumPins* pPinEnum = NULL; hr = currFilt->EnumPins(&pPinEnum); if (hr == NO_ERROR) { IPin *pPin = NULL; hr = E_FAIL; while(S_OK == pPinEnum->Next(1, &pPin, NULL)) { IOverlay *pOverlayPin = NULL; hr = pPin->QueryInterface(IID_IOverlay, (void**)&pOverlayPin); if (SUCCEEDED(hr)) { hr = pOverlayPin->GetDefaultColorKey(&defaultKey); if (!forceColorKey && SUCCEEDED(hr)) { keyedColor = defaultKey.LowColorValue; slog((env, "Got the default color key 0x%x\r\n", keyedColor)); //forceColorKey = TRUE; } SAFE_RELEASE(pOverlayPin); } SAFE_RELEASE(pPin); } SAFE_RELEASE(pPinEnum); } SAFE_RELEASE(currFilt); } SAFE_RELEASE(pEnum); } } pEnum = NULL; // Set the color key value hr = pGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *currFilt = NULL; while (pEnum->Next(1, &currFilt, NULL) == S_OK) { IPin *overlayPin = NULL; IEnumPins* pPinEnum = NULL; currFilt->EnumPins(&pPinEnum); while (pPinEnum->Next(1, &overlayPin, NULL) == S_OK) { // let's see if it's overlay IMixerPinConfig *pOverlayMix = NULL; hr = overlayPin->QueryInterface(IID_IMixerPinConfig, (void**)&pOverlayMix); if (SUCCEEDED(hr)) { if (!forceColorKey) keyedColor = overlayKey.LowColorValue; else overlayKey.LowColorValue = overlayKey.HighColorValue = keyedColor; IPin* testPin = NULL; overlayPin->ConnectedTo(&testPin); BOOL currPinUsed = FALSE; if (testPin) { currPinUsed = TRUE; SAFE_RELEASE(testPin); } if (currPinUsed) { if (forceColorKey) { slog((env, "Setting the color key to 0x%x\r\n", keyedColor)); hr = pOverlayMix->SetColorKey(&overlayKey); } else { hr = pOverlayMix->GetColorKey(&defaultKey, &keyedColor); slog((env, "Got the default overlay color key of 0x%x\r\n", keyedColor)); } // HTESTPRINT(hr); if (!overlayIsUsed) { // Force the color key on all connected mixer pins to match overlayIsUsed = TRUE; forceColorKey = TRUE; } } SAFE_RELEASE(pOverlayMix); } SAFE_RELEASE(overlayPin); } SAFE_RELEASE(pPinEnum); SAFE_RELEASE(currFilt); } SAFE_RELEASE(pEnum); } static jclass colorClass = (jclass) env->NewGlobalRef(env->FindClass("java/awt/Color")); static jmethodID constMeth = env->GetMethodID(colorClass, "<init>", "(I)V"); // Set the alpha to be 255 for the color. keyedColor = keyedColor | 0xFF000000; slog((env, "Returning the color key as 0x%x\r\n", keyedColor)); return env->NewObject(colorClass, constMeth, keyedColor); }
QVector<VideoMode> DirectShow::getDeviceModes(QString devName) { QVector<VideoMode> modes; IBaseFilter* devFilter = getDevFilter(devName); if (!devFilter) return modes; // The outter loop tries to find a valid output pin GUID category; DWORD r2; IEnumPins *pins = nullptr; IPin *pin; if (devFilter->EnumPins(&pins) != S_OK) return modes; while (pins->Next(1, &pin, nullptr) == S_OK) { IKsPropertySet *p = nullptr; PIN_INFO info; pin->QueryPinInfo(&info); info.pFilter->Release(); if (info.dir != PINDIR_OUTPUT) goto next; if (pin->QueryInterface(IID_IKsPropertySet, (void**)&p) != S_OK) goto next; if (p->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, nullptr, 0, &category, sizeof(GUID), &r2) != S_OK) goto next; if (!IsEqualGUID(category, PIN_CATEGORY_CAPTURE)) goto next; // Now we can list the video modes for the current pin // Prepare for another wall of spaghetti DIRECT SHOW QUALITY code { IAMStreamConfig *config = nullptr; VIDEO_STREAM_CONFIG_CAPS *vcaps = nullptr; int size, n; if (pin->QueryInterface(IID_IAMStreamConfig, (void**)&config) != S_OK) goto next; if (config->GetNumberOfCapabilities(&n, &size) != S_OK) goto pinend; assert(size == sizeof(VIDEO_STREAM_CONFIG_CAPS)); vcaps = new VIDEO_STREAM_CONFIG_CAPS; for (int i=0; i<n; ++i) { AM_MEDIA_TYPE* type = nullptr; if (config->GetStreamCaps(i, &type, (BYTE*)vcaps) != S_OK) goto nextformat; if (!IsEqualGUID(type->formattype, FORMAT_VideoInfo) && !IsEqualGUID(type->formattype, FORMAT_VideoInfo2)) goto nextformat; VideoMode mode; mode.width = vcaps->MaxOutputSize.cx; mode.height = vcaps->MaxOutputSize.cy; mode.FPS = 1e7 / vcaps->MinFrameInterval; if (!modes.contains(mode)) modes.append(std::move(mode)); nextformat: if (type->pbFormat) CoTaskMemFree(type->pbFormat); CoTaskMemFree(type); } pinend: config->Release(); delete vcaps; } next: if (p) p->Release(); pin->Release(); } return modes; }
HRESULT CAudioCompressorFormats::GetSupportedFormats(std::vector<WAVEFORMATEX*>& listFormats) { CStringW swDeviceName(m_sAudComp); HRESULT hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_AudioCompressorCategory, &m_pEnumCat, 0); if(NULL == m_pEnumCat) return E_POINTER; if(S_OK == hr) { ULONG cFetched; while(m_pEnumCat->Next(1, &m_pMoniker, &cFetched) == S_OK) { IPropertyBag *pPropBag; hr = m_pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); if (SUCCEEDED(hr)) { VARIANT varName; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, 0); if (SUCCEEDED(hr)) { if(wcscmp((WCHAR*)varName.pbstrVal, swDeviceName.GetBuffer()) == 0) { m_pMoniker->AddRef(); break; } } VariantClear(&varName); pPropBag->Release(); } m_pMoniker->Release(); } } if(m_pMoniker) { IBaseFilter *pFilter = 0; hr = m_pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pFilter); if(SUCCEEDED(hr)) { IEnumPins *pEnum = NULL; hr = pFilter->EnumPins(&pEnum); if (SUCCEEDED(hr)) { IPin *pPin = NULL; while(S_OK == pEnum->Next(1, &pPin, NULL)) { IAMStreamConfig *pConf; hr = pPin->QueryInterface(IID_IAMStreamConfig, (void**)&pConf); if (SUCCEEDED(hr)) { CString sFormat; int iCount, iSize; BYTE *pSCC = NULL; AM_MEDIA_TYPE *pmt; float fSample; hr = pConf->GetNumberOfCapabilities(&iCount, &iSize); pSCC = new BYTE[iSize]; if (pSCC == NULL) { return E_POINTER; } if (iSize == sizeof(AUDIO_STREAM_CONFIG_CAPS)) { // Use the audio capabilities structure. for (int iFormat = 0; iFormat < iCount; iFormat++) { AUDIO_STREAM_CONFIG_CAPS scc; AM_MEDIA_TYPE *pmtConfig; hr = pConf->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc); if (SUCCEEDED(hr)) { if(pmtConfig->formattype == FORMAT_WaveFormatEx) { WAVEFORMATEX *pFormat = new WAVEFORMATEX(*(reinterpret_cast<WAVEFORMATEX*>(pmtConfig->pbFormat))); if(pFormat) { listFormats.push_back(pFormat); } FreeMediaType(*pmtConfig); CoTaskMemFree(pmtConfig); } } } delete pSCC; } pConf->Release(); } pPin->Release(); } pEnum->Release(); } pFilter->Release(); } } }
void TestCamera() { InitOpenCL(); //TCHAR szDeviceName[80]; //TCHAR szDeviceVersion[80]; //for (int wIndex = 0; wIndex < 10; wIndex++) //{ // if (capGetDriverDescription( // wIndex, // szDeviceName, // sizeof (szDeviceName), // szDeviceVersion, // sizeof (szDeviceVersion) // )) // { // // Append name to list of installed capture drivers // // and then let the user select a driver to use. // } //} //HWND hWndC = capCreateCaptureWindow(TEXT("PunkCapture"), // WS_CHILD | WS_VISIBLE, 0, 0, 160, 120, *System::Window::Instance(), 1); //SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0, 0L); //// //// Or, use the macro to connect to the MSVIDEO driver: //// fOK = capDriverConnect(hWndC, 0); //// //// Place code to set up and capture video here. //// ////capDriverDisconnect (hWndC); //CAPDRIVERCAPS CapDriverCaps = { }; //CAPSTATUS CapStatus = { }; //capDriverGetCaps(hWndC, &CapDriverCaps, sizeof(CAPDRIVERCAPS)); //// Video source dialog box. //if (CapDriverCaps.fHasDlgVideoSource) //{ // capDlgVideoSource(hWndC); //} //// Video format dialog box. //if (CapDriverCaps.fHasDlgVideoFormat) //{ // capDlgVideoFormat(hWndC); // // Are there new image dimensions? // capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS)); // // If so, notify the parent of a size change. //} //// Video display dialog box. //if (CapDriverCaps.fHasDlgVideoDisplay) //{ // capDlgVideoDisplay(hWndC); //} HRESULT hr; IGraphBuilder* graph= 0; hr = CoCreateInstance( CLSID_FilterGraph, 0, CLSCTX_INPROC,IID_IGraphBuilder, (void **)&graph ); IMediaControl* ctrl = 0; hr = graph->QueryInterface( IID_IMediaControl, (void **)&ctrl ); ICreateDevEnum* devs = 0; hr = CoCreateInstance (CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &devs); IEnumMoniker* cams = 0; hr = devs?devs->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &cams, 0):0; IMoniker* mon = 0; hr = cams->Next (1,&mon,0); // get first found capture device (webcam?) IBaseFilter* cam = 0; hr = mon->BindToObject(0,0,IID_IBaseFilter, (void**)&cam); hr = graph->AddFilter(cam, L"Capture Source"); // add web cam to graph as source IEnumPins* pins = 0; hr = cam?cam->EnumPins(&pins):0; // we need output pin to autogenerate rest of the graph IPin* pin = 0; hr = pins?pins->Next(1,&pin, 0):0; // via graph->Render hr = graph->Render(pin); // graph builder now builds whole filter chain including MJPG decompression on some webcams IEnumFilters* fil = 0; hr = graph->EnumFilters(&fil); // from all newly added filters IBaseFilter* rnd = 0; hr = fil->Next(1,&rnd,0); // we find last one (renderer) hr = rnd->EnumPins(&pins); // because data we are intersted in are pumped to renderers input pin hr = pins->Next(1,&pin, 0); // via Receive member of IMemInputPin interface IMemInputPin* mem = 0; hr = pin->QueryInterface(IID_IMemInputPin,(void**)&mem); DsHook(mem,6,Receive); // so we redirect it to our own proc to grab image data hr = ctrl->Run(); };
HRESULT CWavPackDSSplitter::TryToLoadCorrectionFile() { // Here is the nasty hacky stuff :> HRESULT hr = S_FALSE; IPin *pPinOutSrc = NULL; IFileSourceFilter *pFSF = NULL; LPOLESTR pszFileName = NULL; IBaseFilter* pSrcFilterCorr = NULL; IFileSourceFilter* pFSFCorr = NULL; IEnumPins *pEnum = NULL; IPin *pPinNew = NULL; BOOL bCorrectionFileLoaded = FALSE; IEnumFilters* pEnumFilers = NULL; BOOL bSrcFileAlreadyLoaded = FALSE; DebugLog("===> Entering CWavPackDSSplitter::TryToLoadCorrectionFile... 0x%08X", GetCurrentThreadId()); if((m_bDontTryToLoadCorrectionFileAgain == TRUE) || (m_pInputPinCorr == NULL) || (m_pInputPinCorr->IsConnected() == TRUE)) { DebugLog("<=== Leaving CWavPackDSSplitter::TryToLoadCorrectionFile already loaded ?... 0x%08X", GetCurrentThreadId()); return hr; } if((m_pInputPin->m_pWavPackParser->first_wphdr.flags & HYBRID_FLAG) != HYBRID_FLAG) { // Not an hybrid file, don't even try m_bDontTryToLoadCorrectionFileAgain = TRUE; DebugLog("<=== Leaving CWavPackDSSplitter::TryToLoadCorrectionFile not hybrid... 0x%08X", GetCurrentThreadId()); return hr; } #define IF_FAIL_BREAK(x) if(FAILED(x)) { break; } do { hr = m_pInputPin->ConnectedTo(&pPinOutSrc); IF_FAIL_BREAK(hr); // Get a pointer on the source filter PIN_INFO pi; pi.pFilter = NULL; hr = pPinOutSrc->QueryPinInfo(&pi); IF_FAIL_BREAK(hr); // Get source filter IFileSourceFilter interface hr = pi.pFilter->QueryInterface(IID_IFileSourceFilter, (void **)&pFSF); IF_FAIL_BREAK(hr); // Get filename hr = pFSF->GetCurFile(&pszFileName, NULL); IF_FAIL_BREAK(hr); // Create correction file filename WCHAR pszFileNameC[MAX_PATH]; ZeroMemory(pszFileNameC, sizeof(WCHAR)*MAX_PATH); int cch = lstrlenW(pszFileName); CopyMemory(pszFileNameC, pszFileName, cch*sizeof(WCHAR)); pszFileNameC[cch] = 'c'; IFilterGraph* pFG = GetFilterGraph(); // Search in the graph in case the source filter with correction file already exist hr = pFG->EnumFilters(&pEnumFilers); IF_FAIL_BREAK(hr); while(pEnumFilers->Next(1, &pSrcFilterCorr, 0) == S_OK) { HRESULT lhr; lhr = pSrcFilterCorr->QueryInterface(IID_IFileSourceFilter, (void**)&pFSFCorr); if(SUCCEEDED(lhr)) { LPOLESTR pszFileNameCandidate = NULL; pFSFCorr->GetCurFile(&pszFileNameCandidate, NULL); if(memcmp(pszFileNameCandidate,pszFileNameC,(cch+1)*sizeof(WCHAR)) == 0) { // This is the good file bSrcFileAlreadyLoaded = TRUE; if(pszFileNameCandidate != NULL) { CoTaskMemFree(pszFileNameCandidate); } break; } if(pszFileNameCandidate != NULL) { CoTaskMemFree(pszFileNameCandidate); } } pSrcFilterCorr->Release(); pSrcFilterCorr = NULL; } if(bSrcFileAlreadyLoaded == FALSE) { // Create new file source filter hr = CoCreateInstance(CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSrcFilterCorr); IF_FAIL_BREAK(hr); hr = pFG->AddFilter(pSrcFilterCorr, pszFileNameC); IF_FAIL_BREAK(hr); hr = pSrcFilterCorr->QueryInterface(IID_IFileSourceFilter, (void**)&pFSFCorr); IF_FAIL_BREAK(hr); hr = pFSFCorr->Load(pszFileNameC, NULL); IF_FAIL_BREAK(hr); } // Get first pin and connect it hr = pSrcFilterCorr->EnumPins(&pEnum); IF_FAIL_BREAK(hr); if(pEnum->Next(1, &pPinNew, 0) == S_OK) { hr = pFG->ConnectDirect(pPinNew, m_pInputPinCorr, NULL); bCorrectionFileLoaded = SUCCEEDED(hr); } } while(0); if((bCorrectionFileLoaded == FALSE) && (pSrcFilterCorr != NULL)) { IFilterGraph* pFG = GetFilterGraph(); pFG->RemoveFilter(pSrcFilterCorr); } // Cleanup SAFE_RELEASE(pPinNew); SAFE_RELEASE(pEnum); SAFE_RELEASE(pEnumFilers); SAFE_RELEASE(pFSFCorr); SAFE_RELEASE(pSrcFilterCorr); if(pszFileName != NULL) { CoTaskMemFree(pszFileName); } SAFE_RELEASE(pFSF); SAFE_RELEASE(pPinOutSrc); #undef IF_FAIL_BREAK m_bDontTryToLoadCorrectionFileAgain = bCorrectionFileLoaded; if(bCorrectionFileLoaded) { DebugLog("<=== Leaving TryToLoadCorrectionFile successfull 0x%08X", GetCurrentThreadId()); } else { DebugLog("<=== Leaving TryToLoadCorrectionFile FAILED 0x%08X", GetCurrentThreadId()); } return hr; }
HRESULT CAccessSys::BuildPreview(void) { HRESULT hr; IBaseFilter *pSrcFilter = NULL; if (b_buildPreview){ return S_OK; } // Get DirectShow interfaces hr = GetInterfaces(); if (FAILED(hr)) { Msg(TEXT("Failed to get video interfaces! hr=0x%x"), hr); return hr; } pSrcFilter = p_streams[0].p_device_filter; hr = p_capture_graph_builder2->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pSrcFilter, NULL, NULL); if (FAILED(hr)) { Msg(TEXT("Couldn't render the video capture stream. hr=0x%x\r\n") TEXT("The capture device may already be in use by another application.\r\n\r\n") TEXT("The sample will now close."), hr); pSrcFilter->Release(); return hr; } //{ // IEnumPins *ep; // IPin *inputpin = NULL; // IPin *voutputpin = NULL; // IPin *aoutputpin = NULL; // IPin *pin = NULL; // bool bFindI420 = false; // bool bFindPCM = false; // pSrcFilter = p_streams[0].p_device_filter; // pSrcFilter->EnumPins(&ep); // if (SUCCEEDED(hr)){ // ep->Reset(); // while (SUCCEEDED(hr = ep->Next(1, &pin, 0)) && hr != S_FALSE){ // PIN_DIRECTION pinDir; // pin->QueryDirection(&pinDir); // if (pinDir == PINDIR_OUTPUT){ // AM_MEDIA_TYPE *pmt; // IEnumMediaTypes *emt; // pin->EnumMediaTypes(&emt); // while (hr = emt->Next(1, &pmt, NULL), hr != S_FALSE){ // if (pmt->majortype == MEDIATYPE_Video){ // if (pmt->subtype == MEDIASUBTYPE_RGB24){ // //Msg(TEXT("MEDIASUBTYPE_RGB24")); // } // else if (pmt->subtype == MEDIASUBTYPE_I420){ // //Msg(TEXT("MEDIASUBTYPE_I420")); // bFindI420 = true; // } // else if (pmt->subtype == MEDIASUBTYPE_YUY2){} // } // TCHAR buf[64] = { 0 }; // swprintf(buf, TEXT("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"), // pmt->subtype.Data1, pmt->subtype.Data2, pmt->subtype.Data3, // pmt->subtype.Data4[0], pmt->subtype.Data4[1], // pmt->subtype.Data4[2], pmt->subtype.Data4[3], // pmt->subtype.Data4[4], pmt->subtype.Data4[5], // pmt->subtype.Data4[6], pmt->subtype.Data4[7]); // //Msg(buf); // DeleteMediaType(pmt); // } // emt->Release(); // } // pin->Release(); // pin = NULL; // } // } // RELEASE(ep); //} pSrcFilter = p_streams[1].p_device_filter; // do not render local audio //hr = p_capture_graph_builder2->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, // pSrcFilter, NULL, NULL); //if (FAILED(hr)) //{ // Msg(TEXT("Couldn't render the video capture stream. hr=0x%x\r\n") // TEXT("The capture device may already be in use by another application.\r\n\r\n") // TEXT("The sample will now close."), hr); // pSrcFilter->Release(); // return hr; //} { IEnumPins *ep; IPin *pin = NULL; IAMBufferNegotiation *buffer_negotiation = NULL; ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 }; pSrcFilter->EnumPins(&ep); ep->Reset(); while (SUCCEEDED(hr = ep->Next(1, &pin, 0)) && hr != S_FALSE){ if (pin->QueryInterface(IID_IAMBufferNegotiation, (void **)&buffer_negotiation) == S_OK){ buffer_negotiation->GetAllocatorProperties(&props); props.cbBuffer = 4096; // set to 4096 byte: acc encode frame length buffer_negotiation->SuggestAllocatorProperties(&props); RELEASE(buffer_negotiation); } RELEASE(pin); } RELEASE(ep); } //{ // IEnumPins *ep; // IPin *inputpin = NULL; // IPin *voutputpin = NULL; // IPin *aoutputpin = NULL; // IPin *pin = NULL; // bool bFindI420 = false; // bool bFindPCM = false; // //pSrcFilter = p_streams[0].p_device_filter; // pSrcFilter->EnumPins(&ep); // if (SUCCEEDED(hr)){ // ep->Reset(); // while (SUCCEEDED(hr = ep->Next(1, &pin, 0)) && hr != S_FALSE){ // PIN_DIRECTION pinDir; // pin->QueryDirection(&pinDir); // if (pinDir == PINDIR_OUTPUT){ // AM_MEDIA_TYPE *pmt; // IEnumMediaTypes *emt; // pin->EnumMediaTypes(&emt); // while (hr = emt->Next(1, &pmt, NULL), hr != S_FALSE){ // if (pmt->majortype == MEDIATYPE_Audio){ // if (pmt->subtype == MEDIASUBTYPE_PCM){ // //Msg(TEXT("MEDIASUBTYPE_PCM")); // } // else if (pmt->subtype == MEDIASUBTYPE_I420){ // //Msg(TEXT("MEDIASUBTYPE_I420")); // bFindI420 = true; // } // else{ // bFindI420 = true; // } // } // TCHAR buf[64] = { 0 }; // swprintf(buf, TEXT("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"), // pmt->subtype.Data1, pmt->subtype.Data2, pmt->subtype.Data3, // pmt->subtype.Data4[0], pmt->subtype.Data4[1], // pmt->subtype.Data4[2], pmt->subtype.Data4[3], // pmt->subtype.Data4[4], pmt->subtype.Data4[5], // pmt->subtype.Data4[6], pmt->subtype.Data4[7]); // //Msg(buf); // DeleteMediaType(pmt); // } // emt->Release(); // } // pin->Release(); // pin = NULL; // } // } // RELEASE(ep); //} b_buildPreview = true; return hr; }
HRESULT recChannel_t::map(void) { __CONTEXT("recChannel_t::map"); int hr = 0; IBaseFilter * pFilter = NULL; IBaseFilter * pFilter2 = NULL; IPin * pVideoInputPin = NULL; pControl->StopWhenReady(); mapping = true; pOutput = camInfo->output; if (remaped){ //refresh Codec BW before creation pSender->sampleGrabber->BWController->refreshBW(); pSender->rebind(); hr = pGraph->Render(pOutput); { // Enumerate the filters in the graph. IEnumFilters *pEnum = NULL; int hr = pGraph->EnumFilters(&pEnum); if (SUCCEEDED(hr)) { IBaseFilter *pFilter = NULL; pEnum->Reset(); while (S_OK == pEnum->Next(1, &pFilter, NULL)) { CLSID filterId; pFilter->GetClassID(&filterId); if(filterId == CLSID_AviSplitter) { IEnumPins * pEnumpin = NULL; hr = pFilter->EnumPins(&pEnumpin); if (!hr) { IPin * pPin = NULL; pEnumpin->Reset(); while (pEnumpin->Next(1, &pPin, 0) == S_OK) { bool break_loop = false; AM_MEDIA_TYPE * mediaType; IEnumMediaTypes * enumMedia = NULL; hr = pPin->EnumMediaTypes(&enumMedia); if(!hr) { enumMedia->Reset(); while(enumMedia->Next(1,&mediaType , NULL) == S_OK) { if (mediaType->majortype == MEDIATYPE_Audio) { pPin->Disconnect(); pGraph->Render(pPin); pPin->Release(); break_loop = true; break; } } enumMedia->Release(); if (break_loop) break; } } pEnumpin->Release(); } } pFilter->Release(); } pEnum->Release(); } } pipeCreated = true; if (hr) { errorCheck(hr); NOTIFY("[recChannel_t::map]WARNING :: Can't render actual format, restoring default settings...\r\n"); capInfo.heigth = DEFAULT_CAPTURE_HEIGTH; capInfo.width = DEFAULT_CAPTURE_WIDTH; ql_t<AM_MEDIA_TYPE *> auxFormats = camInfo->getFormatList(); pSender->SetActualCodec(DEFAULT_CODEC_STR); } } if (fullScreen){ set_full_screen(true); }else{ hr = setWindowGeometry(windowInfo); errorCheck(hr); } // IVideoWindow *pWindowInfo = NULL; // hr = pGraph->QueryInterface(IID_IVideoWindow, (void **)&pWindowInfo); // if (!hr) // { // wchar_t wtext[100]; // long windowStyle,windowStyleEx; // lText(wtext,title); // pWindowInfo->get_WindowStyle(&windowStyle); // pWindowInfo->get_WindowStyleEx(&windowStyleEx); // windowStyle = windowStyle + DEFAULT_WINDOW_PROPS - DEFAULT_WINDOW_NON_PROPS; // windowStyleEx = windowStyleEx - WS_EX_APPWINDOW; // pWindowInfo->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS); // pWindowInfo->put_WindowStyleEx(WS_EX_TOOLWINDOW); // pWindowInfo->put_Caption(wtext); // //#ifdef _WINDOWS // if (camInfo->getKind() == MEDIA) // { // fControl->setGeometry(windowInfo); // // } //#endif ////Ares daemon don't show local windows on ////recChannels //#ifndef __ARES // if (camInfo->getKind() != SHARED) // { // pWindowInfo->put_Visible(OATRUE); // pWindowInfo->put_AutoShow(OATRUE); // } // else // { //#endif // pWindowInfo->put_Visible(OAFALSE); // pWindowInfo->put_AutoShow(OAFALSE); //#ifndef __ARES // } //#endif // // pWindowInfo->Release(); // setOwner(); // } IMediaSeeking * pSeek = NULL; pGraph->QueryInterface(IID_IMediaSeeking,(void **)&pSeek); if (pSeek)pSeek->SetRate(1); pControl->Run(); if (camInfo->getKind() == SHARED) { camInfo->RunSource(); } if (camInfo->getKind() == TEST) { if (pSeek) pSeek->SetRate(0.5); looper->Run(); } remaped = false; return hr; }
void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel) { if( !pGraph ) { return; } IEnumFilters *pFilters; DbgLog((LOG_TRACE,dwLevel,TEXT("DumpGraph [%x]"), pGraph)); if (FAILED(pGraph->EnumFilters(&pFilters))) { DbgLog((LOG_TRACE,dwLevel,TEXT("EnumFilters failed!"))); } IBaseFilter *pFilter; ULONG n; while (pFilters->Next(1, &pFilter, &n) == S_OK) { FILTER_INFO info; if (FAILED(pFilter->QueryFilterInfo(&info))) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] -- failed QueryFilterInfo"), pFilter)); } else { QueryFilterInfoReleaseGraph(info); // !!! should QueryVendorInfo here! DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] '%ls'"), pFilter, info.achName)); IEnumPins *pins; if (FAILED(pFilter->EnumPins(&pins))) { DbgLog((LOG_TRACE,dwLevel,TEXT("EnumPins failed!"))); } else { IPin *pPin; while (pins->Next(1, &pPin, &n) == S_OK) { PIN_INFO info; if (FAILED(pPin->QueryPinInfo(&info))) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] -- failed QueryPinInfo"), pPin)); } else { QueryPinInfoReleaseFilter(info); IPin *pPinConnected = NULL; HRESULT hr = pPin->ConnectedTo(&pPinConnected); if (pPinConnected) { DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] '%ls' [%sput]") TEXT(" Connected to pin [%x]"), pPin, info.achName, info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"), pPinConnected)); pPinConnected->Release(); // perhaps we should really dump the type both ways as a sanity // check? if (info.dir == PINDIR_OUTPUT) { AM_MEDIA_TYPE mt; hr = pPin->ConnectionMediaType(&mt); if (SUCCEEDED(hr)) { DisplayType(TEXT("Connection type"), &mt); FreeMediaType(mt); } } } else { DbgLog((LOG_TRACE,dwLevel, TEXT(" Pin [%x] '%ls' [%sput]"), pPin, info.achName, info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"))); } } pPin->Release(); } pins->Release(); } } pFilter->Release(); } pFilters->Release(); }
HRESULT cDxCapture::CaptureVideo(const int cameraIndex) //cameraIndex = 0 { HRESULT hr; IBaseFilter *pSrcFilter = NULL; // Get DirectShow interfaces hr = GetInterfaces(); if (FAILED(hr)) { Msg(TEXT("Failed to get video interfaces! hr=0x%x"), hr); return hr; } // Attach the filter graph to the capture graph hr = m_pCapture->SetFiltergraph(m_pGraph); if (FAILED(hr)) { Msg(TEXT("Failed to set capture filter graph! hr=0x%x"), hr); return hr; } // Use the system device enumerator and class enumerator to find // a video capture/preview device, such as a desktop USB video camera. hr = FindCaptureDevice(cameraIndex, &pSrcFilter); if (FAILED(hr)) { // Don't display a message because FindCaptureDevice will handle it return hr; } // Add Capture filter to our graph. hr = m_pGraph->AddFilter(pSrcFilter, L"Video Capture"); if (FAILED(hr)) { Msg(TEXT("Couldn't add the capture filter to the graph! hr=0x%x\r\n\r\n") TEXT("If you have a working video capture device, please make sure\r\n") TEXT("that it is connected and is not being used by another application.\r\n\r\n") TEXT("The sample will now close."), hr); pSrcFilter->Release(); return hr; } IEnumPins *pEnum = NULL; IPin *pPin = NULL; hr = pSrcFilter->EnumPins(&pEnum); if (FAILED(hr)) return hr; while (S_OK == pEnum->Next(1, &pPin, NULL)) { hr = ConnectFilters(m_pGraph, pPin, m_pGrabberF); SafeRelease(&pPin); if (SUCCEEDED(hr)) { break; } } if (FAILED(hr)) return hr; hr = m_pGraph->AddFilter(m_pNullF, L"Null Filter"); if (FAILED(hr)) return hr; hr = ConnectFilters(m_pGraph, m_pGrabberF, m_pNullF); if (FAILED(hr)) return hr; hr = m_pGrabber->SetOneShot(TRUE); if (FAILED(hr)) return hr; hr = m_pGrabber->SetBufferSamples(TRUE); if (FAILED(hr)) return hr; // Now that the filter has been added to the graph and we have // rendered its stream, we can release this reference to the filter. pSrcFilter->Release(); // Start previewing video data hr = m_pMC->Run(); if (FAILED(hr)) { Msg(TEXT("Couldn't run the graph! hr=0x%x"), hr); return hr; } // Remember current state m_psCurrent = RUNNING; long evCode; hr = m_pME->WaitForCompletion(INFINITE, &evCode); return S_OK; }
HRESULT SetVboxFrequency( JNIEnv *env, DShowCaptureInfo* pCapInfo, ULONG ulFrequency ) { HRESULT hr; DWORD dwSupported=0; IEnumPins* pEnumPin; IPin* pInputPin; ULONG ulFetched; PIN_INFO infoPin; if ( pCapInfo->pBDATuner == NULL ) return E_FAIL; if( ulFrequency == 0 ) { slog( (env,"VOX tuner skips frequency 0\r\n") ); return S_OK; } IBaseFilter* pTunerDevice = pCapInfo->pBDATuner; pTunerDevice->EnumPins(&pEnumPin); if( SUCCEEDED( hr = pEnumPin->Reset() ) ) { while((hr = pEnumPin->Next( 1, &pInputPin, &ulFetched )) == S_OK) { pInputPin->QueryPinInfo(&infoPin); // Release AddRef'd filter, we don't need it if( infoPin.pFilter != NULL ) infoPin.pFilter->Release(); if(infoPin.dir == PINDIR_INPUT) break; } if(hr != S_OK) { slog( (env,"Vbox tuner input pin query failed \r\n") ); return hr; } } else { slog( (env,"Vbox tuner reset failed \r\n") ); return E_FAIL; } IKsPropertySet *pKsPropertySet; pInputPin->QueryInterface(&pKsPropertySet); if (!pKsPropertySet) { slog( (env,"Vbox tuner input pin's QueryInterface failed \r\n") ); return E_FAIL; } KSPROPERTY_TUNER_MODE_CAPS_S ModeCaps; KSPROPERTY_TUNER_FREQUENCY_S Frequency; memset(&ModeCaps,0,sizeof(KSPROPERTY_TUNER_MODE_CAPS_S)); memset(&Frequency,0,sizeof(KSPROPERTY_TUNER_FREQUENCY_S)); ModeCaps.Mode = AMTUNER_MODE_TV; // Check either the Property is supported or not by the Tuner drivers hr = pKsPropertySet->QuerySupported(PROPSETID_TUNER, KSPROPERTY_TUNER_MODE_CAPS,&dwSupported); if(SUCCEEDED(hr) && dwSupported&KSPROPERTY_SUPPORT_GET) { DWORD cbBytes=0; hr = pKsPropertySet->Get(PROPSETID_TUNER,KSPROPERTY_TUNER_MODE_CAPS, INSTANCEDATA_OF_PROPERTY_PTR(&ModeCaps), INSTANCEDATA_OF_PROPERTY_SIZE(ModeCaps), &ModeCaps, sizeof(ModeCaps), &cbBytes); } else { SAFE_RELEASE(pKsPropertySet); slog( (env,"Vbox tuner input pin's not support GET query \r\n") ); return E_FAIL; } Frequency.Frequency=ulFrequency; // in Hz if(ModeCaps.Strategy==KS_TUNER_STRATEGY_DRIVER_TUNES) Frequency.TuningFlags=KS_TUNER_TUNING_FINE; else Frequency.TuningFlags=KS_TUNER_TUNING_EXACT; // Here the real magic starts //if(ulFrequency>=ModeCaps.MinFrequency && ulFrequency<=ModeCaps.MaxFrequency) { hr = pKsPropertySet->Set(PROPSETID_TUNER, KSPROPERTY_TUNER_FREQUENCY, INSTANCEDATA_OF_PROPERTY_PTR(&Frequency), INSTANCEDATA_OF_PROPERTY_SIZE(Frequency), &Frequency, sizeof(Frequency)); if(FAILED(hr)) { slog( (env,"Vbox tuner input pin's set frequency %d failed hr=0x%x\r\n", Frequency.Frequency, hr ) ); SAFE_RELEASE(pKsPropertySet); return E_FAIL; } } // else // { //slog( (env,"Vbox tuning frequency %d is out of range (%d %d)\r\n", // ulFrequency, ModeCaps.MinFrequency, ModeCaps.MaxFrequency ) ); // return E_FAIL; // } SAFE_RELEASE(pKsPropertySet); slog( (env,"Vbox tuner tuning overider frequency %d successful. \r\n", ulFrequency) ); return S_OK; }
HRESULT CDXGraph::RenderAVIFile(CString mSourceFile) { if(pGraph != NULL) { //Add Grabber Filter IBaseFilter *pGrabberF = NULL; this->AddGrabber(&pGrabberF); //Add src filter IBaseFilter *pSrc; HRESULT hr = pGraph->AddSourceFilter(mSourceFile, L"Source", &pSrc); if(FAILED(hr)) return hr; //Add Avi splitter filter IBaseFilter *pAviSplitter = NULL; hr = CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAviSplitter); hr = pGraph->AddFilter(pAviSplitter, L"AVI Splitter"); //Add Mpeg4s decoder dmo filter IBaseFilter *pMp4Decoder = NULL; hr = CoCreateInstance(CLSID_MPEG4SDecoder, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pMp4Decoder); hr = pGraph->AddFilter(pMp4Decoder, L"Mp4 Decoder"); //Audio //add mp3 decoder IBaseFilter *pMP3Decoder = NULL; hr = CoCreateInstance(CLSID_MP3Decoder, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pMP3Decoder); hr = pGraph->AddFilter(pMP3Decoder, L"MP3 Decoder"); //add direct sound device IBaseFilter *pDSoundDevice = NULL; hr = CoCreateInstance(CLSID_DSoundRender,NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pDSoundDevice); hr = pGraph->AddFilter(pDSoundDevice, L"Sound Renderer"); //connect filters via pins hr = ConnectFilters(pGraph, pSrc, pAviSplitter, MEDIATYPE_NULL); //Split to audio and video IEnumPins *pEnum = 0; IPin *pPin = 0; IEnumMediaTypes *pEnumMediaType = 0; hr = pAviSplitter->EnumPins(&pEnum); bool audio_connected = false, video_connected = false; while(pEnum->Next(1, &pPin, NULL) == S_OK) { hr = pPin->EnumMediaTypes(&pEnumMediaType); //if this is video output pin if(SUCCEEDED(this->CheckMediaType(pEnumMediaType, MEDIATYPE_Video))) { IPin *pMP4DecoderInput = NULL; hr = this->GetUnconnectedPin(pMp4Decoder, PINDIR_INPUT, &pMP4DecoderInput, MEDIATYPE_NULL); hr = pGraph->Connect(pPin, pMP4DecoderInput); PIN_INFO pInfo; pPin->QueryPinInfo(&pInfo); pMP4DecoderInput->QueryPinInfo(&pInfo); pMP4DecoderInput->Release(); video_connected = true; } //if this is audio output pin else if (SUCCEEDED(this->CheckMediaType(pEnumMediaType, MEDIATYPE_Audio))) { IPin *pMP3DecoderInput = NULL; hr = this->GetUnconnectedPin(pMP3Decoder, PINDIR_INPUT, &pMP3DecoderInput, MEDIATYPE_NULL); hr = pGraph->Connect(pPin, pMP3DecoderInput); pMP3DecoderInput->Release(); audio_connected = true; } pPin->Release(); pEnumMediaType->Release(); if (audio_connected && video_connected) break; } pEnum->Release(); //Connect Audio Renderer hr = this->ConnectFilters(pGraph, pMP3Decoder, pDSoundDevice, MEDIATYPE_Audio); //Connect the Mp4Decoder to Sample Grabber hr = this->ConnectFilters(pGraph, pMp4Decoder, pGrabberF, MEDIATYPE_NULL); //get the output pin of grabber, then render pin IPin *pOutPin = NULL; this->GetUnconnectedPin(pGrabberF, PINDIR_OUTPUT, &pOutPin, MEDIATYPE_NULL); hr = pGraph->Render(pOutPin); pGrabberF->Release(); pSrc->Release(); pAviSplitter->Release(); pMp4Decoder->Release(); pMP3Decoder->Release(); pDSoundDevice->Release(); IEnumFilters *pEnumFilter; IBaseFilter *pRenderFilter; hr = pGraph->EnumFilters(&pEnumFilter); //test the graph SaveGraphFile(pGraph, L"D:\\SliderPlayer_264.grf"); return S_OK; } return E_FAIL; }