Mercurial > mplayer.hg
annotate loader/dshow/DS_AudioDecoder.c @ 20658:ed20cbab07a4
Corrigendum 1
change chapter_id from v to s to allow negative chapter_id as required by the spec text
change was unanimously accepted (rich, oded, myself)
this change should not break any existing muxers or demuxers, with the exception of
assumtations about (non)overlapping chapters
author | michael |
---|---|
date | Sat, 04 Nov 2006 22:01:51 +0000 |
parents | f70772d02eaa |
children | 2934974c366a |
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 |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
9967
diff
changeset
|
97 //print_wave_header(this->m_sVhdr, MSGL_V); |
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
9967
diff
changeset
|
98 //print_wave_header(this->m_sVhdr2, MSGL_V); |
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 } |