Using DirectShow video on an OpenGL polygon.
Is it possible to use DirectShow to somehow make a video be displayed on a polygon that was created using OpenGL. If it is possible, how would I do it? Links and source code would help a lot. Thanks.
Use a sample grabber filter, and have it dump it into a 2d texture. Then apply the texture to the triangle. Or you can do a draw pixels and just draw the pixels to the screen. I would use buffer mode of the grabber filter, not callback, that way you only get the sample when u want it.
edit: One thing that took me a while to figure out is that the grabber will return bgr and so u need to create ur texture with a bgr extension. Also create it with mipmaps because the scale will probably not be power of 2.
edit: One thing that took me a while to figure out is that the grabber will return bgr and so u need to create ur texture with a bgr extension. Also create it with mipmaps because the scale will probably not be power of 2.
A sample grabber filter? I just want a video to be directly blitted onto a polygon like a texture. I believe DirectX has some kind of function lieing around in the DirectShow that I need to do this. I just don't know. Can you if possible show some kind of source code if you really know how to do this? And doing it by pixels maybe too slow. I'm looking for realtime speed. Plus I know very little of what I'm doing in rendering videos to polygons obviously.
what kind of video? if you just want avi then there are windows api's to get you the data to create ur texture, in the end your going to have to create a texture every frame of ur video and cover your polygon in it. If you want the software to automaticaly play any kind of video, mpeg, avi, dvd, u name it, then direct show is a good idea. Directshow makes a graph to render what ever kind of file you tell it to. In the end there is a video renderer that actualy plays the video on a window. You want to intercept the stream before it gets to the video renderer with you sample grabber, then your polygon and opengl program are the video renderer. heres my code it may not mean much to you so you'll have to do some hoemwork on directshow.
This function actualy creates the texture from the grabber.
I dont know what version of my program i took this from so it basicaly like a test and unfinished, but it works.
I call this function to load a video file. Or audio file.
MSDN is your friend, directshow sdk.
This function actualy creates the texture from the grabber.
I dont know what version of my program i took this from so it basicaly like a test and unfinished, but it works.
void cPlayer::UpdateVBuf(){ if (!opened || !isvideo) return; if(false) { if (!vbuf) { pGrabber->GetCurrentBuffer(&vbufsize, NULL); vbuf = new unsigned char[vbufsize]; //glGenTextures(1, &tex); if (!vbuf) { Msg("realbad!"); } //Msg("make tex"); } pGrabber->GetCurrentBuffer(&vbufsize, (long*)vbuf); } else { pGrabber->GetCurrentBuffer(&vbufsize, NULL); delete[] vbuf; vbuf = new unsigned char[vbufsize]; if (!vbuf) { Msg("realbad!"); } pGrabber->GetCurrentBuffer(&vbufsize, (long*)vbuf); } AM_MEDIA_TYPE mt; HRESULT hr = pGrabber->GetConnectedMediaType(&mt); if (FAILED(hr)) { // Return error code. } // Examine the format block. VIDEOINFOHEADER *pVih; if ((mt.formattype == FORMAT_VideoInfo) && (mt.cbFormat >= sizeof(VIDEOINFOHEADER)) && (mt.pbFormat != NULL) ) { pVih = (VIDEOINFOHEADER*)mt.pbFormat; } else { return; } //if (vbufsize == 0) //Msg("zero buffer!"); if (vbufsize > 0) { glBindTexture(GL_TEXTURE_2D, tex); //GL_BGR_EXT gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pVih->bmiHeader.biWidth,pVih->bmiHeader.biHeight,GL_BGR_EXT, GL_UNSIGNED_BYTE, vbuf); //gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pVih->bmiHeader.biWidth,pVih->bmiHeader.biHeight,GL_RGB, GL_UNSIGNED_BYTE, vbuf); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // Linear Filtering glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // Linear Filtering }}
I call this function to load a video file. Or audio file.
bool cPlayer::Open(char *filename){ USES_CONVERSION; WCHAR wFile[500]; HRESULT hr; wcsncpy(wFile, T2W(filename), NUMELMS(wFile)-1); wFile[500-1] = 0; JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGB)); if(SUCCEEDED(hr)) { HANDLE logfile; char logfilename[500]; // create win32 file handle sprintf(logfilename, "c:\\graph.txt", ""); logfile = CreateFile(logfilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); pGB->SetLogFile((DWORD_PTR)logfile); hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pGrab); if (FAILED(hr)) { return false; } pGrab->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber); //JIF(pGrab->QueryInterface(IID_ISampleGrabberCB, (void**)&pSCB)); AM_MEDIA_TYPE mt; ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB24; hr = pGrabber->SetMediaType(&mt); //hr = CoCreateInstance(CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, // IID_IBaseFilter , (void**)&pSrc); //if (FAILED(hr)) //{ // Msg("load failed"); // return false; //} //hr = pGB->AddFilter(pSrc, L"Reader"); //if (FAILED(hr)) //{ // // Msg("load failed"); // return false; //} ////mt.majortype = MEDIATYPE_Stream; //JIF(pGB->QueryInterface(IID_IFileSourceFilter, (void **)&pSrcCntr)); //pSrcCntr->Load(wFile, &mt); // //hr = pGB->AddSourceFilter(wFile, L"Source", &pSrc); //if (FAILED(hr)) //{ // Msg("load failed"); // return false; //} hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNR); if (FAILED(hr)) { Msg("load failed"); return false; } JIF(pGB->RenderFile(wFile, NULL)); JIF(pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV)); JIF(pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW)); if (!pBV || !pVW) isvideo = false; else isvideo = true; hr = pGB->AddFilter(pNR, L"Null Renderer"); if (FAILED(hr)) { Msg("load failed"); return false; } hr = pGB->AddFilter(pGrab, L"Sample Grabber"); if (FAILED(hr)) { return false; } if (isvideo) { IBaseFilter *tvr; hr = pGB->FindFilterByName(L"Video Renderer", &tvr); if (FAILED(hr)) { isvideo = false; goto b; } JIF(pGB->RemoveFilter(tvr)); IEnumFilters *fenum; JIF(pGB->EnumFilters(&fenum)); IBaseFilter *efilt; while(fenum->Next(1, &efilt, 0) == S_OK) { IPin *pin; if (!FAILED(GetUnconnectedPin(efilt, PINDIR_OUTPUT, &pin))) { //found an good shot if (!FAILED(ConnectFilters(pGB, efilt, pGrab))) { goto a; } /*else Msg(TEXT("FAILED(hr=0x%x)", hr));*/ } //else //Msg(TEXT("FAILED(hr=0x%x)", hr)); } Msg("could not find an empty connecteable filter");a: JIF(ConnectFilters(pGB, pGrab, pNR)); }b: //pGrabber->SetCallback(pSCB, 1); JIF(pGrab->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber)); pGrabber->SetOneShot(false); pGrabber->SetBufferSamples(true); pGB->SetDefaultSyncSource(); JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC)); JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME)); JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS)); JIF(pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP)); JIF(pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV)); JIF(pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA)); JIF(pME->SetNotifyWindow((OAHWND)apphnd, WM_GRAPHNOTIFY, 0)); IVideoFrameStep *pFSTest = NULL; hr = pGB->QueryInterface(__uuidof(IVideoFrameStep), (PVOID *)&pFSTest); //if (FAILED(hr)) //return FALSE; hr = pFSTest->CanStep(0L, NULL); if (hr == S_OK) { pFS = pFSTest; } else { pFSTest->Release(); } IMoniker * pMoniker; IRunningObjectTable *pROT; if (FAILED(GetRunningObjectTable(0, &pROT))) { return E_FAIL; } WCHAR wsz[128]; wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pGB, GetCurrentProcessId()); HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); if (SUCCEEDED(hr)) { hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pGB, pMoniker, &g_dwGraphRegister); pMoniker->Release(); } pROT->Release(); if (FAILED(hr)) { Msg(TEXT("Failed to register filter graph with ROT! hr=0x%x"), hr); g_dwGraphRegister = 0; } SaveGraphFile(pGB, L"c:\\graph.grf"); opened = true; Stop(); return true; } return false; Msg("load failed");}
MSDN is your friend, directshow sdk.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement