adding the code documentation guide lines
[mplayer/glamo.git] / libmpcodecs / ad_hwac3.c
blob14202195a137406ea9d0b609253c5a2775ce6cb9
2 // Reference: DOCS/tech/hwac3.txt !!!!!
4 /* DTS code based on "ac3/decode_dts.c" and "ac3/conversion.c" from "ogle 0.9"
5 (see http://www.dtek.chalmers.se/~dvd/)
6 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
13 #include "config.h"
14 #ifdef USE_LIBA52
16 #include "mp_msg.h"
17 #include "help_mp.h"
19 #include "ad_internal.h"
21 #include "../liba52/a52.h"
24 static int isdts = -1;
26 static ad_info_t info =
28 "AC3/DTS pass-through SP/DIF",
29 "hwac3",
30 "Nick Kurshev/Peter Schüller",
31 "???",
35 LIBAD_EXTERN(hwac3)
38 static int dts_syncinfo(uint8_t *indata_ptr, int *flags, int *sample_rate, int *bit_rate);
39 static int decode_audio_dts(unsigned char *indata_ptr, int len, unsigned char *buf);
42 static int ac3dts_fillbuff(sh_audio_t *sh_audio)
44 int length = 0;
45 int flags = 0;
46 int sample_rate = 0;
47 int bit_rate = 0;
49 sh_audio->a_in_buffer_len = 0;
50 /* sync frame:*/
51 while(1)
53 // DTS has a 10 byte header
54 while(sh_audio->a_in_buffer_len < 10)
56 int c = demux_getc(sh_audio->ds);
57 if(c<0)
58 return -1; /* EOF*/
59 sh_audio->a_in_buffer[sh_audio->a_in_buffer_len++] = c;
62 length = dts_syncinfo(sh_audio->a_in_buffer, &flags, &sample_rate, &bit_rate);
63 if(length >= 10)
65 if(isdts != 1)
67 mp_msg(MSGT_DECAUDIO, MSGL_STATUS, "hwac3: switched to DTS, %d bps, %d Hz\n", bit_rate, sample_rate);
68 isdts = 1;
70 break;
72 length = a52_syncinfo(sh_audio->a_in_buffer, &flags, &sample_rate, &bit_rate);
73 if(length >= 7 && length <= 3840)
75 if(isdts != 0)
77 mp_msg(MSGT_DECAUDIO, MSGL_STATUS, "hwac3: switched to AC3, %d bps, %d Hz\n", bit_rate, sample_rate);
78 isdts = 0;
80 break; /* we're done.*/
82 /* bad file => resync*/
83 memcpy(sh_audio->a_in_buffer, sh_audio->a_in_buffer + 1, 9);
84 --sh_audio->a_in_buffer_len;
86 mp_msg(MSGT_DECAUDIO, MSGL_DBG2, "ac3dts: %s len=%d flags=0x%X %d Hz %d bit/s\n", isdts == 1 ? "DTS" : isdts == 0 ? "AC3" : "unknown", length, flags, sample_rate, bit_rate);
88 sh_audio->samplerate = sample_rate;
89 sh_audio->i_bps = bit_rate / 8;
90 demux_read_data(sh_audio->ds, sh_audio->a_in_buffer + 10, length - 10);
91 sh_audio->a_in_buffer_len = length;
93 // TODO: is DTS also checksummed?
94 if(isdts == 0 && crc16_block(sh_audio->a_in_buffer + 2, length - 2) != 0)
95 mp_msg(MSGT_DECAUDIO, MSGL_STATUS, "a52: CRC check failed! \n");
97 return length;
101 static int preinit(sh_audio_t *sh)
103 /* Dolby AC3 audio: */
104 sh->audio_out_minsize = 128 * 32 * 2 * 2; // DTS seems to need more than AC3
105 sh->audio_in_minsize = 8192;
106 sh->channels = 2;
107 sh->samplesize = 2;
108 sh->sample_format = AFMT_AC3;
109 return 1;
112 static int init(sh_audio_t *sh_audio)
114 /* Dolby AC3 passthrough:*/
115 sample_t *a52_samples = a52_init(0);
116 if(a52_samples == NULL)
118 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "A52 init failed\n");
119 return 0;
121 if(ac3dts_fillbuff(sh_audio) < 0)
123 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "AC3/DTS sync failed\n");
124 return 0;
126 return 1;
129 static void uninit(sh_audio_t *sh)
133 static int control(sh_audio_t *sh,int cmd,void* arg, ...)
135 switch(cmd)
137 case ADCTRL_SKIP_FRAME:
138 ac3dts_fillbuff(sh); break; // skip AC3 frame
139 return CONTROL_TRUE;
141 return CONTROL_UNKNOWN;
145 static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
147 int len = sh_audio->a_in_buffer_len;
149 if(len <= 0)
150 if((len = ac3dts_fillbuff(sh_audio)) <= 0)
151 return len; /*EOF*/
152 sh_audio->a_in_buffer_len = 0;
154 if(isdts == 1)
156 return decode_audio_dts(sh_audio->a_in_buffer, len, buf);
158 else if(isdts == 0)
160 buf[0] = 0x72;
161 buf[1] = 0xF8;
162 buf[2] = 0x1F;
163 buf[3] = 0x4E;
164 buf[4] = 0x01; //(length) ? data_type : 0; /* & 0x1F; */
165 buf[5] = 0x00;
166 buf[6] = (len << 3) & 0xFF;
167 buf[7] = (len >> 5) & 0xFF;
168 #ifdef WORDS_BIGENDIAN
169 memcpy(buf + 8, sh_audio->a_in_buffer, len); // untested
170 #else
171 swab(sh_audio->a_in_buffer, buf + 8, len);
172 #endif
173 memset(buf + 8 + len, 0, 6144 - 8 - len);
175 return 6144;
177 else
178 return -1;
182 static int DTS_SAMPLEFREQS[16] =
185 8000,
186 16000,
187 32000,
188 64000,
189 128000,
190 11025,
191 22050,
192 44100,
193 88200,
194 176400,
195 12000,
196 24000,
197 48000,
198 96000,
199 192000
202 static int DTS_BITRATES[30] =
204 32000,
205 56000,
206 64000,
207 96000,
208 112000,
209 128000,
210 192000,
211 224000,
212 256000,
213 320000,
214 384000,
215 448000,
216 512000,
217 576000,
218 640000,
219 768000,
220 896000,
221 1024000,
222 1152000,
223 1280000,
224 1344000,
225 1408000,
226 1411200,
227 1472000,
228 1536000,
229 1920000,
230 2048000,
231 3072000,
232 3840000,
233 4096000
236 static int dts_decode_header(uint8_t *indata_ptr, int *rate, int *nblks, int *sfreq)
238 int ftype;
239 int surp;
240 int unknown_bit;
241 int fsize;
242 int amode;
244 if(((indata_ptr[0] << 24) | (indata_ptr[1] << 16) | (indata_ptr[2] << 8)
245 | (indata_ptr[3])) != 0x7ffe8001)
246 return -1;
248 ftype = indata_ptr[4] >> 7;
250 surp = (indata_ptr[4] >> 2) & 0x1f;
251 surp = (surp + 1) % 32;
253 unknown_bit = (indata_ptr[4] >> 1) & 0x01;
255 *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
256 *nblks = *nblks + 1;
258 fsize = (indata_ptr[5] & 0x03) << 12 | (indata_ptr[6] << 4) | (indata_ptr[7] >> 4);
259 fsize = fsize + 1;
261 amode = (indata_ptr[7] & 0x0f) << 2 | (indata_ptr[8] >> 6);
262 *sfreq = (indata_ptr[8] >> 2) & 0x0f;
263 *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
265 if(ftype != 1)
267 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "DTS: Termination frames not handled, REPORT BUG\n");
268 return -1;
271 if(*sfreq != 13)
273 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "DTS: Only 48kHz supported, REPORT BUG\n");
274 return -1;
277 if((fsize > 8192) || (fsize < 96))
279 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "DTS: fsize: %d invalid, REPORT BUG\n", fsize);
280 return -1;
283 if(*nblks != 8 &&
284 *nblks != 16 &&
285 *nblks != 32 &&
286 *nblks != 64 &&
287 *nblks != 128 &&
288 ftype == 1)
290 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "DTS: nblks %d not valid for normal frame, REPORT BUG\n", *nblks);
291 return -1;
294 return fsize;
297 static int dts_syncinfo(uint8_t *indata_ptr, int *flags, int *sample_rate, int *bit_rate)
299 int nblks;
300 int fsize;
301 int rate;
302 int sfreq;
304 fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
305 if(fsize >= 0)
307 if(rate >= 0 && rate <= 29)
308 *bit_rate = DTS_BITRATES[rate];
309 else
310 *bit_rate = 0;
311 if(sfreq >= 1 && sfreq <= 15)
312 *sample_rate = DTS_SAMPLEFREQS[sfreq];
313 else
314 *sample_rate = 0;
316 return fsize;
320 static int decode_audio_dts(unsigned char *indata_ptr, int len, unsigned char *buf)
322 int nblks;
323 int fsize;
324 int rate;
325 int sfreq;
326 int burst_len;
327 int nr_samples;
329 fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
330 if(fsize < 0)
331 return -1;
333 burst_len = fsize * 8;
334 nr_samples = nblks * 32;
336 buf[0] = 0x72; buf[1] = 0xf8; /* iec 61937 */
337 buf[2] = 0x1f; buf[3] = 0x4e; /* syncword */
338 switch(nr_samples)
340 case 512:
341 buf[4] = 0x0b; /* DTS-1 (512-sample bursts) */
342 break;
343 case 1024:
344 buf[4] = 0x0c; /* DTS-2 (1024-sample bursts) */
345 break;
346 case 2048:
347 buf[4] = 0x0d; /* DTS-3 (2048-sample bursts) */
348 break;
349 default:
350 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "DTS: %d-sample bursts not supported\n", nr_samples);
351 buf[4] = 0x00;
352 break;
354 buf[5] = 0; /* ?? */
355 buf[6] = (burst_len) & 0xff;
356 buf[7] = (burst_len >> 8) & 0xff;
358 if(fsize + 8 > nr_samples * 2 * 2)
360 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "DTS: more data than fits\n");
362 #ifdef WORDS_BIGENDIAN
363 memcpy(&buf[8], indata_ptr, fsize); // untested
364 #else
365 //TODO if fzise is odd, swab doesn't copy the last byte
366 swab(indata_ptr, &buf[8], fsize);
367 #endif
368 memset(&buf[fsize + 8], 0, nr_samples * 2 * 2 - (fsize + 8));
370 return nr_samples * 2 * 2;
372 #endif