diff options
author | voroshil <voroshil@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2007-03-02 18:52:10 +0000 |
---|---|---|
committer | voroshil <voroshil@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2007-03-02 18:52:10 +0000 |
commit | e9e53f8cd0704adcab13ae9fee616b4f8f54dfdf (patch) | |
tree | f0f01081985a6b297b15ab318ca31fb087885033 /loader | |
parent | 5c927f23672550e2d3f15aaced60c7bec51da1f9 (diff) | |
download | mpv-e9e53f8cd0704adcab13ae9fee616b4f8f54dfdf.tar.bz2 mpv-e9e53f8cd0704adcab13ae9fee616b4f8f54dfdf.tar.xz |
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.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@22416 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'loader')
-rw-r--r-- | loader/dshow/DS_AudioDecoder.c | 17 | ||||
-rw-r--r-- | loader/dshow/DS_Filter.c | 29 | ||||
-rw-r--r-- | loader/dshow/DS_Filter.h | 7 | ||||
-rw-r--r-- | loader/dshow/DS_VideoDecoder.c | 12 | ||||
-rw-r--r-- | loader/dshow/outputpin.c | 84 | ||||
-rw-r--r-- | loader/dshow/outputpin.h | 14 |
6 files changed, 71 insertions, 92 deletions
diff --git a/loader/dshow/DS_AudioDecoder.c b/loader/dshow/DS_AudioDecoder.c index c2ab624b46..23cd65bdfc 100644 --- a/loader/dshow/DS_AudioDecoder.c +++ b/loader/dshow/DS_AudioDecoder.c @@ -35,6 +35,9 @@ struct _DS_AudioDecoder 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 @@ DS_AudioDecoder * DS_AudioDecoder_Open(char* dllname, GUID* guid, WAVEFORMATEX* /*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 @@ int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, unsigned 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 @@ int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, unsigned 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 --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c index 8d11c170cc..e55862074b 100644 --- a/loader/dshow/DS_Filter.c +++ b/loader/dshow/DS_Filter.c @@ -95,9 +95,34 @@ void DS_Filter_Destroy(DS_Filter* This) #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 @@ DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, //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 --git a/loader/dshow/DS_Filter.h b/loader/dshow/DS_Filter.h index 909217602b..6fb643dc67 100644 --- a/loader/dshow/DS_Filter.h +++ b/loader/dshow/DS_Filter.h @@ -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 @@ struct _DS_Filter }; 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 --git a/loader/dshow/DS_VideoDecoder.c b/loader/dshow/DS_VideoDecoder.c index 358c14ffb3..4f5a8b7a79 100644 --- a/loader/dshow/DS_VideoDecoder.c +++ b/loader/dshow/DS_VideoDecoder.c @@ -31,6 +31,7 @@ struct _DS_VideoDecoder int m_bIsDivX; // for speed int m_bIsDivX4; // for speed }; +static SampleProcUserData sampleProcData; #include "DS_VideoDecoder.h" @@ -175,7 +176,7 @@ DS_VideoDecoder * DS_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEAD * ((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 @@ int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder *this, const void* src, int s } //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 @@ int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder *this, const void* src, int s { 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 --git a/loader/dshow/outputpin.c b/loader/dshow/outputpin.c index 6caf658d51..0e43fe7ba2 100644 --- a/loader/dshow/outputpin.c +++ b/loader/dshow/outputpin.c @@ -709,36 +709,14 @@ static HRESULT STDCALL COutputMemPin_GetAllocatorRequirements(IMemInputPin* This 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 @@ static HRESULT STDCALL COutputMemPin_ReceiveMultiple(IMemInputPin * This, /* [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 @@ static HRESULT STDCALL COutputMemPin_ReceiveCanBlock(IMemInputPin * This) } /** - * \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 @@ static HRESULT STDCALL COutputMemPin_Release(IUnknown* This) * \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 @@ COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt) return NULL; } + This->SampleProc=SampleProc; + This->pUserData=pUserData; + This->mempin->vt = ivt; This->refcount = 1; @@ -1005,9 +954,6 @@ COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt) 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 --git a/loader/dshow/outputpin.h b/loader/dshow/outputpin.h index 1e802f6e02..aa60ca049b 100644 --- a/loader/dshow/outputpin.h +++ b/loader/dshow/outputpin.h @@ -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 @@ struct _COutputPin 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 */ |