HRESULT CQTDec::CompleteConnect(PIN_DIRECTION dir, IPin* pReceivePin) { if(dir == PINDIR_INPUT) { m_mts.RemoveAll(); VIDEOINFOHEADER* vihin = (VIDEOINFOHEADER*)m_pInput->CurrentMediaType().pbFormat; BITMAPINFOHEADER& bihin = vihin->bmiHeader; CMediaType mt; mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_None; mt.formattype = FORMAT_VideoInfo; mt.bFixedSizeSamples = TRUE; mt.bTemporalCompression = FALSE; mt.lSampleSize = 0; mt.pUnk = NULL; VIDEOINFOHEADER vih; memset(&vih, 0, sizeof(vih)); vih.AvgTimePerFrame = vihin->AvgTimePerFrame; vih.rcSource = vihin->rcSource; vih.rcTarget = vihin->rcTarget; vih.dwBitRate = vihin->dwBitRate; vih.dwBitErrorRate = vihin->dwBitErrorRate; BITMAPINFOHEADER& bih = vih.bmiHeader; bih.biSize = sizeof(bih); bih.biWidth = bihin.biWidth; bih.biHeight = abs(bihin.biHeight); bih.biPlanes = 1; bih.biXPelsPerMeter = bih.biYPelsPerMeter = 0; bih.biClrUsed = bih.biClrImportant = 0; // if(fRGB32) // always can decompress to (?) { VIDEOINFOHEADER* vihout = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER)); memcpy(vihout, &vih, sizeof(vih)); BITMAPINFOHEADER& bihout = vihout->bmiHeader; bihout.biBitCount = 32; bihout.biSizeImage = bihout.biWidth*abs(bihout.biHeight)*bihout.biBitCount>>3; mt.subtype = MEDIASUBTYPE_RGB32; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight; CorrectMediaType(&mt); m_mts.Add(mt); ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight; CorrectMediaType(&mt); m_mts.Add(mt); } // if(fRGB16) // always can decompress to (?) { VIDEOINFOHEADER* vihout = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER)); memcpy(vihout, &vih, sizeof(vih)); BITMAPINFOHEADER& bihout = vihout->bmiHeader; bihout.biBitCount = 16; bihout.biSizeImage = bihout.biWidth*abs(bihout.biHeight)*bihout.biBitCount>>3; mt.subtype = MEDIASUBTYPE_RGB565; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight; CorrectMediaType(&mt); m_mts.Add(mt); ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight; CorrectMediaType(&mt); m_mts.Add(mt); mt.subtype = MEDIASUBTYPE_RGB555; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_BITFIELDS; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = -bih.biHeight; CorrectMediaType(&mt); m_mts.Add(mt); ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression = BI_RGB; ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biHeight = bih.biHeight; CorrectMediaType(&mt); m_mts.Add(mt); } }
static int v4w_open_videodevice(V4wState *s) { // Initialize COM CoInitialize(NULL); // get a Graph HRESULT hr= CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, //IID_IBaseFilter, (void **)&s->m_pGraph); if(FAILED(hr)) { return -1; } // get a CaptureGraphBuilder2 hr= CoCreateInstance (CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, //IID_IBaseFilter, (void **)&s->m_pBuilder); if(FAILED(hr)) { return -2; } // connect capture graph builder with the graph s->m_pBuilder->SetFiltergraph(s->m_pGraph); // get mediacontrol so we can start and stop the filter graph hr=s->m_pGraph->QueryInterface (IID_IMediaControl, (void **)&s->m_pControl); if(FAILED(hr)) { return -3; } ICreateDevEnum *pCreateDevEnum = NULL; IEnumMoniker *pEnumMoniker = NULL; IMoniker *pMoniker = NULL; ULONG nFetched = 0; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum); if(FAILED(hr)) { return -4; } hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0); if (FAILED(hr) || pEnumMoniker == NULL) { //printf("no device\n"); return -5; } pEnumMoniker->Reset(); int pos=0; while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) ) { IPropertyBag *pBag; hr = pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag ); if( hr != S_OK ) continue; if (s->dev[0]=='\0') break; VARIANT var; VariantInit(&var); hr = pBag->Read( L"FriendlyName", &var, NULL ); if( hr != S_OK ) { pMoniker->Release(); continue; } //USES_CONVERSION; char szName[256]; WideCharToMultiByte(CP_UTF8,0,var.bstrVal,-1,szName,256,0,0); VariantClear(&var); if (strcmp(szName, s->dev)==0) break; pMoniker->Release(); pBag->Release(); pMoniker=NULL; pBag=NULL; } if(pMoniker==NULL) { return -6; } hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&s->m_pDeviceFilter ); if(FAILED(hr)) { return -7; } s->m_pGraph->AddFilter(s->m_pDeviceFilter, L"Device Filter"); pMoniker->Release(); pEnumMoniker->Release(); pCreateDevEnum->Release(); GUID pPinCategory; if (try_format(s->m_pDeviceFilter, s->pix_fmt, &pPinCategory)==0) s->pix_fmt = s->pix_fmt; else if (try_format(s->m_pDeviceFilter,MS_YUV420P, &pPinCategory)==0) s->pix_fmt = MS_YUV420P; else if (try_format(s->m_pDeviceFilter,MS_YUY2, &pPinCategory)==0) s->pix_fmt = MS_YUY2; else if (try_format(s->m_pDeviceFilter,MS_YUYV, &pPinCategory)==0) s->pix_fmt = MS_YUYV; else if (try_format(s->m_pDeviceFilter,MS_UYVY, &pPinCategory)==0) s->pix_fmt = MS_UYVY; else if (try_format(s->m_pDeviceFilter,MS_RGB24, &pPinCategory)==0) s->pix_fmt = MS_RGB24; else { ms_error("Unsupported video pixel format."); return -8; } if (s->pix_fmt == MS_YUV420P) ms_message("Driver supports YUV420P, using that format."); else if (s->pix_fmt == MS_YUY2) ms_message("Driver supports YUY2 (YUYV), using that format."); else if (s->pix_fmt == MS_YUYV) ms_message("Driver supports YUV422, using that format."); else if (s->pix_fmt == MS_UYVY) ms_message("Driver supports UYVY, using that format."); else if (s->pix_fmt == MS_RGB24) ms_message("Driver supports RGB24, using that format."); if (try_format_size(s, s->pix_fmt, s->vsize.width, s->vsize.height, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", s->vsize.width, s->vsize.height); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QQVGA_W, MS_VIDEO_SIZE_QQVGA_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QQVGA_W, MS_VIDEO_SIZE_QQVGA_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_NS1_W, MS_VIDEO_SIZE_NS1_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_NS1_W, MS_VIDEO_SIZE_NS1_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QSIF_W, MS_VIDEO_SIZE_QSIF_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QSIF_W, MS_VIDEO_SIZE_QSIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_SIF_W, MS_VIDEO_SIZE_SIF_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_SIF_W, MS_VIDEO_SIZE_SIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_SDTV_W, MS_VIDEO_SIZE_SDTV_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_SDTV_W, MS_VIDEO_SIZE_SDTV_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_288P_W, MS_VIDEO_SIZE_288P_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_288P_W, MS_VIDEO_SIZE_288P_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_448P_W, MS_VIDEO_SIZE_448P_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_448P_W, MS_VIDEO_SIZE_448P_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_576P_W, MS_VIDEO_SIZE_576P_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_576P_W, MS_VIDEO_SIZE_576P_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_720P_W, MS_VIDEO_SIZE_720P_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_720P_W, MS_VIDEO_SIZE_720P_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_1080P_W, MS_VIDEO_SIZE_1080P_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_1080P_W, MS_VIDEO_SIZE_1080P_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_4SIF_W, MS_VIDEO_SIZE_4SIF_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_4SIF_W, MS_VIDEO_SIZE_4SIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_SVGA_W, MS_VIDEO_SIZE_SVGA_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_SVGA_W, MS_VIDEO_SIZE_SVGA_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_XGA_W, MS_VIDEO_SIZE_XGA_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_XGA_W, MS_VIDEO_SIZE_XGA_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_WXGA_W, MS_VIDEO_SIZE_WXGA_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_WXGA_W, MS_VIDEO_SIZE_WXGA_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_HDTVP_W, MS_VIDEO_SIZE_HDTVP_H, &pPinCategory)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_HDTVP_W, MS_VIDEO_SIZE_HDTVP_H); else { ms_error("No supported size found for format."); /* size not supported? */ return -9; } // get DXFilter s->m_pDXFilter = new CDXFilter(NULL, &hr, FALSE); if(s->m_pDXFilter==NULL) { return -10; } s->m_pDXFilter->AddRef(); CMediaType mt; mt.SetType(&MEDIATYPE_Video); GUID m = MEDIASUBTYPE_RGB24; if (s->pix_fmt == MS_YUV420P) m = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0')); else if (s->pix_fmt == MS_YUY2) m = MEDIASUBTYPE_YUY2; else if (s->pix_fmt == MS_YUYV) m = MEDIASUBTYPE_YUYV; else if (s->pix_fmt == MS_UYVY) m = MEDIASUBTYPE_UYVY; else if (s->pix_fmt == MS_RGB24) m = MEDIASUBTYPE_RGB24; mt.SetSubtype(&m); mt.formattype = FORMAT_VideoInfo; mt.SetTemporalCompression(FALSE); VIDEOINFO *pvi = (VIDEOINFO *) mt.AllocFormatBuffer(sizeof(VIDEOINFO)); if (NULL == pvi) return -11; ZeroMemory(pvi, sizeof(VIDEOINFO)); if (s->pix_fmt == MS_YUV420P) pvi->bmiHeader.biCompression = MAKEFOURCC('I','4','2','0'); else if (s->pix_fmt == MS_YUY2) pvi->bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','2'); else if (s->pix_fmt == MS_YUYV) pvi->bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','V'); else if (s->pix_fmt == MS_UYVY) pvi->bmiHeader.biCompression = MAKEFOURCC('U','Y','V','Y'); else if (s->pix_fmt == MS_RGB24) pvi->bmiHeader.biCompression = BI_RGB; if (s->pix_fmt == MS_YUV420P) pvi->bmiHeader.biBitCount = 12; else if (s->pix_fmt == MS_YUY2) pvi->bmiHeader.biBitCount = 16; else if (s->pix_fmt == MS_YUYV) pvi->bmiHeader.biBitCount = 16; else if (s->pix_fmt == MS_UYVY) pvi->bmiHeader.biBitCount = 16; else if (s->pix_fmt == MS_RGB24) pvi->bmiHeader.biBitCount = 24; pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pvi->bmiHeader.biWidth = s->vsize.width; pvi->bmiHeader.biHeight = s->vsize.height; pvi->bmiHeader.biPlanes = 1; pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); pvi->bmiHeader.biClrImportant = 0; mt.SetSampleSize(pvi->bmiHeader.biSizeImage); mt.SetFormat((BYTE*)pvi, sizeof(VIDEOINFO)); hr = s->m_pDXFilter->SetAcceptedMediaType(&mt); if(FAILED(hr)) { return -12; } hr = s->m_pDXFilter->SetCallback(Callback); if(FAILED(hr)) { return -13; } hr = s->m_pDXFilter->QueryInterface(IID_IBaseFilter, (LPVOID *)&s->m_pIDXFilter); if(FAILED(hr)) { return -14; } hr = s->m_pGraph->AddFilter(s->m_pIDXFilter, L"DXFilter Filter"); if(FAILED(hr)) { return -15; } // get null renderer hr=CoCreateInstance (CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&s->m_pNullRenderer); if(FAILED(hr)) { return -16; } if (s->m_pNullRenderer!=NULL) { s->m_pGraph->AddFilter(s->m_pNullRenderer, L"Null Renderer"); } hr = s->m_pBuilder->RenderStream(&pPinCategory, &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); if (FAILED(hr)) { return -17; } IAMStreamConfig *pConfig = NULL; hr = s->m_pBuilder->FindInterface( &pPinCategory, // Preview pin. &MEDIATYPE_Video, // Any media type. s->m_pDeviceFilter, // Pointer to the capture filter. IID_IAMStreamConfig, (void**)&pConfig); if (pConfig!=NULL) { AM_MEDIA_TYPE *pType = NULL; int iCount, iSize; pConfig->GetNumberOfCapabilities(&iCount, &iSize); for (int i = 0; i < iCount; i++) { VIDEO_STREAM_CONFIG_CAPS scc; pType = NULL; pConfig->GetStreamCaps(i, &pType, (BYTE *)&scc); if (!((pType->formattype == FORMAT_VideoInfo) && (pType->cbFormat >= sizeof(VIDEOINFOHEADER)) && (pType->pbFormat != NULL))) continue; VIDEOINFOHEADER & videoInfo = *(VIDEOINFOHEADER *)pType->pbFormat; if (m != pType->subtype) continue; if (videoInfo.bmiHeader.biWidth != s->vsize.width) continue; if (videoInfo.bmiHeader.biHeight != s->vsize.height) continue; if (videoInfo.bmiHeader.biBitCount != pvi->bmiHeader.biBitCount) continue; if (videoInfo.bmiHeader.biCompression != pvi->bmiHeader.biCompression) continue; videoInfo.AvgTimePerFrame = UNITS / (LONGLONG)s->fps; pConfig->SetFormat(pType); } pConfig->GetFormat(&pType); if (pType!=NULL) { VIDEOINFO *pvi; pvi = (VIDEOINFO *)pType->pbFormat; ms_message("v4w: camera asked fps=%.2f // real fps=%.2f", s->fps, ((float)UNITS / (float)pvi->AvgTimePerFrame)); } pConfig->Release(); } //m_pDXFilter->SetBufferSamples(TRUE); s_callback = s; hr = s->m_pControl->Run(); if(FAILED(hr)) { return -18; } s->rotregvalue=1; return 0; }
static int v4w_open_videodevice(V4wState *s, int format, MSVideoSize *vsize) { // Initialize COM CoInitialize(NULL); // get a Graph HRESULT hr=s->m_pGraph.CoCreateInstance(CLSID_FilterGraph); if(FAILED(hr)) { return -1; } // get a CaptureGraphBuilder2 #if !defined(_WIN32_WCE) hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2); #else hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder); #endif if(FAILED(hr)) { return -2; } // connect capture graph builder with the graph s->m_pBuilder->SetFiltergraph(s->m_pGraph); // get mediacontrol so we can start and stop the filter graph hr=s->m_pGraph.QueryInterface(&(s->m_pControl)); if(FAILED(hr)) { return -3; } // get DXFilter s->m_pDXFilter = new CDXFilter(NULL, &hr, FALSE); if(s->m_pDXFilter==NULL) { return -4; } s->m_pDXFilter->AddRef(); if(FAILED(hr)) { return -4; } CMediaType mt; mt.SetType(&MEDIATYPE_Video); if (format==MS_YUV420P) { GUID m = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0')); mt.SetSubtype(&m); mt.SetSubtype(&MEDIASUBTYPE_YV12); } else //if (format==MS_RGB24) { mt.SetSubtype(&MEDIASUBTYPE_RGB24); } //mt.SetSubtype(&MEDIASUBTYPE_IYUV); //mt.SetSubtype(&MEDIASUBTYPE_YUYV); //mt.SetSubtype(&MEDIASUBTYPE_RGB24); //mt.SetSampleSize(); mt.formattype = FORMAT_VideoInfo; mt.SetTemporalCompression(FALSE); VIDEOINFO *pvi = (VIDEOINFO *) mt.AllocFormatBuffer(sizeof(VIDEOINFO)); if (NULL == pvi) return E_OUTOFMEMORY; ZeroMemory(pvi, sizeof(VIDEOINFO)); if (format==MS_YUV420P) { pvi->bmiHeader.biCompression = MAKEFOURCC('I','4','2','0'); pvi->bmiHeader.biCompression = MAKEFOURCC('Y','V','1','2'); pvi->bmiHeader.biBitCount = 12; } else { pvi->bmiHeader.biCompression = BI_RGB; pvi->bmiHeader.biBitCount = 24; } pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pvi->bmiHeader.biWidth = vsize->width; pvi->bmiHeader.biHeight = vsize->height; pvi->bmiHeader.biPlanes = 1; pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); pvi->bmiHeader.biClrImportant = 0; mt.SetSampleSize(pvi->bmiHeader.biSizeImage); mt.SetFormat((BYTE*)pvi, sizeof(VIDEOINFO)); hr = s->m_pDXFilter->SetAcceptedMediaType(&mt); if(FAILED(hr)) { return -5; } hr = s->m_pDXFilter->SetCallback(Callback); if(FAILED(hr)) { return -6; } hr = s->m_pDXFilter->QueryInterface(IID_IBaseFilter, (LPVOID *)&s->m_pIDXFilter); if(FAILED(hr)) { return -7; } hr = s->m_pGraph->AddFilter(s->m_pIDXFilter, L"DXFilter Filter"); if(FAILED(hr)) { return -8; } #ifdef WM6 ICreateDevEnum *pCreateDevEnum = NULL; IEnumMoniker *pEnumMoniker = NULL; IMoniker *pMoniker = NULL; ULONG nFetched = 0; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum); if(FAILED(hr)) { return -9; } hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0); if (FAILED(hr) || pEnumMoniker == NULL) { //printf("no device\n"); return -10; } pEnumMoniker->Reset(); hr = pEnumMoniker->Next(1, &pMoniker, &nFetched); if(FAILED(hr) || pMoniker==NULL) { return -11; } hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&s->m_pDeviceFilter ); if(FAILED(hr)) { return -12; } s->m_pGraph->AddFilter(s->m_pDeviceFilter, L"Device Filter"); pMoniker->Release(); pEnumMoniker->Release(); pCreateDevEnum->Release(); #else WCHAR wzDeviceName[ MAX_PATH + 1 ]; CComVariant varCamName; CPropertyBag PropBag; CComPtr<IPersistPropertyBag> pPropertyBag; GetFirstCameraDriver(wzDeviceName); hr = s->m_pDeviceFilter.CoCreateInstance( CLSID_VideoCapture ); if (FAILED(hr)) { return -8; } s->m_pDeviceFilter.QueryInterface( &pPropertyBag ); varCamName = wzDeviceName; if(( varCamName.vt == VT_BSTR ) == NULL ) { return E_OUTOFMEMORY; } PropBag.Write( L"VCapName", &varCamName ); pPropertyBag->Load( &PropBag, NULL ); pPropertyBag.Release(); hr = s->m_pGraph->AddFilter( s->m_pDeviceFilter, L"Video capture source" ); #endif if (FAILED(hr)) { return -8; } // get null renderer s->m_pNullRenderer = NULL; #if 0 hr=s->m_pNullRenderer.CoCreateInstance(CLSID_NullRenderer); if(FAILED(hr)) { return -13; } #endif if (s->m_pNullRenderer!=NULL) { s->m_pGraph->AddFilter(s->m_pNullRenderer, L"Null Renderer"); } hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); if (FAILED(hr)) { //hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, // &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); if (FAILED(hr)) { return -14; } } //m_pDXFilter->SetBufferSamples(TRUE); // Create the System Device Enumerator. IFilterMapper *pMapper = NULL; //IEnumMoniker *pEnum = NULL; IEnumRegFilters *pEnum = NULL; hr = CoCreateInstance(CLSID_FilterMapper, NULL, CLSCTX_INPROC, IID_IFilterMapper, (void **) &pMapper); if (FAILED(hr)) { // Error handling omitted for clarity. } GUID arrayInTypes[2]; arrayInTypes[0] = MEDIATYPE_Video; arrayInTypes[1] = MEDIASUBTYPE_dvsd; hr = pMapper->EnumMatchingFilters( &pEnum, MERIT_HW_COMPRESSOR, // Minimum merit. FALSE, // At least one input pin? MEDIATYPE_NULL, MEDIASUBTYPE_NULL, FALSE, // Must be a renderer? FALSE, // At least one output pin? MEDIATYPE_NULL, MEDIASUBTYPE_NULL); // Enumerate the monikers. //IMoniker *pMoniker; REGFILTER *pMoniker; ULONG cFetched; while (pEnum->Next(1, &pMoniker, &cFetched) == S_OK) { IPropertyBag *pPropBag = NULL; #if 0 hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); if (SUCCEEDED(hr)) { // To retrieve the friendly name of the filter, do the following: VARIANT varName; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, 0); if (SUCCEEDED(hr)) { // Display the name in your UI somehow. } VariantClear(&varName); // To create an instance of the filter, do the following: IBaseFilter *pFilter; hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter); // Now add the filter to the graph. Remember to release pFilter later. // Clean up. pPropBag->Release(); } pMoniker->Release(); #endif } // Clean up. pMapper->Release(); pEnum->Release(); s_callback = s; hr = s->m_pControl->Run(); if(FAILED(hr)) { return -15; } s->rotregvalue=1; s->pix_fmt = format; s->vsize.height = vsize->height; s->vsize.width = vsize->width; return 0; }
HRESULT CFSTSplitterFilter::Initialize(IPin *pPin, IAsyncReader *pReader) { // Check and validate the pointer CheckPointer(pReader, E_POINTER); ValidateReadPtr(pReader, sizeof(IAsyncReader)); // Read file header FST_HEADER header; HRESULT hr = pReader->SyncRead(0, sizeof(header), (BYTE*)&header); if (hr != S_OK) return hr; // Verify file header if (header.dwID != FST_ID_2TSF) return VFW_E_INVALID_FILE_FORMAT; // Protect the filter data CAutoLock datalock(&m_csData); // Set video stream info m_nVideoFrames = header.nVideoFrames; m_nFramesPerSecond = header.nFramesPerSecond; // Allocate frame table m_pFrameTable = (FST_FRAME_ENTRY*)CoTaskMemAlloc(m_nVideoFrames * sizeof(FST_FRAME_ENTRY)); if (m_pFrameTable == NULL) { Shutdown(); return E_OUTOFMEMORY; } // Read in the frame table hr = pReader->SyncRead(sizeof(header), m_nVideoFrames * sizeof(FST_FRAME_ENTRY), (BYTE*)m_pFrameTable); if (hr != S_OK) { Shutdown(); return hr; } // Walk the frame table and determine the maximum frame data sizes DWORD cbMaxImage = 0, cbMaxSound = 0; for (DWORD iFrame = 0; iFrame < m_nVideoFrames; iFrame++) { if (m_pFrameTable[iFrame].cbImage > cbMaxImage) cbMaxImage = m_pFrameTable[iFrame].cbImage; if (m_pFrameTable[iFrame].cbSound > cbMaxSound) cbMaxSound = m_pFrameTable[iFrame].cbSound; } // Set file positions m_llDefaultStart = (LONGLONG)sizeof(FST_HEADER) + m_nVideoFrames * sizeof(FST_FRAME_ENTRY); // Right after the header and frame table m_llDefaultStop = MAXLONGLONG; // Defaults to file end // Decide on the input pin properties m_cbInputAlign = 1; m_cbInputBuffer = cbMaxImage + cbMaxSound; // Protect the output pins state CAutoLock pinlock(&m_csPins); // Decide on the output pins count m_nOutputPins = 1; // Video is always present // Check if we have soundtrack if ( (header.dwAudioSampleRate != 0) && (header.nAudioBits != 0) && (m_pFrameTable[0].cbSound != 0) ) m_nOutputPins++; // Create output pins array ASSERT(m_ppOutputPin == NULL); m_ppOutputPin = new CParserOutputPin*[m_nOutputPins]; if (m_ppOutputPin == NULL) { m_nOutputPins = 0; Shutdown(); return E_OUTOFMEMORY; } // Reset the output pin array elements to NULLs for (int i = 0; i < m_nOutputPins; i++) m_ppOutputPin[i] = NULL; // Allocate video media type CMediaType *pmtVideo = new CMediaType(); if (pmtVideo == NULL) { Shutdown(); return E_OUTOFMEMORY; } // Initialize the video media type pmtVideo->InitMediaType(); pmtVideo->SetType(&MEDIATYPE_Video); pmtVideo->SetSubtype(&MEDIASUBTYPE_FSTVideo); pmtVideo->SetSampleSize(0); pmtVideo->SetTemporalCompression(TRUE); pmtVideo->SetFormatType(&FORMAT_FSTVideo); if (!pmtVideo->SetFormat((BYTE*)&header, sizeof(header))) { delete pmtVideo; Shutdown(); return E_FAIL; } // Allocate the video allocator properties ALLOCATOR_PROPERTIES *papVideo = (ALLOCATOR_PROPERTIES*)CoTaskMemAlloc(sizeof(ALLOCATOR_PROPERTIES)); if (papVideo == NULL) { delete pmtVideo; Shutdown(); return E_OUTOFMEMORY; } // Set the video allocator properties papVideo->cbAlign = 0; // No matter papVideo->cbPrefix = 0; // No matter papVideo->cBuffers = 4; // TEMP: No need to set larger value? papVideo->cbBuffer = cbMaxImage; // Allocate time formats array. If we fail here, it's not an error, // we'll just set zero seeker parameters and may proceed DWORD dwVideoCapabilities = 0; int nVideoTimeFormats = 0; GUID *pVideoTimeFormats = (GUID*)CoTaskMemAlloc(3 * sizeof(GUID)); if (pVideoTimeFormats) { nVideoTimeFormats = 3; // Fill in the time formats array pVideoTimeFormats[0] = TIME_FORMAT_MEDIA_TIME; pVideoTimeFormats[1] = TIME_FORMAT_FRAME; pVideoTimeFormats[2] = TIME_FORMAT_SAMPLE; dwVideoCapabilities = AM_SEEKING_CanGetCurrentPos | AM_SEEKING_CanGetStopPos | AM_SEEKING_CanGetDuration; } // Create video output pin (always the first one!) hr = NOERROR; m_ppOutputPin[0] = new CParserOutputPin( NAME("FST Splitter Video Output Pin"), this, &m_csFilter, pmtVideo, papVideo, dwVideoCapabilities, nVideoTimeFormats, pVideoTimeFormats, &hr, wszFSTVideoOutputName ); if ( (FAILED(hr)) || (m_ppOutputPin[0] == NULL) ) { if (m_ppOutputPin[0]) { delete m_ppOutputPin[0]; m_ppOutputPin[0] = NULL; } else { delete pmtVideo; CoTaskMemFree(papVideo); if (pVideoTimeFormats) CoTaskMemFree(pVideoTimeFormats); } Shutdown(); if (FAILED(hr)) return hr; else return E_OUTOFMEMORY; } // Hold a reference on the video output pin m_ppOutputPin[0]->AddRef(); // We've created a new pin -- so increment pin version IncrementPinVersion(); if (m_nOutputPins > 1) { // Allocate audio media type CMediaType *pmtAudio = new CMediaType(); if (pmtAudio == NULL) { Shutdown(); return E_OUTOFMEMORY; } // Initialize the audio media type pmtAudio->InitMediaType(); pmtAudio->SetType(&MEDIATYPE_Audio); pmtAudio->SetSubtype(&MEDIASUBTYPE_PCM); pmtAudio->SetSampleSize(header.nAudioBits * (header.wAudioChannels + 1) / 8); pmtAudio->SetTemporalCompression(FALSE); pmtAudio->SetFormatType(&FORMAT_WaveFormatEx); WAVEFORMATEX *pFormat = (WAVEFORMATEX*)pmtAudio->AllocFormatBuffer(sizeof(WAVEFORMATEX)); if (pFormat == NULL) { delete pmtAudio; Shutdown(); return E_OUTOFMEMORY; } // Fill in the audio format block pFormat->wFormatTag = WAVE_FORMAT_PCM; pFormat->nChannels = header.wAudioChannels + 1; // TEMP: Is it really so? pFormat->nSamplesPerSec = header.dwAudioSampleRate; pFormat->nAvgBytesPerSec = pFormat->nChannels * header.nAudioBits * header.dwAudioSampleRate / 8; pFormat->nBlockAlign = pFormat->nChannels * header.nAudioBits / 8; pFormat->wBitsPerSample = header.nAudioBits; pFormat->cbSize = 0; // Allocate the audio allocator properties ALLOCATOR_PROPERTIES *papAudio = (ALLOCATOR_PROPERTIES*)CoTaskMemAlloc(sizeof(ALLOCATOR_PROPERTIES)); if (papAudio == NULL) { delete pmtAudio; Shutdown(); return E_OUTOFMEMORY; } // Set the audio allocator properties papAudio->cbAlign = 0; // No matter papAudio->cbPrefix = 0; // No matter papAudio->cBuffers = 4; // No use to set different from video value papAudio->cbBuffer = cbMaxSound; // Set the wave format parameters needed for the calculation // of sample stream and media duration m_nSampleSize = pFormat->nBlockAlign; m_nAvgBytesPerSec = pFormat->nAvgBytesPerSec; // Allocate time formats array. If we fail here, it's not an error, // we'll just set zero seeker parameters and may proceed DWORD dwAudioCapabilities = 0; int nAudioTimeFormats = 0; GUID *pAudioTimeFormats = (GUID*)CoTaskMemAlloc(3 * sizeof(GUID)); if (pAudioTimeFormats) { nAudioTimeFormats = 3; // Fill in the time formats array pAudioTimeFormats[0] = TIME_FORMAT_MEDIA_TIME; pAudioTimeFormats[1] = TIME_FORMAT_SAMPLE; pAudioTimeFormats[2] = TIME_FORMAT_BYTE; dwAudioCapabilities = AM_SEEKING_CanGetCurrentPos | AM_SEEKING_CanGetStopPos | AM_SEEKING_CanGetDuration; } // Create audio output pin hr = NOERROR; m_ppOutputPin[1] = new CParserOutputPin( NAME("FST Splitter Audio Output Pin"), this, &m_csFilter, pmtAudio, papAudio, dwAudioCapabilities, nAudioTimeFormats, pAudioTimeFormats, &hr, wszFSTAudioOutputName ); if ( (FAILED(hr)) || (m_ppOutputPin[1] == NULL) ) { if (m_ppOutputPin[1]) { delete m_ppOutputPin[1]; m_ppOutputPin[1] = NULL; } else { delete pmtAudio; CoTaskMemFree(papAudio); if (pAudioTimeFormats) CoTaskMemFree(pAudioTimeFormats); } Shutdown(); if (FAILED(hr)) return hr; else return E_OUTOFMEMORY; } // Hold a reference on the audio output pin m_ppOutputPin[1]->AddRef(); // We've created a new pin -- so increment pin version IncrementPinVersion(); } // Scope for the locking { // Protect media content information CAutoLock infolock(&m_csInfo); // Set the media content strings m_wszAuthorName = (OLECHAR*)CoTaskMemAlloc(sizeof(OLECHAR) * (lstrlenW(wszFSTAuthorName) + 1)); if (m_wszAuthorName) lstrcpyW(m_wszAuthorName, wszFSTAuthorName); m_wszDescription = (OLECHAR*)CoTaskMemAlloc(sizeof(OLECHAR) * (lstrlenW(wszFSTDescription) + 1)); if (m_wszDescription) lstrcpyW(m_wszDescription, wszFSTDescription); } return NOERROR; }
HRESULT VorbisDecodeOutputPin::FillMediaType(CMediaType& mediaType, bool useWaveFormatEx) { if (useWaveFormatEx) { #ifndef WINCE WAVEFORMATEXTENSIBLE* formatEx = (WAVEFORMATEXTENSIBLE*)mediaType.AllocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE)); formatEx->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; formatEx->Format.nChannels = 0; formatEx->Format.nSamplesPerSec = 0; if (GetFilter()->mVorbisFormatInfo) { formatEx->Format.nChannels = (WORD)GetFilter()->mVorbisFormatInfo->numChannels; formatEx->Format.nSamplesPerSec = GetFilter()->mVorbisFormatInfo->samplesPerSec; } formatEx->Format.wBitsPerSample = 16; formatEx->Samples.wValidBitsPerSample = 16; switch (formatEx->Format.nChannels) { case 1: formatEx->dwChannelMask = KSAUDIO_SPEAKER_MONO; break; case 2: formatEx->dwChannelMask = KSAUDIO_SPEAKER_STEREO; break; case 3: formatEx->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER; break; case 4: formatEx->dwChannelMask = KSAUDIO_SPEAKER_QUAD; break; case 5: formatEx->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; break; case 6: formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break; case 7: formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND | SPEAKER_BACK_CENTER; break; case 8: formatEx->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND; break; default: formatEx->dwChannelMask = 0; break; } formatEx->Format.nBlockAlign = (WORD)(formatEx->Format.nChannels * (formatEx->Format.wBitsPerSample >> 3)); formatEx->Format.nAvgBytesPerSec = (formatEx->Format.nChannels * (formatEx->Format.wBitsPerSample >> 3)) * formatEx->Format.nSamplesPerSec; formatEx->Format.cbSize = 22; //sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); formatEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; return S_OK; #endif } else {
HRESULT CMatroskaSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader) { CheckPointer(pAsyncReader, E_POINTER); HRESULT hr = E_FAIL; m_pFile.Free(); m_pTrackEntryMap.RemoveAll(); m_pOrderedTrackArray.RemoveAll(); CAtlArray<CMatroskaSplitterOutputPin*> pinOut; CAtlArray<TrackEntry*> pinOutTE; m_pFile.Attach(DNew CMatroskaFile(pAsyncReader, hr)); if(!m_pFile) return E_OUTOFMEMORY; if(FAILED(hr)) {m_pFile.Free(); return hr;} m_rtNewStart = m_rtCurrent = 0; m_rtNewStop = m_rtStop = m_rtDuration = 0; int iVideo = 1, iAudio = 1, iSubtitle = 1; POSITION pos = m_pFile->m_segment.Tracks.GetHeadPosition(); while(pos) { Track* pT = m_pFile->m_segment.Tracks.GetNext(pos); POSITION pos2 = pT->TrackEntries.GetHeadPosition(); while(pos2) { TrackEntry* pTE = pT->TrackEntries.GetNext(pos2); bool isSub = false; if(!pTE->Expand(pTE->CodecPrivate, ContentEncoding::TracksPrivateData)) continue; CStringA CodecID = pTE->CodecID.ToString(); CStringW Name; Name.Format(L"Output %I64d", (UINT64)pTE->TrackNumber); CMediaType mt; CAtlArray<CMediaType> mts; mt.SetSampleSize(1); if(pTE->TrackType == TrackEntry::TypeVideo) { Name.Format(L"Video %d", iVideo++); mt.majortype = MEDIATYPE_Video; if(CodecID == "V_MS/VFW/FOURCC") { mt.formattype = FORMAT_VideoInfo; VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER) + pTE->CodecPrivate.GetCount() - sizeof(BITMAPINFOHEADER)); memset(mt.Format(), 0, mt.FormatLength()); memcpy(&pvih->bmiHeader, pTE->CodecPrivate.GetData(), pTE->CodecPrivate.GetCount()); mt.subtype = FOURCCMap(pvih->bmiHeader.biCompression); switch(pvih->bmiHeader.biCompression) { case BI_RGB: case BI_BITFIELDS: mt.subtype = pvih->bmiHeader.biBitCount == 1 ? MEDIASUBTYPE_RGB1 : pvih->bmiHeader.biBitCount == 4 ? MEDIASUBTYPE_RGB4 : pvih->bmiHeader.biBitCount == 8 ? MEDIASUBTYPE_RGB8 : pvih->bmiHeader.biBitCount == 16 ? MEDIASUBTYPE_RGB565 : pvih->bmiHeader.biBitCount == 24 ? MEDIASUBTYPE_RGB24 : pvih->bmiHeader.biBitCount == 32 ? MEDIASUBTYPE_ARGB32 : MEDIASUBTYPE_NULL; break; // case BI_RLE8: mt.subtype = MEDIASUBTYPE_RGB8; break; // case BI_RLE4: mt.subtype = MEDIASUBTYPE_RGB4; break; } mts.Add(mt); } else if(CodecID == "V_UNCOMPRESSED") { } else if(CodecID.Find("V_MPEG4/ISO/AVC") == 0 && pTE->CodecPrivate.GetCount() >= 6) { BYTE sps = pTE->CodecPrivate[5] & 0x1f; std::vector<BYTE> avcC; for(int i = 0, j = pTE->CodecPrivate.GetCount(); i < j; i++) avcC.push_back(pTE->CodecPrivate[i]); std::vector<BYTE> sh; unsigned jj = 6; while (sps--) { if (jj + 2 > avcC.size()) goto avcfail; unsigned spslen = ((unsigned)avcC[jj] << 8) | avcC[jj+1]; if (jj + 2 + spslen > avcC.size()) goto avcfail; unsigned cur = sh.size(); sh.resize(cur + spslen + 2, 0); std::copy(avcC.begin() + jj, avcC.begin() + jj + 2 + spslen,sh.begin() + cur); jj += 2 + spslen; } if (jj + 1 > avcC.size()) continue; unsigned pps = avcC[jj++]; while (pps--) { if (jj + 2 > avcC.size()) goto avcfail; unsigned ppslen = ((unsigned)avcC[jj] << 8) | avcC[jj+1]; if (jj + 2 + ppslen > avcC.size()) goto avcfail; unsigned cur = sh.size(); sh.resize(cur + ppslen + 2, 0); std::copy(avcC.begin() + jj, avcC.begin() + jj + 2 + ppslen, sh.begin() + cur); jj += 2 + ppslen; } goto avcsuccess; avcfail: continue; avcsuccess: CAtlArray<BYTE> data; data.SetCount(sh.size()); std::copy(sh.begin(), sh.end(), data.GetData()); mt.subtype = FOURCCMap('1CVA'); mt.formattype = FORMAT_MPEG2Video; MPEG2VIDEOINFO* pm2vi = (MPEG2VIDEOINFO*)mt.AllocFormatBuffer(FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + data.GetCount()); memset(mt.Format(), 0, mt.FormatLength()); pm2vi->hdr.bmiHeader.biSize = sizeof(pm2vi->hdr.bmiHeader); pm2vi->hdr.bmiHeader.biWidth = (LONG)pTE->v.PixelWidth; pm2vi->hdr.bmiHeader.biHeight = (LONG)pTE->v.PixelHeight; pm2vi->hdr.bmiHeader.biCompression = '1CVA'; pm2vi->hdr.bmiHeader.biPlanes = 1; pm2vi->hdr.bmiHeader.biBitCount = 24; pm2vi->dwProfile = pTE->CodecPrivate[1]; pm2vi->dwLevel = pTE->CodecPrivate[3]; pm2vi->dwFlags = (pTE->CodecPrivate[4] & 3) + 1; BYTE* pSequenceHeader = (BYTE*)pm2vi->dwSequenceHeader; memcpy(pSequenceHeader, data.GetData(), data.GetCount()); pm2vi->cbSequenceHeader = data.GetCount(); mts.Add(mt); } else if(CodecID.Find("V_MPEG4/") == 0) { mt.subtype = FOURCCMap('V4PM'); mt.formattype = FORMAT_MPEG2Video; MPEG2VIDEOINFO* pm2vi = (MPEG2VIDEOINFO*)mt.AllocFormatBuffer(FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + pTE->CodecPrivate.GetCount()); memset(mt.Format(), 0, mt.FormatLength()); pm2vi->hdr.bmiHeader.biSize = sizeof(pm2vi->hdr.bmiHeader); pm2vi->hdr.bmiHeader.biWidth = (LONG)pTE->v.PixelWidth; pm2vi->hdr.bmiHeader.biHeight = (LONG)pTE->v.PixelHeight; pm2vi->hdr.bmiHeader.biCompression = 'V4PM'; pm2vi->hdr.bmiHeader.biPlanes = 1; pm2vi->hdr.bmiHeader.biBitCount = 24; BYTE* pSequenceHeader = (BYTE*)pm2vi->dwSequenceHeader; memcpy(pSequenceHeader, pTE->CodecPrivate.GetData(), pTE->CodecPrivate.GetCount()); pm2vi->cbSequenceHeader = pTE->CodecPrivate.GetCount(); mts.Add(mt); } else if(CodecID.Find("V_REAL/RV") == 0) { mt.subtype = FOURCCMap('00VR' + ((CodecID[9]-0x30)<<16)); mt.formattype = FORMAT_VideoInfo; VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER) + pTE->CodecPrivate.GetCount()); memset(mt.Format(), 0, mt.FormatLength()); memcpy(mt.Format() + sizeof(VIDEOINFOHEADER), pTE->CodecPrivate.GetData(), pTE->CodecPrivate.GetCount()); pvih->bmiHeader.biSize = sizeof(pvih->bmiHeader); pvih->bmiHeader.biWidth = (LONG)pTE->v.PixelWidth; pvih->bmiHeader.biHeight = (LONG)pTE->v.PixelHeight; pvih->bmiHeader.biCompression = mt.subtype.Data1; mts.Add(mt); } else if(CodecID == "V_DIRAC") { mt.subtype = MEDIASUBTYPE_DiracVideo; mt.formattype = FORMAT_DiracVideoInfo; DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)mt.AllocFormatBuffer(FIELD_OFFSET(DIRACINFOHEADER, dwSequenceHeader) + pTE->CodecPrivate.GetCount()); memset(mt.Format(), 0, mt.FormatLength()); dvih->hdr.bmiHeader.biSize = sizeof(dvih->hdr.bmiHeader); dvih->hdr.bmiHeader.biWidth = (LONG)pTE->v.PixelWidth; dvih->hdr.bmiHeader.biHeight = (LONG)pTE->v.PixelHeight; dvih->hdr.dwPictAspectRatioX = dvih->hdr.bmiHeader.biWidth; dvih->hdr.dwPictAspectRatioY = dvih->hdr.bmiHeader.biHeight; BYTE* pSequenceHeader = (BYTE*)dvih->dwSequenceHeader; memcpy(pSequenceHeader, pTE->CodecPrivate.GetData(), pTE->CodecPrivate.GetCount()); dvih->cbSequenceHeader = pTE->CodecPrivate.GetCount(); mts.Add(mt); } else if(CodecID == "V_MPEG2") { BYTE* seqhdr = pTE->CodecPrivate.GetData(); DWORD len = pTE->CodecPrivate.GetCount(); int w = pTE->v.PixelWidth; int h = pTE->v.PixelHeight; if(MakeMPEG2MediaType(mt, seqhdr, len, w, h)) mts.Add(mt); } else if(CodecID == "V_THEORA") { BYTE* thdr = pTE->CodecPrivate.GetData() + 3; mt.majortype = MEDIATYPE_Video; mt.subtype = FOURCCMap('OEHT'); mt.formattype = FORMAT_MPEG2_VIDEO; MPEG2VIDEOINFO* vih = (MPEG2VIDEOINFO*)mt.AllocFormatBuffer(sizeof(MPEG2VIDEOINFO) + pTE->CodecPrivate.GetCount()); memset(mt.Format(), 0, mt.FormatLength()); vih->hdr.bmiHeader.biSize = sizeof(vih->hdr.bmiHeader); vih->hdr.bmiHeader.biWidth = *(WORD*)&thdr[10] >> 4; vih->hdr.bmiHeader.biHeight = *(WORD*)&thdr[12] >> 4; vih->hdr.bmiHeader.biCompression = 'OEHT'; vih->hdr.bmiHeader.biPlanes = 1; vih->hdr.bmiHeader.biBitCount = 24; int nFpsNum = (thdr[22]<<24)|(thdr[23]<<16)|(thdr[24]<<8)|thdr[25]; int nFpsDenum = (thdr[26]<<24)|(thdr[27]<<16)|(thdr[28]<<8)|thdr[29]; if(nFpsNum) vih->hdr.AvgTimePerFrame = (REFERENCE_TIME)(10000000.0 * nFpsDenum / nFpsNum); vih->hdr.dwPictAspectRatioX = (thdr[14]<<16)|(thdr[15]<<8)|thdr[16]; vih->hdr.dwPictAspectRatioY = (thdr[17]<<16)|(thdr[18]<<8)|thdr[19]; mt.bFixedSizeSamples = 0; vih->cbSequenceHeader = pTE->CodecPrivate.GetCount(); memcpy (&vih->dwSequenceHeader, pTE->CodecPrivate.GetData(), vih->cbSequenceHeader); mts.Add(mt); } else if(CodecID.Find("V_VP8") == 0) { mt.subtype = FOURCCMap('08PV'); mt.formattype = FORMAT_VideoInfo; VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER) + pTE->CodecPrivate.GetCount()); memset(mt.Format(), 0, mt.FormatLength()); memcpy(mt.Format() + sizeof(VIDEOINFOHEADER), pTE->CodecPrivate.GetData(), pTE->CodecPrivate.GetCount()); pvih->bmiHeader.biSize = sizeof(pvih->bmiHeader); pvih->bmiHeader.biWidth = (LONG)pTE->v.PixelWidth; pvih->bmiHeader.biHeight = (LONG)pTE->v.PixelHeight; pvih->bmiHeader.biCompression = mt.subtype.Data1; mts.Add(mt); } /* else if(CodecID == "V_DSHOW/MPEG1VIDEO") // V_MPEG1 { mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_MPEG1Payload; mt.formattype = FORMAT_MPEGVideo; MPEG1VIDEOINFO* pm1vi = (MPEG1VIDEOINFO*)mt.AllocFormatBuffer(pTE->CodecPrivate.GetCount()); memcpy(pm1vi, pTE->CodecPrivate.GetData(), pTE->CodecPrivate.GetCount()); mt.SetSampleSize(pm1vi->hdr.bmiHeader.biWidth*pm1vi->hdr.bmiHeader.biHeight*4); mts.Add(mt); } */ REFERENCE_TIME AvgTimePerFrame = 0; if(pTE->v.FramePerSec > 0) AvgTimePerFrame = (REFERENCE_TIME)(10000000i64 / pTE->v.FramePerSec); else if(pTE->DefaultDuration > 0) AvgTimePerFrame = (REFERENCE_TIME)pTE->DefaultDuration / 100; if(AvgTimePerFrame) { for(int i = 0; i < mts.GetCount(); i++) { if(mts[i].formattype == FORMAT_VideoInfo || mts[i].formattype == FORMAT_VideoInfo2 || mts[i].formattype == FORMAT_MPEG2Video) { ((VIDEOINFOHEADER*)mts[i].Format())->AvgTimePerFrame = AvgTimePerFrame; } } } if(pTE->v.DisplayWidth != 0 && pTE->v.DisplayHeight != 0) { for(int i = 0; i < mts.GetCount(); i++) { if(mts[i].formattype == FORMAT_VideoInfo) { DWORD vih1 = FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader); DWORD vih2 = FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader); DWORD bmi = mts[i].FormatLength() - FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader); mt.formattype = FORMAT_VideoInfo2; mt.AllocFormatBuffer(vih2 + bmi); memcpy(mt.Format(), mts[i].Format(), vih1); memset(mt.Format() + vih1, 0, vih2 - vih1); memcpy(mt.Format() + vih2, mts[i].Format() + vih1, bmi); ((VIDEOINFOHEADER2*)mt.Format())->dwPictAspectRatioX = (DWORD)pTE->v.DisplayWidth; ((VIDEOINFOHEADER2*)mt.Format())->dwPictAspectRatioY = (DWORD)pTE->v.DisplayHeight; mts.InsertAt(i++, mt); } else if(mts[i].formattype == FORMAT_MPEG2Video) { ((MPEG2VIDEOINFO*)mts[i].Format())->hdr.dwPictAspectRatioX = (DWORD)pTE->v.DisplayWidth; ((MPEG2VIDEOINFO*)mts[i].Format())->hdr.dwPictAspectRatioY = (DWORD)pTE->v.DisplayHeight; } } } }
HRESULT XnVideoStream::GetStreamCapability(int iIndex, CMediaType& mediaType, VIDEO_STREAM_CONFIG_CAPS& vscc) { // check bounds if(iIndex < 0 || iIndex >= int(m_aSupportedModes.GetSize())) { xnLogVerbose(XN_MASK_FILTER, "GetStreamCapability() - Index %d is out of bounds!", iIndex); return S_FALSE; } VIDEOINFO *pvi = (VIDEOINFO*)mediaType.AllocFormatBuffer(sizeof(VIDEOINFO)); if(NULL == pvi) return(E_OUTOFMEMORY); ZeroMemory(pvi, sizeof(VIDEOINFO)); int xRes = m_aSupportedModes[iIndex].OutputMode.nXRes; int yRes = m_aSupportedModes[iIndex].OutputMode.nYRes; XnUInt64 nFrameTime = 10000000 / m_aSupportedModes[iIndex].OutputMode.nFPS; if (m_aSupportedModes[iIndex].Format == XN_PIXEL_FORMAT_RGB24) { pvi->bmiHeader.biCompression = BI_RGB; } else if (m_aSupportedModes[iIndex].Format == XN_PIXEL_FORMAT_MJPEG) { pvi->bmiHeader.biCompression = 'GPJM'; } else { xnLogError(XN_MASK_FILTER, "Unknown format type!"); return E_UNEXPECTED; } pvi->bmiHeader.biBitCount = 24; pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pvi->bmiHeader.biWidth = xRes; pvi->bmiHeader.biHeight = yRes; pvi->bmiHeader.biPlanes = 1; pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); pvi->bmiHeader.biClrImportant = 0; SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered. SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle pvi->dwBitRate = GetBitmapSize(&pvi->bmiHeader) * // bytes per frame m_aSupportedModes[iIndex].OutputMode.nFPS * // frames per second 8; // bits per byte pvi->dwBitErrorRate = 0; // assume no errors pvi->AvgTimePerFrame = nFrameTime; mediaType.SetType(&MEDIATYPE_Video); mediaType.SetFormatType(&FORMAT_VideoInfo); mediaType.SetTemporalCompression(FALSE); // Work out the GUID for the subtype from the header info. const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader); mediaType.SetSubtype(&SubTypeGUID); mediaType.SetSampleSize(pvi->bmiHeader.biSizeImage); vscc.guid = FORMAT_VideoInfo; vscc.VideoStandard = AnalogVideo_None; vscc.InputSize.cx = xRes; vscc.InputSize.cy = yRes; vscc.MinCroppingSize.cx = xRes; vscc.MinCroppingSize.cy = yRes; vscc.MaxCroppingSize.cx = xRes; vscc.MaxCroppingSize.cy = yRes; vscc.CropGranularityX = 1; vscc.CropGranularityY = 1; vscc.CropAlignX = 1; vscc.CropAlignY = 1; vscc.MinOutputSize.cx = xRes; vscc.MinOutputSize.cy = yRes; vscc.MaxOutputSize.cx = xRes; vscc.MaxOutputSize.cy = yRes; vscc.OutputGranularityX = 1; vscc.OutputGranularityY = 1; vscc.StretchTapsX = 0; vscc.StretchTapsY = 0; vscc.ShrinkTapsX = 0; vscc.ShrinkTapsY = 0; // Frame interval is in 100 nanosecond units vscc.MinFrameInterval = nFrameTime; vscc.MaxFrameInterval = nFrameTime; vscc.MinBitsPerSecond = mediaType.GetSampleSize() * // bytes in frame m_aSupportedModes[iIndex].OutputMode.nFPS * // frames per second 8; // bits per byte vscc.MaxBitsPerSecond = vscc.MinBitsPerSecond; return S_OK; }
HRESULT CConvert::AddVideoGroup(double dSourceFramerate, long nSourceWidth, long nSourceHeight) { // make the root group/composition HRESULT hr = S_OK; hr = m_pTimeline->CreateEmptyNode(&m_pVideoGroupObj, TIMELINE_MAJOR_TYPE_GROUP); if(FAILED( hr )) { return hr; } CComQIPtr<IAMTimelineGroup, &IID_IAMTimelineGroup> pVideoGroup(m_pVideoGroupObj); //// Set Media Type CMediaType VideoGroupType; VideoGroupType.SetType(&MEDIATYPE_Video); VideoGroupType.SetSubtype(&MEDIASUBTYPE_RGB24); VideoGroupType.SetFormatType(&FORMAT_VideoInfo); VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)VideoGroupType.AllocFormatBuffer(sizeof(VIDEOINFOHEADER)); ZeroMemory(pVideoHeader, sizeof(VIDEOINFOHEADER)); pVideoHeader->bmiHeader.biBitCount = 24; pVideoHeader->bmiHeader.biWidth = nSourceWidth; pVideoHeader->bmiHeader.biHeight = nSourceHeight; pVideoHeader->bmiHeader.biPlanes = 1; pVideoHeader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pVideoHeader->bmiHeader.biSizeImage = DIBSIZE(pVideoHeader->bmiHeader); VideoGroupType.SetSampleSize(DIBSIZE(pVideoHeader->bmiHeader)); hr = pVideoGroup->SetMediaType(&VideoGroupType); if(FAILED( hr )) { return hr; } // double dRequiredInputFramerate = 0; // m_pMPEGWriterProps->SetSourceFramerate(dSourceFramerate, &dRequiredInputFramerate); // hr = pVideoGroup->SetOutputFPS(15); /* if (GetOutputFPS() != 0) { // the user set a framerate hr = pVideoGroup->SetOutputFPS(GetOutputFPS()); GetMPEGWriterProps()->OverrideSourceFPS(GetOutputFPS()); } else if (IsFrameRateSupported((float)dSourceFramerate)) { // the user did not set a framerate. If the source // framerate is supported, we use it. hr = pVideoGroup->SetOutputFPS(dSourceFramerate); GetMPEGWriterProps()->OverrideSourceFPS((float)dSourceFramerate); } else { // the user did not want a framerate, and the framerate // of the file is not supported. We use 25fps hr = pVideoGroup->SetOutputFPS(25); GetMPEGWriterProps()->OverrideSourceFPS(25); } */ hr = m_pTimeline->AddGroup(m_pVideoGroupObj); return hr; }
HRESULT CEASpliterFilter::CreateOutputs(IAsyncReader* pAsyncReader) { SVP_LogMsg5(L" CEASpliterFilter::CreateOutputs"); CheckPointer(pAsyncReader, E_POINTER); HRESULT hr = E_FAIL; m_pFile.Free(); m_pFile.Attach(new CEAFile(pAsyncReader, hr)); if(!m_pFile) return E_OUTOFMEMORY; if(FAILED(hr)) {m_pFile.Free(); return hr;} m_rtNewStart = m_rtCurrent = 0; m_rtNewStop = m_rtStop = m_rtDuration = 0; m_pFile->Seek(0); DWORD EAFileTag = bswap_32((DWORD)m_pFile->BitRead(32)); switch(EAFileTag) { case ISNh_TAG: case SCHl_TAG: case SEAD_TAG: case SHEN_TAG: case kVGT_TAG: case MADk_TAG: case MPCh_TAG: case MVhd_TAG: case MVIh_TAG: SVP_LogMsg5(L"GotEA Tag"); break; default: return hr; } m_pFile->Seek(0); EaDemuxContext *ea = (EaDemuxContext *)m_pea; SVP_LogMsg5(L"EABefore Info %x %x", ea->audio_codec, ea->video_codec);; process_header(); SVP_LogMsg5(L"GotEA Info %d %d", ea->audio_codec, ea->video_codec);; int idPin = 0; while(ea->video_codec){ CMediaType mt; mt.SetSampleSize(1); mt.subtype = GUID_NULL; switch(ea->video_codec){ case CODEC_ID_VP6: { mt.majortype = MEDIATYPE_Video; mt.formattype = FORMAT_VideoInfo; VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.AllocFormatBuffer(sizeof(VIDEOINFOHEADER)); memset(vih, 0, sizeof(VIDEOINFOHEADER)); BITMAPINFOHEADER* bih = &vih->bmiHeader; vih->bmiHeader.biWidth = ea->width; vih->bmiHeader.biHeight = ea->height; bih->biCompression = '26PV'; mt.subtype = MEDIASUBTYPE_VP62; } break; case CODEC_ID_MPEG2VIDEO: //TODO: handle MPEG2 in vp6 /*mt.formattype = FORMAT_MPEG2Video; MPEG2VIDEOINFO* vih = (MPEG2VIDEOINFO*)mt.AllocFormatBuffer(FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + headerSize); memset(vih, 0, mt.FormatLength()); vih->hdr.bmiHeader.biSize = sizeof(vih->hdr.bmiHeader); vih->hdr.bmiHeader.biPlanes = 1; vih->hdr.bmiHeader.biBitCount = 24; vih->hdr.bmiHeader.biWidth = ea->width; vih->hdr.bmiHeader.biHeight = ea->height; */ case CODEC_ID_MDEC: case CODEC_ID_CMV: case CODEC_ID_TGV: case CODEC_ID_TGQ: case CODEC_ID_TQI: case CODEC_ID_MAD: SVP_LogMsg5(L"sorry we cant handle this now"); break; } if(mt.subtype == GUID_NULL) break; CAtlArray<CMediaType> mts; mts.Add(mt); CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, L"Video", this, this, &hr)); EXECUTE_ASSERT(SUCCEEDED(AddOutputPin(idPin, pPinOut))); idPin++; break; } if(ea->audio_codec){ CMediaType mt; mt.SetSampleSize(1); mt.majortype = MEDIATYPE_Audio; mt.formattype = FORMAT_WaveFormatEx; switch(ea->audio_codec){ case CODEC_ID_MP3: mt.subtype = MEDIASUBTYPE_MP3; { WAVEFORMATEX* wfe = (WAVEFORMATEX*)mt.AllocFormatBuffer(sizeof(WAVEFORMATEX)); memset(wfe, 0, sizeof(WAVEFORMATEX)); wfe->nSamplesPerSec = ea->sample_rate; wfe->wBitsPerSample = ea->bytes * 8; wfe->nChannels = ea->num_channels; } break; case CODEC_ID_ADPCM_EA: case CODEC_ID_ADPCM_EA_R1: case CODEC_ID_ADPCM_EA_R2: case CODEC_ID_ADPCM_EA_R3: case CODEC_ID_PCM_S16LE_PLANAR: case CODEC_ID_PCM_S8: case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_MULAW: case CODEC_ID_ADPCM_IMA_EA_EACS: case CODEC_ID_ADPCM_IMA_EA_SEAD: break; } if(mt.subtype != GUID_NULL){ CAtlArray<CMediaType> mts; mts.Add(mt); CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, L"Audio", this, this, &hr)); EXECUTE_ASSERT(SUCCEEDED(AddOutputPin(idPin, pPinOut))); } } SVP_LogMsg5(L"EA Out %d", m_pOutputs.GetCount()); m_rtNewStop = m_rtStop = m_rtDuration ; return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL; }
static int v4w_open_videodevice(V4wState *s) { // Initialize COM CoInitialize(NULL); // get a Graph HRESULT hr=s->m_pGraph.CoCreateInstance(CLSID_FilterGraph); if(FAILED(hr)) { return -1; } // get a CaptureGraphBuilder2 hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2); if(FAILED(hr)) { return -2; } // connect capture graph builder with the graph s->m_pBuilder->SetFiltergraph(s->m_pGraph); // get mediacontrol so we can start and stop the filter graph hr=s->m_pGraph.QueryInterface(&(s->m_pControl)); if(FAILED(hr)) { return -3; } #ifdef _DEBUG HANDLE m_hLogFile=CreateFile(L"DShowGraphLog.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(m_hLogFile!=INVALID_HANDLE_VALUE) { hr=s->m_pGraph->SetLogFile((DWORD_PTR)m_hLogFile); /* ASSERT(SUCCEEDED(hr)); */ } //AddGraphToRot(s->m_pGraph, &s->rotregvalue); #endif ICreateDevEnum *pCreateDevEnum = NULL; IEnumMoniker *pEnumMoniker = NULL; IMoniker *pMoniker = NULL; ULONG nFetched = 0; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum); if(FAILED(hr)) { return -4; } hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0); if (FAILED(hr) || pEnumMoniker == NULL) { //printf("no device\n"); return -5; } pEnumMoniker->Reset(); int pos=0; while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) ) { if (pos>=s->devidx) break; pos++; pMoniker->Release(); pMoniker=NULL; } if(pMoniker==NULL) { return -6; } hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&s->m_pDeviceFilter ); if(FAILED(hr)) { return -7; } s->m_pGraph->AddFilter(s->m_pDeviceFilter, L"Device Filter"); pMoniker->Release(); pEnumMoniker->Release(); pCreateDevEnum->Release(); if (try_format(s, s->pix_fmt)==0) s->pix_fmt = s->pix_fmt; else if (try_format(s,MS_YUV420P)==0) s->pix_fmt = MS_YUV420P; else if (try_format(s,MS_YUY2)==0) s->pix_fmt = MS_YUY2; else if (try_format(s,MS_YUYV)==0) s->pix_fmt = MS_YUYV; else if (try_format(s,MS_UYVY)==0) s->pix_fmt = MS_UYVY; else if (try_format(s,MS_RGB24)==0) s->pix_fmt = MS_RGB24; else { ms_error("Unsupported video pixel format."); return -8; } if (s->pix_fmt == MS_YUV420P) ms_message("Driver supports YUV420P, using that format."); else if (s->pix_fmt == MS_YUY2) ms_message("Driver supports YUY2 (UYVY), using that format."); else if (s->pix_fmt == MS_YUYV) ms_message("Driver supports YUV422, using that format."); else if (s->pix_fmt == MS_UYVY) ms_message("Driver supports UYVY, using that format."); else if (s->pix_fmt == MS_RGB24) ms_message("Driver supports RGB24, using that format."); if (try_format_size(s, s->pix_fmt, s->vsize.width, s->vsize.height)==0) ms_message("Selected Size: %ix%i.", s->vsize.width, s->vsize.height); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H); else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H)==0) ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H); else { ms_error("No supported size found for format."); /* size not supported? */ return -9; } // get DXFilter s->m_pDXFilter = new CDXFilter(NULL, &hr, FALSE); if(s->m_pDXFilter==NULL) { return -10; } s->m_pDXFilter->AddRef(); CMediaType mt; mt.SetType(&MEDIATYPE_Video); GUID m = MEDIASUBTYPE_RGB24; if (s->pix_fmt == MS_YUV420P) m = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0')); else if (s->pix_fmt == MS_YUY2) m = MEDIASUBTYPE_YUY2; else if (s->pix_fmt == MS_YUYV) m = MEDIASUBTYPE_YUYV; else if (s->pix_fmt == MS_UYVY) m = MEDIASUBTYPE_UYVY; else if (s->pix_fmt == MS_RGB24) m = MEDIASUBTYPE_RGB24; mt.SetSubtype(&m); mt.formattype = FORMAT_VideoInfo; mt.SetTemporalCompression(FALSE); VIDEOINFO *pvi = (VIDEOINFO *) mt.AllocFormatBuffer(sizeof(VIDEOINFO)); if (NULL == pvi) return -11; ZeroMemory(pvi, sizeof(VIDEOINFO)); if (s->pix_fmt == MS_YUV420P) pvi->bmiHeader.biCompression = MAKEFOURCC('I','4','2','0'); else if (s->pix_fmt == MS_YUY2) pvi->bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','2'); else if (s->pix_fmt == MS_YUYV) pvi->bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','V'); else if (s->pix_fmt == MS_UYVY) pvi->bmiHeader.biCompression = MAKEFOURCC('U','Y','V','Y'); else if (s->pix_fmt == MS_RGB24) pvi->bmiHeader.biCompression = BI_RGB; if (s->pix_fmt == MS_YUV420P) pvi->bmiHeader.biBitCount = 12; else if (s->pix_fmt == MS_YUY2) pvi->bmiHeader.biBitCount = 16; else if (s->pix_fmt == MS_YUYV) pvi->bmiHeader.biBitCount = 16; else if (s->pix_fmt == MS_UYVY) pvi->bmiHeader.biBitCount = 16; else if (s->pix_fmt == MS_RGB24) pvi->bmiHeader.biBitCount = 24; pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pvi->bmiHeader.biWidth = s->vsize.width; pvi->bmiHeader.biHeight = s->vsize.height; pvi->bmiHeader.biPlanes = 1; pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); pvi->bmiHeader.biClrImportant = 0; mt.SetSampleSize(pvi->bmiHeader.biSizeImage); mt.SetFormat((BYTE*)pvi, sizeof(VIDEOINFO)); hr = s->m_pDXFilter->SetAcceptedMediaType(&mt); if(FAILED(hr)) { return -12; } hr = s->m_pDXFilter->SetCallback(Callback); if(FAILED(hr)) { return -13; } hr = s->m_pDXFilter->QueryInterface(IID_IBaseFilter, (LPVOID *)&s->m_pIDXFilter); if(FAILED(hr)) { return -14; } hr = s->m_pGraph->AddFilter(s->m_pIDXFilter, L"DXFilter Filter"); if(FAILED(hr)) { return -15; } // get null renderer hr=s->m_pNullRenderer.CoCreateInstance(CLSID_NullRenderer); if(FAILED(hr)) { return -16; } if (s->m_pNullRenderer!=NULL) { s->m_pGraph->AddFilter(s->m_pNullRenderer, L"Null Renderer"); } hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); if (FAILED(hr)) { //hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, // &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); if (FAILED(hr)) { return -17; } } //m_pDXFilter->SetBufferSamples(TRUE); s_callback = s; hr = s->m_pControl->Run(); if(FAILED(hr)) { return -18; } s->rotregvalue=1; return 0; }