1
|
1 // ACM audio and VfW video codecs initialization
|
|
2 // based on the avifile library [http://divx.euro.ru]
|
|
3
|
92
|
4 static char* a_in_buffer=NULL;
|
|
5 static int a_in_buffer_len=0;
|
|
6 static int a_in_buffer_size=0;
|
|
7
|
1
|
8 int init_audio_codec(){
|
|
9 HRESULT ret;
|
|
10 WAVEFORMATEX *in_fmt=(WAVEFORMATEX*)&avi_header.wf_ext;
|
|
11 unsigned long srcsize=0;
|
|
12
|
|
13 if(verbose) printf("======= Win32 (ACM) AUDIO Codec init =======\n");
|
|
14
|
|
15 avi_header.srcstream=NULL;
|
|
16
|
|
17 // if(in_fmt->nSamplesPerSec==0){ printf("Bad WAVE header!\n");exit(1); }
|
|
18 // MSACM_RegisterAllDrivers();
|
|
19
|
|
20 avi_header.wf.nChannels=in_fmt->nChannels;
|
|
21 avi_header.wf.nSamplesPerSec=in_fmt->nSamplesPerSec;
|
|
22 avi_header.wf.nAvgBytesPerSec=2*avi_header.wf.nSamplesPerSec*avi_header.wf.nChannels;
|
|
23 avi_header.wf.wFormatTag=WAVE_FORMAT_PCM;
|
|
24 avi_header.wf.nBlockAlign=2*in_fmt->nChannels;
|
|
25 avi_header.wf.wBitsPerSample=16;
|
|
26 avi_header.wf.cbSize=0;
|
|
27
|
|
28 win32_codec_name = avi_header.audio_codec;
|
|
29 ret=acmStreamOpen(&avi_header.srcstream,(HACMDRIVER)NULL,
|
|
30 in_fmt,&avi_header.wf,
|
|
31 NULL,0,0,0);
|
|
32 if(ret){
|
|
33 if(ret==ACMERR_NOTPOSSIBLE)
|
|
34 printf("ACM_Decoder: Unappropriate audio format\n");
|
|
35 else
|
|
36 printf("ACM_Decoder: acmStreamOpen error %d", ret);
|
|
37 avi_header.srcstream=NULL;
|
|
38 return 0;
|
|
39 }
|
|
40 if(verbose) printf("Audio codec opened OK! ;-)\n");
|
|
41
|
|
42 srcsize=in_fmt->nBlockAlign;
|
|
43 acmStreamSize(avi_header.srcstream, srcsize, &srcsize, ACM_STREAMSIZEF_SOURCE);
|
|
44 if(srcsize<OUTBURST) srcsize=OUTBURST;
|
|
45 avi_header.audio_out_minsize=srcsize; // audio output min. size
|
|
46 if(verbose) printf("Audio ACM output buffer min. size: %d\n",srcsize);
|
|
47
|
|
48 acmStreamSize(avi_header.srcstream, srcsize, &srcsize, ACM_STREAMSIZEF_DESTINATION);
|
|
49 avi_header.audio_in_minsize=srcsize; // audio input min. size
|
|
50 if(verbose) printf("Audio ACM input buffer min. size: %d\n",srcsize);
|
|
51
|
92
|
52 a_in_buffer_size=avi_header.audio_in_minsize;
|
|
53 a_in_buffer=malloc(a_in_buffer_size);
|
|
54 a_in_buffer_len=0;
|
|
55
|
1
|
56 return 1;
|
|
57 }
|
|
58
|
92
|
59 int acm_decode_audio(void* a_buffer,int len){
|
|
60 ACMSTREAMHEADER ash;
|
|
61 HRESULT hr;
|
|
62 DWORD srcsize=0;
|
|
63 acmStreamSize(avi_header.srcstream,len , &srcsize, ACM_STREAMSIZEF_DESTINATION);
|
|
64 if(verbose>=3)printf("acm says: srcsize=%d (buffsize=%d) out_size=%d\n",srcsize,a_in_buffer_size,len);
|
|
65 // if(srcsize==0) srcsize=((WAVEFORMATEX *)&avi_header.wf_ext)->nBlockAlign;
|
|
66 if(srcsize>a_in_buffer_size) srcsize=a_in_buffer_size; // !!!!!!
|
|
67 if(a_in_buffer_len<srcsize){
|
|
68 a_in_buffer_len+=
|
|
69 demux_read_data(d_audio,&a_in_buffer[a_in_buffer_len],
|
|
70 srcsize-a_in_buffer_len);
|
|
71 }
|
|
72 memset(&ash, 0, sizeof(ash));
|
|
73 ash.cbStruct=sizeof(ash);
|
|
74 ash.fdwStatus=0;
|
|
75 ash.dwUser=0;
|
|
76 ash.pbSrc=a_in_buffer;
|
|
77 ash.cbSrcLength=a_in_buffer_len;
|
|
78 ash.pbDst=a_buffer;
|
|
79 ash.cbDstLength=len;
|
|
80 hr=acmStreamPrepareHeader(avi_header.srcstream,&ash,0);
|
|
81 if(hr){
|
|
82 printf("ACM_Decoder: acmStreamPrepareHeader error %d\n",hr);
|
|
83 return -1;
|
|
84 }
|
|
85 hr=acmStreamConvert(avi_header.srcstream,&ash,0);
|
|
86 if(hr){
|
|
87 printf("ACM_Decoder: acmStreamConvert error %d\n",hr);
|
|
88 return -1;
|
|
89 }
|
|
90 //printf("ACM convert %d -> %d (buf=%d)\n",ash.cbSrcLengthUsed,ash.cbDstLengthUsed,a_in_buffer_len);
|
|
91 if(ash.cbSrcLengthUsed>=a_in_buffer_len){
|
|
92 a_in_buffer_len=0;
|
|
93 } else {
|
|
94 a_in_buffer_len-=ash.cbSrcLengthUsed;
|
|
95 memcpy(a_in_buffer,&a_in_buffer[ash.cbSrcLengthUsed],a_in_buffer_len);
|
|
96 }
|
|
97 len=ash.cbDstLengthUsed;
|
|
98 hr=acmStreamUnprepareHeader(avi_header.srcstream,&ash,0);
|
|
99 if(hr){
|
|
100 printf("ACM_Decoder: acmStreamUnprepareHeader error %d\n",hr);
|
|
101 }
|
|
102 return len;
|
|
103 }
|
|
104
|
|
105
|
1
|
106
|
|
107 int init_video_codec(int outfmt){
|
|
108 HRESULT ret;
|
|
109
|
|
110 if(verbose) printf("======= Win32 (VFW) VIDEO Codec init =======\n");
|
|
111
|
|
112 memset(&avi_header.o_bih, 0, sizeof(BITMAPINFOHEADER));
|
|
113 avi_header.o_bih.biSize = sizeof(BITMAPINFOHEADER);
|
|
114
|
|
115 win32_codec_name = avi_header.video_codec;
|
|
116 avi_header.hic = ICOpen( 0x63646976, avi_header.bih.biCompression, ICMODE_FASTDECOMPRESS);
|
|
117 // avi_header.hic = ICOpen( 0x63646976, avi_header.bih.biCompression, ICMODE_DECOMPRESS);
|
|
118 if(!avi_header.hic){
|
|
119 printf("ICOpen failed! unknown codec / wrong parameters?\n");
|
|
120 return 0;
|
|
121 }
|
|
122
|
|
123 // avi_header.bih.biBitCount=32;
|
|
124
|
|
125 ret = ICDecompressGetFormat(avi_header.hic, &avi_header.bih, &avi_header.o_bih);
|
|
126 if(ret){
|
|
127 printf("ICDecompressGetFormat failed: Error %d\n", ret);
|
|
128 return 0;
|
|
129 }
|
|
130 if(verbose) printf("ICDecompressGetFormat OK\n");
|
|
131
|
|
132 // printf("ICM_DECOMPRESS_QUERY=0x%X",ICM_DECOMPRESS_QUERY);
|
|
133
|
|
134 // avi_header.o_bih.biWidth=avi_header.bih.biWidth;
|
|
135 // avi_header.o_bih.biCompression = 0x32315659; // mmioFOURCC('U','Y','V','Y');
|
|
136 // ret=ICDecompressGetFormatSize(avi_header.hic,&avi_header.o_bih);
|
|
137 // avi_header.o_bih.biCompression = 3; //0x32315659;
|
|
138 // avi_header.o_bih.biCompression = mmioFOURCC('U','Y','V','Y');
|
|
139 // avi_header.o_bih.biCompression = mmioFOURCC('U','Y','V','Y');
|
|
140 // avi_header.o_bih.biCompression = mmioFOURCC('Y','U','Y','2');
|
|
141 // avi_header.o_bih.biPlanes=3;
|
|
142 // avi_header.o_bih.biBitCount=16;
|
|
143
|
|
144 if(outfmt==IMGFMT_YUY2)
|
|
145 avi_header.o_bih.biBitCount=16;
|
|
146 else
|
|
147 avi_header.o_bih.biBitCount=outfmt&0xFF;// //24;
|
|
148
|
|
149 avi_header.o_bih.biSizeImage=avi_header.o_bih.biWidth*avi_header.o_bih.biHeight*(avi_header.o_bih.biBitCount/8);
|
|
150
|
|
151 if(!avi_header.flipped)
|
|
152 avi_header.o_bih.biHeight=-avi_header.bih.biHeight; // flip image!
|
|
153
|
|
154 if(outfmt==IMGFMT_YUY2 && !avi_header.yuv_hack_needed)
|
|
155 avi_header.o_bih.biCompression = mmioFOURCC('Y','U','Y','2');
|
|
156
|
|
157 // avi_header.o_bih.biCompression = mmioFOURCC('U','Y','V','Y');
|
|
158
|
|
159
|
|
160 if(verbose) {
|
|
161 printf("Starting decompression, format:\n");
|
|
162 printf(" biSize %d\n", avi_header.bih.biSize);
|
|
163 printf(" biWidth %d\n", avi_header.bih.biWidth);
|
|
164 printf(" biHeight %d\n", avi_header.bih.biHeight);
|
|
165 printf(" biPlanes %d\n", avi_header.bih.biPlanes);
|
|
166 printf(" biBitCount %d\n", avi_header.bih.biBitCount);
|
|
167 printf(" biCompression %d='%.4s'\n", avi_header.bih.biCompression, &avi_header.bih.biCompression);
|
|
168 printf(" biSizeImage %d\n", avi_header.bih.biSizeImage);
|
|
169 printf("Dest fmt:\n");
|
|
170 printf(" biSize %d\n", avi_header.o_bih.biSize);
|
|
171 printf(" biWidth %d\n", avi_header.o_bih.biWidth);
|
|
172 printf(" biHeight %d\n", avi_header.o_bih.biHeight);
|
|
173 printf(" biPlanes %d\n", avi_header.o_bih.biPlanes);
|
|
174 printf(" biBitCount %d\n", avi_header.o_bih.biBitCount);
|
|
175 printf(" biCompression %d='%.4s'\n", avi_header.o_bih.biCompression, &avi_header.o_bih.biCompression);
|
|
176 printf(" biSizeImage %d\n", avi_header.o_bih.biSizeImage);
|
|
177 }
|
|
178
|
|
179 ret = ICDecompressQuery(avi_header.hic, &avi_header.bih, &avi_header.o_bih);
|
|
180 if(ret){
|
|
181 printf("ICDecompressQuery failed: Error %d\n", ret);
|
|
182 return 0;
|
|
183 }
|
|
184 if(verbose) printf("ICDecompressQuery OK\n");
|
|
185
|
|
186
|
|
187 ret = ICDecompressBegin(avi_header.hic, &avi_header.bih, &avi_header.o_bih);
|
|
188 if(ret){
|
|
189 printf("ICDecompressBegin failed: Error %d\n", ret);
|
|
190 return 0;
|
|
191 }
|
|
192
|
|
193 #if 0
|
|
194
|
|
195 //avi_header.hic
|
|
196 //ICSendMessage(HIC hic,unsigned int msg,long lParam1,long lParam2)
|
|
197 { int i;
|
|
198 for(i=73;i<256;i++){
|
|
199 printf("Calling ICM_USER+%d function...",i);fflush(stdout);
|
|
200 ret = ICSendMessage(avi_header.hic,ICM_USER+i,NULL,NULL);
|
|
201 printf(" ret=%d\n",ret);
|
|
202 }
|
|
203 }
|
|
204 #endif
|
|
205
|
|
206 avi_header.our_out_buffer = malloc(avi_header.o_bih.biSizeImage);
|
|
207 if(!avi_header.our_out_buffer){
|
|
208 printf("not enough memory for decoded picture buffer (%d bytes)\n", avi_header.o_bih.biSizeImage);
|
|
209 return 0;
|
|
210 }
|
|
211
|
|
212 if(outfmt==IMGFMT_YUY2 && avi_header.yuv_hack_needed)
|
|
213 avi_header.o_bih.biCompression = mmioFOURCC('Y','U','Y','2');
|
|
214
|
|
215 // avi_header.our_in_buffer=malloc(avi_header.video.dwSuggestedBufferSize); // FIXME!!!!
|
|
216
|
|
217 if(verbose) printf("VIDEO CODEC Init OK!!! ;-)\n");
|
|
218 return 1;
|
|
219 }
|