1package com.googlecode.mp4parser.authoring.tracks;
2
3import com.coremedia.iso.boxes.*;
4import com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;
5import com.googlecode.mp4parser.authoring.AbstractTrack;
6import com.googlecode.mp4parser.authoring.TrackMetaData;
7import com.googlecode.mp4parser.boxes.AC3SpecificBox;
8import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;
9
10import java.io.InputStream;
11import java.io.IOException;
12import java.nio.ByteBuffer;
13import java.util.Date;
14import java.util.LinkedList;
15import java.util.List;
16
17public class AC3TrackImpl extends AbstractTrack {
18    TrackMetaData trackMetaData = new TrackMetaData();
19    SampleDescriptionBox sampleDescriptionBox;
20
21    int samplerate;
22    int bitrate;
23    int channelCount;
24
25    int fscod;
26    int bsid;
27    int bsmod;
28    int acmod;
29    int lfeon;
30    int frmsizecod;
31
32    int frameSize;
33    int[][][][] bitRateAndFrameSizeTable;
34
35    private InputStream inputStream;
36    private List<ByteBuffer> samples;
37    boolean readSamples = false;
38    List<TimeToSampleBox.Entry> stts;
39    private String lang = "und";
40
41    public AC3TrackImpl(InputStream fin, String lang) throws IOException {
42        this.lang = lang;
43        parse(fin);
44    }
45
46    public AC3TrackImpl(InputStream fin) throws IOException {
47        parse(fin);
48    }
49
50    private void parse(InputStream fin) throws IOException {
51        inputStream = fin;
52        bitRateAndFrameSizeTable = new int[19][2][3][2];
53        stts = new LinkedList<TimeToSampleBox.Entry>();
54        initBitRateAndFrameSizeTable();
55        if (!readVariables()) {
56            throw new IOException();
57        }
58
59        sampleDescriptionBox = new SampleDescriptionBox();
60        AudioSampleEntry audioSampleEntry = new AudioSampleEntry("ac-3");
61        audioSampleEntry.setChannelCount(2);  // According to  ETSI TS 102 366 Annex F
62        audioSampleEntry.setSampleRate(samplerate);
63        audioSampleEntry.setDataReferenceIndex(1);
64        audioSampleEntry.setSampleSize(16);
65
66        AC3SpecificBox ac3 = new AC3SpecificBox();
67        ac3.setAcmod(acmod);
68        ac3.setBitRateCode(frmsizecod >> 1);
69        ac3.setBsid(bsid);
70        ac3.setBsmod(bsmod);
71        ac3.setFscod(fscod);
72        ac3.setLfeon(lfeon);
73        ac3.setReserved(0);
74
75        audioSampleEntry.addBox(ac3);
76        sampleDescriptionBox.addBox(audioSampleEntry);
77
78        trackMetaData.setCreationTime(new Date());
79        trackMetaData.setModificationTime(new Date());
80        trackMetaData.setLanguage(lang);
81        trackMetaData.setTimescale(samplerate); // Audio tracks always use samplerate as timescale
82
83        samples = new LinkedList<ByteBuffer>();
84        if (!readSamples()) {
85            throw new IOException();
86        }
87    }
88
89
90    public List<ByteBuffer> getSamples() {
91
92        return samples;
93    }
94
95    public SampleDescriptionBox getSampleDescriptionBox() {
96        return sampleDescriptionBox;
97    }
98
99    public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
100        return stts;
101    }
102
103    public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
104        return null;
105    }
106
107    public long[] getSyncSamples() {
108        return null;
109    }
110
111    public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
112        return null;
113    }
114
115    public TrackMetaData getTrackMetaData() {
116        return trackMetaData;
117    }
118
119    public String getHandler() {
120        return "soun";
121    }
122
123    public Box getMediaHeaderBox() {
124        return new SoundMediaHeaderBox();
125    }
126
127    public SubSampleInformationBox getSubsampleInformationBox() {
128        return null;
129    }
130
131    private boolean readVariables() throws IOException {
132        byte[] data = new byte[100];
133        inputStream.mark(100);
134        if (100 != inputStream.read(data, 0, 100)) {
135            return false;
136        }
137        inputStream.reset(); // Rewind
138        ByteBuffer bb = ByteBuffer.wrap(data);
139        BitReaderBuffer brb = new BitReaderBuffer(bb);
140        int syncword = brb.readBits(16);
141        if (syncword != 0xb77) {
142            return false;
143        }
144        brb.readBits(16); // CRC-1
145        fscod = brb.readBits(2);
146
147        switch (fscod) {
148            case 0:
149                samplerate = 48000;
150                break;
151
152            case 1:
153                samplerate = 44100;
154                break;
155
156            case 2:
157                samplerate = 32000;
158                break;
159
160            case 3:
161                samplerate = 0;
162                break;
163
164        }
165        if (samplerate == 0) {
166            return false;
167        }
168
169        frmsizecod = brb.readBits(6);
170
171        if (!calcBitrateAndFrameSize(frmsizecod)) {
172            return false;
173        }
174
175        if (frameSize == 0) {
176            return false;
177        }
178        bsid = brb.readBits(5);
179        bsmod = brb.readBits(3);
180        acmod = brb.readBits(3);
181
182        if (bsid == 9) {
183            samplerate /= 2;
184        } else if (bsid != 8 && bsid != 6) {
185            return false;
186        }
187
188        if ((acmod != 1) && ((acmod & 1) == 1)) {
189            brb.readBits(2);
190        }
191
192        if (0 != (acmod & 4)) {
193            brb.readBits(2);
194        }
195
196        if (acmod == 2) {
197            brb.readBits(2);
198        }
199
200        switch (acmod) {
201            case 0:
202                channelCount = 2;
203                break;
204
205            case 1:
206                channelCount = 1;
207                break;
208
209            case 2:
210                channelCount = 2;
211                break;
212
213            case 3:
214                channelCount = 3;
215                break;
216
217            case 4:
218                channelCount = 3;
219                break;
220
221            case 5:
222                channelCount = 4;
223                break;
224
225            case 6:
226                channelCount = 4;
227                break;
228
229            case 7:
230                channelCount = 5;
231                break;
232
233        }
234
235        lfeon = brb.readBits(1);
236
237        if (lfeon == 1) {
238            channelCount++;
239        }
240        return true;
241    }
242
243    private boolean calcBitrateAndFrameSize(int code) {
244        int frmsizecode = code >>> 1;
245        int flag = code & 1;
246        if (frmsizecode > 18 || flag > 1 || fscod > 2) {
247            return false;
248        }
249        bitrate = bitRateAndFrameSizeTable[frmsizecode][flag][fscod][0];
250        frameSize = 2 * bitRateAndFrameSizeTable[frmsizecode][flag][fscod][1];
251        return true;
252    }
253
254    private boolean readSamples() throws IOException {
255        if (readSamples) {
256            return true;
257        }
258        readSamples = true;
259        byte[] header = new byte[5];
260        boolean ret = false;
261        inputStream.mark(5);
262        while (-1 != inputStream.read(header)) {
263            ret = true;
264            int frmsizecode = header[4] & 63;
265            calcBitrateAndFrameSize(frmsizecode);
266            inputStream.reset();
267            byte[] data = new byte[frameSize];
268            inputStream.read(data);
269            samples.add(ByteBuffer.wrap(data));
270            stts.add(new TimeToSampleBox.Entry(1, 1536));
271            inputStream.mark(5);
272        }
273        return ret;
274    }
275
276    private void initBitRateAndFrameSizeTable() {
277        // ETSI 102 366 Table 4.13, in frmsizecod, flag, fscod, bitrate/size order. Note that all sizes are in words, and all bitrates in kbps
278
279        // 48kHz
280        bitRateAndFrameSizeTable[0][0][0][0] = 32;
281        bitRateAndFrameSizeTable[0][1][0][0] = 32;
282        bitRateAndFrameSizeTable[0][0][0][1] = 64;
283        bitRateAndFrameSizeTable[0][1][0][1] = 64;
284        bitRateAndFrameSizeTable[1][0][0][0] = 40;
285        bitRateAndFrameSizeTable[1][1][0][0] = 40;
286        bitRateAndFrameSizeTable[1][0][0][1] = 80;
287        bitRateAndFrameSizeTable[1][1][0][1] = 80;
288        bitRateAndFrameSizeTable[2][0][0][0] = 48;
289        bitRateAndFrameSizeTable[2][1][0][0] = 48;
290        bitRateAndFrameSizeTable[2][0][0][1] = 96;
291        bitRateAndFrameSizeTable[2][1][0][1] = 96;
292        bitRateAndFrameSizeTable[3][0][0][0] = 56;
293        bitRateAndFrameSizeTable[3][1][0][0] = 56;
294        bitRateAndFrameSizeTable[3][0][0][1] = 112;
295        bitRateAndFrameSizeTable[3][1][0][1] = 112;
296        bitRateAndFrameSizeTable[4][0][0][0] = 64;
297        bitRateAndFrameSizeTable[4][1][0][0] = 64;
298        bitRateAndFrameSizeTable[4][0][0][1] = 128;
299        bitRateAndFrameSizeTable[4][1][0][1] = 128;
300        bitRateAndFrameSizeTable[5][0][0][0] = 80;
301        bitRateAndFrameSizeTable[5][1][0][0] = 80;
302        bitRateAndFrameSizeTable[5][0][0][1] = 160;
303        bitRateAndFrameSizeTable[5][1][0][1] = 160;
304        bitRateAndFrameSizeTable[6][0][0][0] = 96;
305        bitRateAndFrameSizeTable[6][1][0][0] = 96;
306        bitRateAndFrameSizeTable[6][0][0][1] = 192;
307        bitRateAndFrameSizeTable[6][1][0][1] = 192;
308        bitRateAndFrameSizeTable[7][0][0][0] = 112;
309        bitRateAndFrameSizeTable[7][1][0][0] = 112;
310        bitRateAndFrameSizeTable[7][0][0][1] = 224;
311        bitRateAndFrameSizeTable[7][1][0][1] = 224;
312        bitRateAndFrameSizeTable[8][0][0][0] = 128;
313        bitRateAndFrameSizeTable[8][1][0][0] = 128;
314        bitRateAndFrameSizeTable[8][0][0][1] = 256;
315        bitRateAndFrameSizeTable[8][1][0][1] = 256;
316        bitRateAndFrameSizeTable[9][0][0][0] = 160;
317        bitRateAndFrameSizeTable[9][1][0][0] = 160;
318        bitRateAndFrameSizeTable[9][0][0][1] = 320;
319        bitRateAndFrameSizeTable[9][1][0][1] = 320;
320        bitRateAndFrameSizeTable[10][0][0][0] = 192;
321        bitRateAndFrameSizeTable[10][1][0][0] = 192;
322        bitRateAndFrameSizeTable[10][0][0][1] = 384;
323        bitRateAndFrameSizeTable[10][1][0][1] = 384;
324        bitRateAndFrameSizeTable[11][0][0][0] = 224;
325        bitRateAndFrameSizeTable[11][1][0][0] = 224;
326        bitRateAndFrameSizeTable[11][0][0][1] = 448;
327        bitRateAndFrameSizeTable[11][1][0][1] = 448;
328        bitRateAndFrameSizeTable[12][0][0][0] = 256;
329        bitRateAndFrameSizeTable[12][1][0][0] = 256;
330        bitRateAndFrameSizeTable[12][0][0][1] = 512;
331        bitRateAndFrameSizeTable[12][1][0][1] = 512;
332        bitRateAndFrameSizeTable[13][0][0][0] = 320;
333        bitRateAndFrameSizeTable[13][1][0][0] = 320;
334        bitRateAndFrameSizeTable[13][0][0][1] = 640;
335        bitRateAndFrameSizeTable[13][1][0][1] = 640;
336        bitRateAndFrameSizeTable[14][0][0][0] = 384;
337        bitRateAndFrameSizeTable[14][1][0][0] = 384;
338        bitRateAndFrameSizeTable[14][0][0][1] = 768;
339        bitRateAndFrameSizeTable[14][1][0][1] = 768;
340        bitRateAndFrameSizeTable[15][0][0][0] = 448;
341        bitRateAndFrameSizeTable[15][1][0][0] = 448;
342        bitRateAndFrameSizeTable[15][0][0][1] = 896;
343        bitRateAndFrameSizeTable[15][1][0][1] = 896;
344        bitRateAndFrameSizeTable[16][0][0][0] = 512;
345        bitRateAndFrameSizeTable[16][1][0][0] = 512;
346        bitRateAndFrameSizeTable[16][0][0][1] = 1024;
347        bitRateAndFrameSizeTable[16][1][0][1] = 1024;
348        bitRateAndFrameSizeTable[17][0][0][0] = 576;
349        bitRateAndFrameSizeTable[17][1][0][0] = 576;
350        bitRateAndFrameSizeTable[17][0][0][1] = 1152;
351        bitRateAndFrameSizeTable[17][1][0][1] = 1152;
352        bitRateAndFrameSizeTable[18][0][0][0] = 640;
353        bitRateAndFrameSizeTable[18][1][0][0] = 640;
354        bitRateAndFrameSizeTable[18][0][0][1] = 1280;
355        bitRateAndFrameSizeTable[18][1][0][1] = 1280;
356
357        // 44.1 kHz
358        bitRateAndFrameSizeTable[0][0][1][0] = 32;
359        bitRateAndFrameSizeTable[0][1][1][0] = 32;
360        bitRateAndFrameSizeTable[0][0][1][1] = 69;
361        bitRateAndFrameSizeTable[0][1][1][1] = 70;
362        bitRateAndFrameSizeTable[1][0][1][0] = 40;
363        bitRateAndFrameSizeTable[1][1][1][0] = 40;
364        bitRateAndFrameSizeTable[1][0][1][1] = 87;
365        bitRateAndFrameSizeTable[1][1][1][1] = 88;
366        bitRateAndFrameSizeTable[2][0][1][0] = 48;
367        bitRateAndFrameSizeTable[2][1][1][0] = 48;
368        bitRateAndFrameSizeTable[2][0][1][1] = 104;
369        bitRateAndFrameSizeTable[2][1][1][1] = 105;
370        bitRateAndFrameSizeTable[3][0][1][0] = 56;
371        bitRateAndFrameSizeTable[3][1][1][0] = 56;
372        bitRateAndFrameSizeTable[3][0][1][1] = 121;
373        bitRateAndFrameSizeTable[3][1][1][1] = 122;
374        bitRateAndFrameSizeTable[4][0][1][0] = 64;
375        bitRateAndFrameSizeTable[4][1][1][0] = 64;
376        bitRateAndFrameSizeTable[4][0][1][1] = 139;
377        bitRateAndFrameSizeTable[4][1][1][1] = 140;
378        bitRateAndFrameSizeTable[5][0][1][0] = 80;
379        bitRateAndFrameSizeTable[5][1][1][0] = 80;
380        bitRateAndFrameSizeTable[5][0][1][1] = 174;
381        bitRateAndFrameSizeTable[5][1][1][1] = 175;
382        bitRateAndFrameSizeTable[6][0][1][0] = 96;
383        bitRateAndFrameSizeTable[6][1][1][0] = 96;
384        bitRateAndFrameSizeTable[6][0][1][1] = 208;
385        bitRateAndFrameSizeTable[6][1][1][1] = 209;
386        bitRateAndFrameSizeTable[7][0][1][0] = 112;
387        bitRateAndFrameSizeTable[7][1][1][0] = 112;
388        bitRateAndFrameSizeTable[7][0][1][1] = 243;
389        bitRateAndFrameSizeTable[7][1][1][1] = 244;
390        bitRateAndFrameSizeTable[8][0][1][0] = 128;
391        bitRateAndFrameSizeTable[8][1][1][0] = 128;
392        bitRateAndFrameSizeTable[8][0][1][1] = 278;
393        bitRateAndFrameSizeTable[8][1][1][1] = 279;
394        bitRateAndFrameSizeTable[9][0][1][0] = 160;
395        bitRateAndFrameSizeTable[9][1][1][0] = 160;
396        bitRateAndFrameSizeTable[9][0][1][1] = 348;
397        bitRateAndFrameSizeTable[9][1][1][1] = 349;
398        bitRateAndFrameSizeTable[10][0][1][0] = 192;
399        bitRateAndFrameSizeTable[10][1][1][0] = 192;
400        bitRateAndFrameSizeTable[10][0][1][1] = 417;
401        bitRateAndFrameSizeTable[10][1][1][1] = 418;
402        bitRateAndFrameSizeTable[11][0][1][0] = 224;
403        bitRateAndFrameSizeTable[11][1][1][0] = 224;
404        bitRateAndFrameSizeTable[11][0][1][1] = 487;
405        bitRateAndFrameSizeTable[11][1][1][1] = 488;
406        bitRateAndFrameSizeTable[12][0][1][0] = 256;
407        bitRateAndFrameSizeTable[12][1][1][0] = 256;
408        bitRateAndFrameSizeTable[12][0][1][1] = 557;
409        bitRateAndFrameSizeTable[12][1][1][1] = 558;
410        bitRateAndFrameSizeTable[13][0][1][0] = 320;
411        bitRateAndFrameSizeTable[13][1][1][0] = 320;
412        bitRateAndFrameSizeTable[13][0][1][1] = 696;
413        bitRateAndFrameSizeTable[13][1][1][1] = 697;
414        bitRateAndFrameSizeTable[14][0][1][0] = 384;
415        bitRateAndFrameSizeTable[14][1][1][0] = 384;
416        bitRateAndFrameSizeTable[14][0][1][1] = 835;
417        bitRateAndFrameSizeTable[14][1][1][1] = 836;
418        bitRateAndFrameSizeTable[15][0][1][0] = 448;
419        bitRateAndFrameSizeTable[15][1][1][0] = 448;
420        bitRateAndFrameSizeTable[15][0][1][1] = 975;
421        bitRateAndFrameSizeTable[15][1][1][1] = 975;
422        bitRateAndFrameSizeTable[16][0][1][0] = 512;
423        bitRateAndFrameSizeTable[16][1][1][0] = 512;
424        bitRateAndFrameSizeTable[16][0][1][1] = 1114;
425        bitRateAndFrameSizeTable[16][1][1][1] = 1115;
426        bitRateAndFrameSizeTable[17][0][1][0] = 576;
427        bitRateAndFrameSizeTable[17][1][1][0] = 576;
428        bitRateAndFrameSizeTable[17][0][1][1] = 1253;
429        bitRateAndFrameSizeTable[17][1][1][1] = 1254;
430        bitRateAndFrameSizeTable[18][0][1][0] = 640;
431        bitRateAndFrameSizeTable[18][1][1][0] = 640;
432        bitRateAndFrameSizeTable[18][0][1][1] = 1393;
433        bitRateAndFrameSizeTable[18][1][1][1] = 1394;
434
435        // 32kHz
436        bitRateAndFrameSizeTable[0][0][2][0] = 32;
437        bitRateAndFrameSizeTable[0][1][2][0] = 32;
438        bitRateAndFrameSizeTable[0][0][2][1] = 96;
439        bitRateAndFrameSizeTable[0][1][2][1] = 96;
440        bitRateAndFrameSizeTable[1][0][2][0] = 40;
441        bitRateAndFrameSizeTable[1][1][2][0] = 40;
442        bitRateAndFrameSizeTable[1][0][2][1] = 120;
443        bitRateAndFrameSizeTable[1][1][2][1] = 120;
444        bitRateAndFrameSizeTable[2][0][2][0] = 48;
445        bitRateAndFrameSizeTable[2][1][2][0] = 48;
446        bitRateAndFrameSizeTable[2][0][2][1] = 144;
447        bitRateAndFrameSizeTable[2][1][2][1] = 144;
448        bitRateAndFrameSizeTable[3][0][2][0] = 56;
449        bitRateAndFrameSizeTable[3][1][2][0] = 56;
450        bitRateAndFrameSizeTable[3][0][2][1] = 168;
451        bitRateAndFrameSizeTable[3][1][2][1] = 168;
452        bitRateAndFrameSizeTable[4][0][2][0] = 64;
453        bitRateAndFrameSizeTable[4][1][2][0] = 64;
454        bitRateAndFrameSizeTable[4][0][2][1] = 192;
455        bitRateAndFrameSizeTable[4][1][2][1] = 192;
456        bitRateAndFrameSizeTable[5][0][2][0] = 80;
457        bitRateAndFrameSizeTable[5][1][2][0] = 80;
458        bitRateAndFrameSizeTable[5][0][2][1] = 240;
459        bitRateAndFrameSizeTable[5][1][2][1] = 240;
460        bitRateAndFrameSizeTable[6][0][2][0] = 96;
461        bitRateAndFrameSizeTable[6][1][2][0] = 96;
462        bitRateAndFrameSizeTable[6][0][2][1] = 288;
463        bitRateAndFrameSizeTable[6][1][2][1] = 288;
464        bitRateAndFrameSizeTable[7][0][2][0] = 112;
465        bitRateAndFrameSizeTable[7][1][2][0] = 112;
466        bitRateAndFrameSizeTable[7][0][2][1] = 336;
467        bitRateAndFrameSizeTable[7][1][2][1] = 336;
468        bitRateAndFrameSizeTable[8][0][2][0] = 128;
469        bitRateAndFrameSizeTable[8][1][2][0] = 128;
470        bitRateAndFrameSizeTable[8][0][2][1] = 384;
471        bitRateAndFrameSizeTable[8][1][2][1] = 384;
472        bitRateAndFrameSizeTable[9][0][2][0] = 160;
473        bitRateAndFrameSizeTable[9][1][2][0] = 160;
474        bitRateAndFrameSizeTable[9][0][2][1] = 480;
475        bitRateAndFrameSizeTable[9][1][2][1] = 480;
476        bitRateAndFrameSizeTable[10][0][2][0] = 192;
477        bitRateAndFrameSizeTable[10][1][2][0] = 192;
478        bitRateAndFrameSizeTable[10][0][2][1] = 576;
479        bitRateAndFrameSizeTable[10][1][2][1] = 576;
480        bitRateAndFrameSizeTable[11][0][2][0] = 224;
481        bitRateAndFrameSizeTable[11][1][2][0] = 224;
482        bitRateAndFrameSizeTable[11][0][2][1] = 672;
483        bitRateAndFrameSizeTable[11][1][2][1] = 672;
484        bitRateAndFrameSizeTable[12][0][2][0] = 256;
485        bitRateAndFrameSizeTable[12][1][2][0] = 256;
486        bitRateAndFrameSizeTable[12][0][2][1] = 768;
487        bitRateAndFrameSizeTable[12][1][2][1] = 768;
488        bitRateAndFrameSizeTable[13][0][2][0] = 320;
489        bitRateAndFrameSizeTable[13][1][2][0] = 320;
490        bitRateAndFrameSizeTable[13][0][2][1] = 960;
491        bitRateAndFrameSizeTable[13][1][2][1] = 960;
492        bitRateAndFrameSizeTable[14][0][2][0] = 384;
493        bitRateAndFrameSizeTable[14][1][2][0] = 384;
494        bitRateAndFrameSizeTable[14][0][2][1] = 1152;
495        bitRateAndFrameSizeTable[14][1][2][1] = 1152;
496        bitRateAndFrameSizeTable[15][0][2][0] = 448;
497        bitRateAndFrameSizeTable[15][1][2][0] = 448;
498        bitRateAndFrameSizeTable[15][0][2][1] = 1344;
499        bitRateAndFrameSizeTable[15][1][2][1] = 1344;
500        bitRateAndFrameSizeTable[16][0][2][0] = 512;
501        bitRateAndFrameSizeTable[16][1][2][0] = 512;
502        bitRateAndFrameSizeTable[16][0][2][1] = 1536;
503        bitRateAndFrameSizeTable[16][1][2][1] = 1536;
504        bitRateAndFrameSizeTable[17][0][2][0] = 576;
505        bitRateAndFrameSizeTable[17][1][2][0] = 576;
506        bitRateAndFrameSizeTable[17][0][2][1] = 1728;
507        bitRateAndFrameSizeTable[17][1][2][1] = 1728;
508        bitRateAndFrameSizeTable[18][0][2][0] = 640;
509        bitRateAndFrameSizeTable[18][1][2][0] = 640;
510        bitRateAndFrameSizeTable[18][0][2][1] = 1920;
511        bitRateAndFrameSizeTable[18][1][2][1] = 1920;
512    }
513}