# HG changeset patch # User voroshil # Date 1172861530 0 # Node ID 49f01f8fbd601819c19353af7022fef78914203f # Parent b2e4557a3160ba2f92eb763e4b2ba4ed003e22f7 Rework of copying samples from directshow codecs. Using callback function provided by filter to store and process samples from codec instead of explicit typecast to DS_Filter. diff -r b2e4557a3160 -r 49f01f8fbd60 loader/dshow/DS_AudioDecoder.c --- a/loader/dshow/DS_AudioDecoder.c Fri Mar 02 17:59:19 2007 +0000 +++ b/loader/dshow/DS_AudioDecoder.c Fri Mar 02 18:52:10 2007 +0000 @@ -35,6 +35,9 @@ typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**); +static SampleProcUserData sampleProcData; + + DS_AudioDecoder * DS_AudioDecoder_Open(char* dllname, GUID* guid, WAVEFORMATEX* wf) //DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf) { @@ -98,7 +101,7 @@ /*try*/ { ALLOCATOR_PROPERTIES props, props1; - this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); + this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType,&sampleProcData); if( !this->m_pDS_Filter ) { free(this); return NULL; @@ -148,15 +151,9 @@ in_size -= in_size%this->in_fmt.nBlockAlign; while (in_size>0) { - unsigned int frame_size = 0; - char* frame_pointer; IMediaSample* sample=0; char* ptr; int result; - -// this->m_pOurOutput->SetFramePointer(out_data+written); - this->m_pDS_Filter->m_pOurOutput->SetFramePointer(this->m_pDS_Filter->m_pOurOutput,&frame_pointer); - this->m_pDS_Filter->m_pOurOutput->SetFrameSizePointer(this->m_pDS_Filter->m_pOurOutput,(long*)&frame_size); this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0); if (!sample) { @@ -171,15 +168,15 @@ result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample); if (result) Debug printf("DS_AudioDecoder::Convert() Error: putting data into input pin %x\n", result); - if ((written + frame_size) > out_size) + if ((written + sampleProcData.frame_size) > out_size) { sample->vt->Release((IUnknown*)sample); break; } - memcpy((uint8_t*)out_data + written, frame_pointer, frame_size); + memcpy((uint8_t*)out_data + written, sampleProcData.frame_pointer, sampleProcData.frame_size); sample->vt->Release((IUnknown*)sample); read+=this->in_fmt.nBlockAlign; - written+=frame_size; + written+=sampleProcData.frame_size; break; } if (size_read) diff -r b2e4557a3160 -r 49f01f8fbd60 loader/dshow/DS_Filter.c --- a/loader/dshow/DS_Filter.c Fri Mar 02 17:59:19 2007 +0000 +++ b/loader/dshow/DS_Filter.c Fri Mar 02 18:52:10 2007 +0000 @@ -95,9 +95,34 @@ #endif } +static HRESULT STDCALL DS_Filter_CopySample(void* pUserData,IMediaSample* pSample){ + char* pointer; + int len; + SampleProcUserData* pData=(SampleProcUserData*)pUserData; + Debug printf("CopySample called(%p,%p)\n",pSample,pUserData); + if (pSample->vt->GetPointer(pSample, (BYTE**) &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) + AM_MEDIA_TYPE* out_fmt,SampleProcUserData* pUserData) { int init = 0; // char eb[250]; @@ -262,7 +287,7 @@ //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); + This->m_pOurOutput = COutputPinCreate(This->m_pDestType,DS_Filter_CopySample,pUserData); result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, (IPin*) This->m_pOurOutput, diff -r b2e4557a3160 -r 49f01f8fbd60 loader/dshow/DS_Filter.h --- a/loader/dshow/DS_Filter.h Fri Mar 02 17:59:19 2007 +0000 +++ b/loader/dshow/DS_Filter.h Fri Mar 02 18:52:10 2007 +0000 @@ -8,6 +8,11 @@ extern "C" { #endif +typedef struct { + char* frame_pointer; + long frame_size; +} SampleProcUserData; + /** User will allocate and fill format structures, call Create(), and then set up m_pAll. @@ -35,7 +40,7 @@ }; DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, - AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt); + AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt,SampleProcUserData* pUserData); void DS_Filter_Destroy(DS_Filter* This); #if defined(__cplusplus) diff -r b2e4557a3160 -r 49f01f8fbd60 loader/dshow/DS_VideoDecoder.c --- a/loader/dshow/DS_VideoDecoder.c Fri Mar 02 17:59:19 2007 +0000 +++ b/loader/dshow/DS_VideoDecoder.c Fri Mar 02 18:52:10 2007 +0000 @@ -31,6 +31,7 @@ int m_bIsDivX; // for speed int m_bIsDivX4; // for speed }; +static SampleProcUserData sampleProcData; #include "DS_VideoDecoder.h" @@ -175,7 +176,7 @@ * ((this->iv.m_obh.biBitCount + 7) / 8); - this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); + this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType,&sampleProcData); if (!this->m_pDS_Filter) { @@ -307,10 +308,6 @@ } //cout << "DECODE " << (void*) pImage << " d: " << (void*) pImage->Data() << endl; - if (pImage) - { - this->m_pDS_Filter->m_pOurOutput->SetPointer2(this->m_pDS_Filter->m_pOurOutput,pImage); - } sample->vt->SetActualDataLength(sample, size); @@ -340,7 +337,10 @@ { Debug printf("DS_VideoDecoder::DecodeInternal() error putting data into input pin %x\n", result); } - + if (pImage) + { + memcpy(pImage, sampleProcData.frame_pointer, sampleProcData.frame_size); + } sample->vt->Release((IUnknown*)sample); #if 0 diff -r b2e4557a3160 -r 49f01f8fbd60 loader/dshow/outputpin.c --- a/loader/dshow/outputpin.c Fri Mar 02 17:59:19 2007 +0000 +++ b/loader/dshow/outputpin.c Fri Mar 02 18:52:10 2007 +0000 @@ -709,36 +709,14 @@ static HRESULT STDCALL COutputMemPin_Receive(IMemInputPin* This, /* [in] */ IMediaSample* pSample) { - COutputMemPin* mp = (COutputMemPin*)This; - char* pointer; - int len; - Debug printf("COutputMemPin_Receive(%p) called\n", This); if (!pSample) return E_INVALIDARG; - if (pSample->vt->GetPointer(pSample, (BYTE**) &pointer)) - return -1; - len = pSample->vt->GetActualDataLength(pSample); - if (len == 0) - len = pSample->vt->GetSize(pSample);//for iv50 - //if(me.frame_pointer)memcpy(me.frame_pointer, pointer, len); - if (mp->frame_pointer) - *(mp->frame_pointer) = pointer; - if (mp->frame_size_pointer) - *(mp->frame_size_pointer) = 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); -*/ -// pSample->vt->Release((IUnknown*)pSample); - - return 0; + if(((COutputMemPin*)This)->parent->SampleProc) + return ((COutputMemPin*)This)->parent->SampleProc(((COutputMemPin*)This)->parent->pUserData,pSample); + //reject sample + return S_FALSE; } /** @@ -772,7 +750,13 @@ /* [in] */ long nSamples, /* [out] */ long *nSamplesProcessed) { - return output_unimplemented("COutputMemPin_ReceiveMultiple", This); + HRESULT hr; + Debug printf("COutputMemPin_ReceiveMultiple(%p) %d\n", This,nSamples); + for(*nSamplesProcessed=0; *nSamplesProcessed < nSamples; *nSamplesProcessed++) { + hr = This->vt->Receive(This,pSamples[*nSamplesProcessed]); + if (hr != S_OK) break; + } + return hr; } /** @@ -790,44 +774,6 @@ } /** - * \brief COutputPin::SetFramePointer (sets internal frame pointer to an external buffer) - * - * \param[in] This pointer to COutputPin class - * \param[in] z new pointer - * - */ -static void COutputPin_SetFramePointer(COutputPin* This, char** z) -{ - This->mempin->frame_pointer = z; -} - -/** - * \brief COutputPin::SetFramePointer2 (sets allocator's pointer to an external buffer) - * - * \param[in] This pointer to COutputPin class - * \param[in] z new pointer - * - */ -static void COutputPin_SetPointer2(COutputPin* This, char* p) -{ - if (This->mempin->pAllocator) - // fixme - This->mempin->pAllocator->SetPointer(This->mempin->pAllocator, p); -} - -/** - * \brief COutputPin::SetFrameSizePointer (sets pointer to variable that receives frame size) - * - * \param[in] This pointer to COutputPin class - * \param[in] z new pointer - * - */ -static void COutputPin_SetFrameSizePointer(COutputPin* This, long* z) -{ - This->mempin->frame_size_pointer = z; -} - -/** * \brief COutputPin::SetNewFormat(sets new media format for the pin) * * \param[in] This pointer to COutputPin class @@ -946,7 +892,7 @@ * \return NULL if error occured * */ -COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt) +COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt,SAMPLEPROC SampleProc,void* pUserData) { COutputPin* This = (COutputPin*) malloc(sizeof(COutputPin)); IMemInputPin_vt* ivt; @@ -964,6 +910,9 @@ return NULL; } + This->SampleProc=SampleProc; + This->pUserData=pUserData; + This->mempin->vt = ivt; This->refcount = 1; @@ -1005,9 +954,6 @@ This->mempin->refcount = 1; This->mempin->parent = This; - This->SetPointer2 = COutputPin_SetPointer2; - This->SetFramePointer = COutputPin_SetFramePointer; - This->SetFrameSizePointer = COutputPin_SetFrameSizePointer; This->SetNewFormat = COutputPin_SetNewFormat; return This; diff -r b2e4557a3160 -r 49f01f8fbd60 loader/dshow/outputpin.h --- a/loader/dshow/outputpin.h Fri Mar 02 17:59:19 2007 +0000 +++ b/loader/dshow/outputpin.h Fri Mar 02 18:52:10 2007 +0000 @@ -8,6 +8,13 @@ typedef struct _COutputMemPin COutputMemPin; typedef struct _COutputPin COutputPin; +/** + Callback routine for copying samples from pin into filter + \param pUserData pointer to user's data + \param sample IMediaSample +*/ +typedef HRESULT STDCALL (*SAMPLEPROC)(void* pUserData,IMediaSample*sample); + struct _COutputPin { IPin_vt* vt; @@ -15,12 +22,11 @@ COutputMemPin* mempin; AM_MEDIA_TYPE type; IPin* remote; - void ( *SetFramePointer )(COutputPin*, char** z); - void ( *SetPointer2 )(COutputPin*, char* p); - void ( *SetFrameSizePointer )(COutputPin*, long* z); + SAMPLEPROC SampleProc; + void* pUserData; void ( *SetNewFormat )(COutputPin*, const AM_MEDIA_TYPE* a); }; -COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* vhdr); +COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt,SAMPLEPROC SampleProc,void* pUserData); #endif /* DS_OUTPUTPIN_H */