Mercurial > mplayer.hg
view loader/dshow/DS_Filter.c @ 30251:fbb33d643fe6
Remove hackish and not actually working code to make vidix compile with
compilers without inline assembly.
Almost no OS provides inb() etc. in its libraries, and removing the
broken fallback code makes it compile on Solaris with Sun C compiler.
author | reimar |
---|---|
date | Tue, 12 Jan 2010 20:20:49 +0000 |
parents | 008338d7679f |
children | 31a00b2a621f |
line wrap: on
line source
/* * Modified for use with MPlayer, detailed changelog at * http://svn.mplayerhq.hu/mplayer/trunk/ */ #include "config.h" #include "DS_Filter.h" #include "loader/drv.h" #include "loader/com.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include "loader/win32.h" // printf macro typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); #ifndef WIN32_LOADER const GUID IID_IUnknown = { 0x00000000, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; const GUID IID_IClassFactory = { 0x00000001, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; HRESULT STDCALL CoInitialize(LPVOID pvReserved); void STDCALL CoUninitialize(void); #endif static void DS_Filter_Start(DS_Filter* This) { HRESULT hr; //Debug printf("DS_Filter_Start(%p)\n", This); hr = This->m_pFilter->vt->Run(This->m_pFilter, (REFERENCE_TIME)0); if (hr != 0) { Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); } } static void DS_Filter_Stop(DS_Filter* This) { if (This->m_pAll) { //Debug printf("DS_Filter_Stop(%p)\n", This); This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME This->m_pAll->vt->Release((IUnknown*)This->m_pAll); This->m_pAll = 0; } } void DS_Filter_Destroy(DS_Filter* This) { This->Stop(This); if (This->m_pOurInput) This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput); if (This->m_pInputPin) This->m_pInputPin->vt->Disconnect(This->m_pInputPin); if (This->m_pOutputPin) This->m_pOutputPin->vt->Disconnect(This->m_pOutputPin); if (This->m_pFilter) This->m_pFilter->vt->Release((IUnknown*)This->m_pFilter); if (This->m_pOutputPin) This->m_pOutputPin->vt->Release((IUnknown*)This->m_pOutputPin); if (This->m_pInputPin) This->m_pInputPin->vt->Release((IUnknown*)This->m_pInputPin); if (This->m_pImp) This->m_pImp->vt->Release((IUnknown*)This->m_pImp); if (This->m_pOurOutput) This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput); if (This->m_pParentFilter) This->m_pParentFilter->vt->Release((IUnknown*)This->m_pParentFilter); if (This->m_pSrcFilter) This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter); // FIXME - we are still leaving few things allocated! if (This->m_iHandle) FreeLibrary((unsigned)This->m_iHandle); free(This); #ifdef WIN32_LOADER CodecRelease(); #else CoUninitialize(); #endif } static HRESULT STDCALL DS_Filter_CopySample(void* pUserData,IMediaSample* pSample){ BYTE* pointer; int len; SampleProcUserData* pData=pUserData; Debug printf("CopySample called(%p,%p)\n",pSample,pUserData); if (pSample->vt->GetPointer(pSample, &pointer)) return 1; len = pSample->vt->GetActualDataLength(pSample); if (len == 0) len = pSample->vt->GetSize(pSample);//for iv50 pData->frame_pointer = pointer; pData->frame_size = len; /* FILE* file=fopen("./uncompr.bmp", "wb"); char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00}; *(int*)(&head[2])=len+0x36; fwrite(head, 14, 1, file); fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file); fwrite(pointer, len, 1, file); fclose(file); */ return 0; } DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt,SampleProcUserData* pUserData) { int init = 0; // char eb[250]; const char* em = NULL; MemAllocator* tempAll; ALLOCATOR_PROPERTIES props,props1; DS_Filter* This = malloc(sizeof(DS_Filter)); if (!This) return NULL; #ifdef WIN32_LOADER CodecAlloc(); #else CoInitialize(0L); #endif /* tempAll is not used anywhere. MemAllocatorCreate() is called to ensure that RegisterComObject for IMemoryAllocator will be called before possible call to CoCreateInstance(...,&IID_IMemoryAllocator,...) from binary codec. */ tempAll=MemAllocatorCreate(); This->m_pFilter = NULL; This->m_pInputPin = NULL; This->m_pOutputPin = NULL; This->m_pSrcFilter = NULL; This->m_pParentFilter = NULL; This->m_pOurInput = NULL; This->m_pOurOutput = NULL; This->m_pAll = NULL; This->m_pImp = NULL; This->Start = DS_Filter_Start; This->Stop = DS_Filter_Stop; for (;;) { GETCLASS func; struct IClassFactory* factory = NULL; struct IUnknown* object = NULL; IEnumPins* enum_pins = 0; IPin* array[256]; ULONG fetched; HRESULT result; unsigned int i; This->m_iHandle = LoadLibraryA(dllname); if (!This->m_iHandle) { em = "could not open DirectShow DLL"; break; } func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject"); if (!func) { em = "illegal or corrupt DirectShow DLL"; break; } result = func(id, &IID_IClassFactory, (void*)&factory); if (result || !factory) { em = "no such class object"; break; } result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void*)&object); factory->vt->Release((IUnknown*)factory); if (result || !object) { em = "class factory failure"; break; } result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void*)&This->m_pFilter); object->vt->Release((IUnknown*)object); if (result || !This->m_pFilter) { em = "object does not provide IBaseFilter interface"; break; } // enumerate pins result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins); if (result || !enum_pins) { em = "could not enumerate pins"; break; } enum_pins->vt->Reset(enum_pins); result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched); Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result); for (i = 0; i < fetched; i++) { PIN_DIRECTION direction = -1; array[i]->vt->QueryDirection(array[i], &direction); if (!This->m_pInputPin && direction == PINDIR_INPUT) { This->m_pInputPin = array[i]; This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin); } if (!This->m_pOutputPin && direction == PINDIR_OUTPUT) { This->m_pOutputPin = array[i]; This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin); } array[i]->vt->Release((IUnknown*)(array[i])); } if (!This->m_pInputPin) { em = "could not find input pin"; break; } if (!This->m_pOutputPin) { em = "could not find output pin"; break; } result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin, &IID_IMemInputPin, (void*)&This->m_pImp); if (result) { em = "could not get IMemInputPin interface"; break; } This->m_pOurType = in_fmt; This->m_pDestType = out_fmt; result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType); if (result) { em = "source format is not accepted"; break; } This->m_pParentFilter = CBaseFilter2Create(); This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter); This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter); This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput); result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin, This->m_pOurInput, This->m_pOurType); if (result) { em = "could not connect to input pin"; break; } result = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll); if (result || !This->m_pAll) { em="error getting IMemAllocator interface"; break; } //Seting allocator property according to our media type props.cBuffers=1; props.cbBuffer=This->m_pOurType->lSampleSize; props.cbAlign=1; props.cbPrefix=0; This->m_pAll->vt->SetProperties(This->m_pAll, &props, &props1); //Notify remote pin about choosed allocator This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0); This->m_pOurOutput = COutputPinCreate(This->m_pDestType,DS_Filter_CopySample,pUserData); result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, (IPin*) This->m_pOurOutput, This->m_pDestType); if (result) { em = "could not connect to output pin"; break; } init++; break; } tempAll->vt->Release(tempAll); if (!init) { DS_Filter_Destroy(This); printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em, dllname); This = 0; } return This; }