mirror of
https://github.com/mpv-player/mpv
synced 2025-01-05 03:06:28 +01:00
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
This commit is contained in:
parent
5c927f2367
commit
e9e53f8cd0
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -789,44 +773,6 @@ static HRESULT STDCALL COutputMemPin_ReceiveCanBlock(IMemInputPin * This)
|
||||
return output_unimplemented("COutputMemPin_ReceiveCanBlock", 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)
|
||||
*
|
||||
@ -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;
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user