Mercurial > mplayer.hg
annotate loader/dshow/DS_AudioDecoder.c @ 11330:a974c00c779d
Removed temporary .cpp file used during the Matroska test. Updated the libebml and libmatroska requirements to at least v0.6.0 for both. There have been changes in the lacing code, and users WILL come and complain why mplayer, linked against older versions, will have issues playing newer files.
author | mosu |
---|---|
date | Thu, 30 Oct 2003 14:57:06 +0000 |
parents | b0d1b415320c |
children | f70772d02eaa |
rev | line source |
---|---|
1545 | 1 /******************************************************** |
2 | |
3 DirectShow audio decoder | |
4 Copyright 2001 Eugene Kuznetsov (divx@euro.ru) | |
5 | |
6 *********************************************************/ | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
7 #include "config.h" |
1545 | 8 |
3946 | 9 #ifndef NOAVIFILE_HEADERS |
10 #include "audiodecoder.h" | |
11 #include "except.h" | |
12 #else | |
13 #include "libwin32.h" | |
14 #endif | |
15 | |
16 #include "DS_Filter.h" | |
17 | |
18 struct _DS_AudioDecoder | |
19 { | |
20 WAVEFORMATEX in_fmt; | |
21 AM_MEDIA_TYPE m_sOurType, m_sDestType; | |
22 DS_Filter* m_pDS_Filter; | |
23 char* m_sVhdr; | |
24 char* m_sVhdr2; | |
25 }; | |
26 | |
2069 | 27 #include "DS_AudioDecoder.h" |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
28 #ifdef WIN32_LOADER |
8451 | 29 #include "../ldt_keeper.h" |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
30 #endif |
3946 | 31 |
2069 | 32 #include <string.h> |
33 #include <stdio.h> | |
3059 | 34 #include <stdlib.h> |
2069 | 35 |
1545 | 36 #define __MODULE__ "DirectShow audio decoder" |
37 | |
38 typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**); | |
39 | |
3444 | 40 DS_AudioDecoder * DS_AudioDecoder_Open(char* dllname, GUID* guid, WAVEFORMATEX* wf) |
41 //DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf) | |
1545 | 42 { |
3059 | 43 DS_AudioDecoder *this; |
44 int sz; | |
45 WAVEFORMATEX* pWF; | |
3444 | 46 |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
47 #ifdef WIN32_LOADER |
3444 | 48 Setup_LDT_Keeper(); |
49 Setup_FS_Segment(); | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
50 #endif |
3059 | 51 |
52 this = malloc(sizeof(DS_AudioDecoder)); | |
53 | |
54 sz = 18 + wf->cbSize; | |
55 this->m_sVhdr = malloc(sz); | |
56 memcpy(this->m_sVhdr, wf, sz); | |
3915 | 57 this->m_sVhdr2 = malloc(18); |
58 memcpy(this->m_sVhdr2, this->m_sVhdr, 18); | |
3059 | 59 |
60 pWF = (WAVEFORMATEX*)this->m_sVhdr2; | |
61 pWF->wFormatTag = 1; | |
62 pWF->wBitsPerSample = 16; | |
3915 | 63 pWF->nBlockAlign = pWF->nChannels * (pWF->wBitsPerSample + 7) / 8; |
3059 | 64 pWF->cbSize = 0; |
3915 | 65 pWF->nAvgBytesPerSec = pWF->nBlockAlign * pWF->nSamplesPerSec; |
3059 | 66 |
67 memcpy(&this->in_fmt,wf,sizeof(WAVEFORMATEX)); | |
1545 | 68 |
3059 | 69 memset(&this->m_sOurType, 0, sizeof(this->m_sOurType)); |
70 this->m_sOurType.majortype=MEDIATYPE_Audio; | |
71 this->m_sOurType.subtype=MEDIASUBTYPE_PCM; | |
72 this->m_sOurType.subtype.f1=wf->wFormatTag; | |
73 this->m_sOurType.formattype=FORMAT_WaveFormatEx; | |
74 this->m_sOurType.lSampleSize=wf->nBlockAlign; | |
75 this->m_sOurType.bFixedSizeSamples=1; | |
76 this->m_sOurType.bTemporalCompression=0; | |
77 this->m_sOurType.pUnk=0; | |
78 this->m_sOurType.cbFormat=sz; | |
79 this->m_sOurType.pbFormat=this->m_sVhdr; | |
1545 | 80 |
3059 | 81 memset(&this->m_sDestType, 0, sizeof(this->m_sDestType)); |
82 this->m_sDestType.majortype=MEDIATYPE_Audio; | |
83 this->m_sDestType.subtype=MEDIASUBTYPE_PCM; | |
3915 | 84 // this->m_sDestType.subtype.f1=pWF->wFormatTag; |
3059 | 85 this->m_sDestType.formattype=FORMAT_WaveFormatEx; |
86 this->m_sDestType.bFixedSizeSamples=1; | |
87 this->m_sDestType.bTemporalCompression=0; | |
3915 | 88 this->m_sDestType.lSampleSize=pWF->nBlockAlign; |
3466 | 89 if (wf->wFormatTag == 0x130) |
90 // ACEL hack to prevent memory corruption | |
91 // obviosly we are missing something here | |
92 this->m_sDestType.lSampleSize *= 288; | |
3059 | 93 this->m_sDestType.pUnk=0; |
3915 | 94 this->m_sDestType.cbFormat=18; //pWF->cbSize; |
3059 | 95 this->m_sDestType.pbFormat=this->m_sVhdr2; |
1545 | 96 |
6139
3898967fcc96
some more output cosmetics, especially for vivo and mov demuxers
arpi
parents:
3946
diff
changeset
|
97 //print_wave_header(this->m_sVhdr); |
3898967fcc96
some more output cosmetics, especially for vivo and mov demuxers
arpi
parents:
3946
diff
changeset
|
98 //print_wave_header(this->m_sVhdr2); |
3915 | 99 |
3059 | 100 /*try*/ |
1545 | 101 { |
3059 | 102 ALLOCATOR_PROPERTIES props, props1; |
3444 | 103 this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); |
3059 | 104 if( !this->m_pDS_Filter ) { |
105 free(this); | |
106 return NULL; | |
107 } | |
108 | |
3063 | 109 this->m_pDS_Filter->Start(this->m_pDS_Filter); |
1545 | 110 |
111 props.cBuffers=1; | |
3059 | 112 props.cbBuffer=this->m_sOurType.lSampleSize; |
9503
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8451
diff
changeset
|
113 props.cbAlign=1; |
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8451
diff
changeset
|
114 props.cbPrefix=0; |
3059 | 115 this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1); |
116 this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll); | |
1545 | 117 } |
3059 | 118 /* |
119 catch (FatalError& e) | |
1545 | 120 { |
121 e.PrintAll(); | |
122 delete[] m_sVhdr; | |
123 delete[] m_sVhdr2; | |
124 delete m_pDS_Filter; | |
125 throw; | |
126 } | |
3059 | 127 */ |
128 return this; | |
1545 | 129 } |
130 | |
3059 | 131 void DS_AudioDecoder_Destroy(DS_AudioDecoder *this) |
1545 | 132 { |
3059 | 133 free(this->m_sVhdr); |
134 free(this->m_sVhdr2); | |
135 DS_Filter_Destroy(this->m_pDS_Filter); | |
136 free(this); | |
1545 | 137 } |
138 | |
3946 | 139 int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, unsigned int in_size, |
140 void* out_data, unsigned int out_size, | |
141 unsigned int* size_read, unsigned int* size_written) | |
1545 | 142 { |
3946 | 143 unsigned int written = 0; |
144 unsigned int read = 0; | |
3059 | 145 |
1545 | 146 if (!in_data || !out_data) |
147 return -1; | |
148 | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
149 #ifdef WIN32_LOADER |
3444 | 150 Setup_FS_Segment(); |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9503
diff
changeset
|
151 #endif |
3444 | 152 |
3059 | 153 in_size -= in_size%this->in_fmt.nBlockAlign; |
1545 | 154 while (in_size>0) |
155 { | |
3946 | 156 unsigned int frame_size = 0; |
1545 | 157 char* frame_pointer; |
158 IMediaSample* sample=0; | |
3059 | 159 char* ptr; |
160 int result; | |
161 | |
162 // this->m_pOurOutput->SetFramePointer(out_data+written); | |
3063 | 163 this->m_pDS_Filter->m_pOurOutput->SetFramePointer(this->m_pDS_Filter->m_pOurOutput,&frame_pointer); |
164 this->m_pDS_Filter->m_pOurOutput->SetFrameSizePointer(this->m_pDS_Filter->m_pOurOutput,(long*)&frame_size); | |
3059 | 165 this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0); |
166 if (!sample) | |
1545 | 167 { |
2069 | 168 Debug printf("DS_AudioDecoder::Convert() Error: null sample\n"); |
1545 | 169 break; |
170 } | |
3466 | 171 sample->vt->SetActualDataLength(sample, this->in_fmt.nBlockAlign); |
1545 | 172 sample->vt->GetPointer(sample, (BYTE **)&ptr); |
3059 | 173 memcpy(ptr, (const uint8_t*)in_data + read, this->in_fmt.nBlockAlign); |
174 sample->vt->SetSyncPoint(sample, 1); | |
1545 | 175 sample->vt->SetPreroll(sample, 0); |
3059 | 176 result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample); |
1545 | 177 if (result) |
178 Debug printf("DS_AudioDecoder::Convert() Error: putting data into input pin %x\n", result); | |
179 if ((written + frame_size) > out_size) | |
180 { | |
181 sample->vt->Release((IUnknown*)sample); | |
182 break; | |
183 } | |
184 memcpy((uint8_t*)out_data + written, frame_pointer, frame_size); | |
185 sample->vt->Release((IUnknown*)sample); | |
3059 | 186 read+=this->in_fmt.nBlockAlign; |
1545 | 187 written+=frame_size; |
3466 | 188 break; |
1545 | 189 } |
190 if (size_read) | |
191 *size_read = read; | |
192 if (size_written) | |
193 *size_written = written; | |
194 return 0; | |
195 } | |
196 | |
3059 | 197 int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder *this, int dest_size) |
1545 | 198 { |
3059 | 199 double efficiency =(double) this->in_fmt.nAvgBytesPerSec |
200 / (this->in_fmt.nSamplesPerSec*this->in_fmt.nBlockAlign); | |
201 int frames = (int)(dest_size*efficiency);; | |
202 | |
1545 | 203 if (frames < 1) |
204 frames = 1; | |
3059 | 205 return frames * this->in_fmt.nBlockAlign; |
1545 | 206 } |