1 /********************************************************
3 DirectShow audio decoder
4 Copyright 2001 Eugene Kuznetsov (divx@euro.ru)
6 *********************************************************/
11 #include "DS_Filter.h"
13 struct DS_AudioDecoder
16 AM_MEDIA_TYPE m_sOurType
, m_sDestType
;
17 DS_Filter
* m_pDS_Filter
;
22 #include "DS_AudioDecoder.h"
24 #include "loader/ldt_keeper.h"
31 typedef long STDCALL (*GETCLASS
) (GUID
*, GUID
*, void**);
33 static SampleProcUserData sampleProcData
;
36 DS_AudioDecoder
* DS_AudioDecoder_Open(char* dllname
, GUID
* guid
, WAVEFORMATEX
* wf
)
37 //DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf)
39 DS_AudioDecoder
*this;
48 this = malloc(sizeof(DS_AudioDecoder
));
51 this->m_sVhdr
= malloc(sz
);
52 memcpy(this->m_sVhdr
, wf
, sz
);
53 this->m_sVhdr2
= malloc(18);
54 memcpy(this->m_sVhdr2
, this->m_sVhdr
, 18);
56 pWF
= (WAVEFORMATEX
*)this->m_sVhdr2
;
58 pWF
->wBitsPerSample
= 16;
59 pWF
->nBlockAlign
= pWF
->nChannels
* (pWF
->wBitsPerSample
+ 7) / 8;
61 pWF
->nAvgBytesPerSec
= pWF
->nBlockAlign
* pWF
->nSamplesPerSec
;
63 memcpy(&this->in_fmt
,wf
,sizeof(WAVEFORMATEX
));
65 memset(&this->m_sOurType
, 0, sizeof(this->m_sOurType
));
66 this->m_sOurType
.majortype
=MEDIATYPE_Audio
;
67 this->m_sOurType
.subtype
=MEDIASUBTYPE_PCM
;
68 this->m_sOurType
.subtype
.f1
=wf
->wFormatTag
;
69 this->m_sOurType
.formattype
=FORMAT_WaveFormatEx
;
70 this->m_sOurType
.lSampleSize
=wf
->nBlockAlign
;
71 this->m_sOurType
.bFixedSizeSamples
=1;
72 this->m_sOurType
.bTemporalCompression
=0;
73 this->m_sOurType
.pUnk
=0;
74 this->m_sOurType
.cbFormat
=sz
;
75 this->m_sOurType
.pbFormat
=this->m_sVhdr
;
77 memset(&this->m_sDestType
, 0, sizeof(this->m_sDestType
));
78 this->m_sDestType
.majortype
=MEDIATYPE_Audio
;
79 this->m_sDestType
.subtype
=MEDIASUBTYPE_PCM
;
80 // this->m_sDestType.subtype.f1=pWF->wFormatTag;
81 this->m_sDestType
.formattype
=FORMAT_WaveFormatEx
;
82 this->m_sDestType
.bFixedSizeSamples
=1;
83 this->m_sDestType
.bTemporalCompression
=0;
84 this->m_sDestType
.lSampleSize
=pWF
->nBlockAlign
;
85 if (wf
->wFormatTag
== 0x130)
86 // ACEL hack to prevent memory corruption
87 // obviosly we are missing something here
88 this->m_sDestType
.lSampleSize
*= 288;
89 this->m_sDestType
.pUnk
=0;
90 this->m_sDestType
.cbFormat
=18; //pWF->cbSize;
91 this->m_sDestType
.pbFormat
=this->m_sVhdr2
;
93 //print_wave_header(this->m_sVhdr, MSGL_V);
94 //print_wave_header(this->m_sVhdr2, MSGL_V);
98 this->m_pDS_Filter
= DS_FilterCreate(dllname
, guid
, &this->m_sOurType
, &this->m_sDestType
,&sampleProcData
);
99 if( !this->m_pDS_Filter
) {
104 //Commit should be done before binary codec start
105 this->m_pDS_Filter
->m_pAll
->vt
->Commit(this->m_pDS_Filter
->m_pAll
);
107 this->m_pDS_Filter
->Start(this->m_pDS_Filter
);
111 catch (FatalError& e)
123 void DS_AudioDecoder_Destroy(DS_AudioDecoder
*this)
126 free(this->m_sVhdr2
);
127 DS_Filter_Destroy(this->m_pDS_Filter
);
131 int DS_AudioDecoder_Convert(DS_AudioDecoder
*this, const void* in_data
, unsigned int in_size
,
132 void* out_data
, unsigned int out_size
,
133 unsigned int* size_read
, unsigned int* size_written
)
135 unsigned int written
= 0;
136 unsigned int read
= 0;
138 if (!in_data
|| !out_data
)
145 in_size
-= in_size
%this->in_fmt
.nBlockAlign
;
148 IMediaSample
* sample
=0;
151 this->m_pDS_Filter
->m_pAll
->vt
->GetBuffer(this->m_pDS_Filter
->m_pAll
, &sample
, 0, 0, 0);
154 Debug
printf("DS_AudioDecoder::Convert() Error: null sample\n");
157 sample
->vt
->SetActualDataLength(sample
, this->in_fmt
.nBlockAlign
);
158 sample
->vt
->GetPointer(sample
, (BYTE
**)&ptr
);
159 memcpy(ptr
, (const uint8_t*)in_data
+ read
, this->in_fmt
.nBlockAlign
);
160 sample
->vt
->SetSyncPoint(sample
, 1);
161 sample
->vt
->SetPreroll(sample
, 0);
162 result
= this->m_pDS_Filter
->m_pImp
->vt
->Receive(this->m_pDS_Filter
->m_pImp
, sample
);
164 Debug
printf("DS_AudioDecoder::Convert() Error: putting data into input pin %x\n", result
);
165 if ((written
+ sampleProcData
.frame_size
) > out_size
)
167 sample
->vt
->Release((IUnknown
*)sample
);
170 memcpy((uint8_t*)out_data
+ written
, sampleProcData
.frame_pointer
, sampleProcData
.frame_size
);
171 sample
->vt
->Release((IUnknown
*)sample
);
172 read
+=this->in_fmt
.nBlockAlign
;
173 written
+=sampleProcData
.frame_size
;
179 *size_written
= written
;
183 int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder
*this, int dest_size
)
185 double efficiency
=(double) this->in_fmt
.nAvgBytesPerSec
186 / (this->in_fmt
.nSamplesPerSec
*this->in_fmt
.nBlockAlign
);
187 int frames
= (int)(dest_size
*efficiency
);
191 return frames
* this->in_fmt
.nBlockAlign
;