FileDocCategorySizeDatePackage
EC3TrackImpl.javaAPI Docmp4parser 1.0-RC-1713623Wed Dec 19 20:10:37 GMT 2012com.googlecode.mp4parser.authoring.tracks

EC3TrackImpl

public class EC3TrackImpl extends com.googlecode.mp4parser.authoring.AbstractTrack
Created by IntelliJ IDEA. User: magnus Date: 2012-03-14 Time: 10:39 To change this template use File | Settings | File Templates.

Fields Summary
com.googlecode.mp4parser.authoring.TrackMetaData
trackMetaData
SampleDescriptionBox
sampleDescriptionBox
int
samplerate
int
bitrate
int
frameSize
List
entries
private BufferedInputStream
inputStream
private List
samples
List
stts
private String
lang
Constructors Summary
public EC3TrackImpl(InputStream fin, String lang)


           
        this.lang = lang;
        parse(fin);
    
public EC3TrackImpl(InputStream fin)

        parse(fin);
    
Methods Summary
public java.util.ListgetCompositionTimeEntries()

        return null;
    
public java.util.ListgetDecodingTimeEntries()

        return stts;
    
public java.lang.StringgetHandler()

        return "soun";
    
public AbstractMediaHeaderBoxgetMediaHeaderBox()

        return new SoundMediaHeaderBox();
    
public java.util.ListgetSampleDependencies()

        return null;
    
public SampleDescriptionBoxgetSampleDescriptionBox()

        return sampleDescriptionBox;
    
public java.util.ListgetSamples()


        return samples;
    
public SubSampleInformationBoxgetSubsampleInformationBox()

        return null;
    
public long[]getSyncSamples()

        return null;
    
public com.googlecode.mp4parser.authoring.TrackMetaDatagetTrackMetaData()

        return trackMetaData;
    
private voidparse(java.io.InputStream fin)

        inputStream = new BufferedInputStream(fin);

        boolean done = false;
        inputStream.mark(10000);
        while (!done) {
            BitStreamInfo bsi = readVariables();
            if (bsi == null) {
                throw new IOException();
            }
            for (BitStreamInfo entry : entries) {
                if (bsi.strmtyp != 1 && entry.substreamid == bsi.substreamid) {
                    done = true;
                }
            }
            if (!done) {
                entries.add(bsi);
                long skipped = inputStream.skip(bsi.frameSize);
                assert skipped == bsi.frameSize;
            }
        }

        inputStream.reset();

        if (entries.size() == 0) {
            throw new IOException();
        }
        samplerate = entries.get(0).samplerate;

        sampleDescriptionBox = new SampleDescriptionBox();
        AudioSampleEntry audioSampleEntry = new AudioSampleEntry("ec-3");
        audioSampleEntry.setChannelCount(2);  // According to  ETSI TS 102 366 Annex F
        audioSampleEntry.setSampleRate(samplerate);
        audioSampleEntry.setDataReferenceIndex(1);
        audioSampleEntry.setSampleSize(16);

        EC3SpecificBox ec3 = new EC3SpecificBox();
        int[] deps = new int[entries.size()];
        int[] chan_locs = new int[entries.size()];
        for (BitStreamInfo bsi : entries) {
            if (bsi.strmtyp == 1) {
                deps[bsi.substreamid]++;
                chan_locs[bsi.substreamid] = ((bsi.chanmap >> 6) & 0x100) | ((bsi.chanmap >> 5) & 0xff);
            }
        }
        for (BitStreamInfo bsi : entries) {
            if (bsi.strmtyp != 1) {
                EC3SpecificBox.Entry e = new EC3SpecificBox.Entry();
                e.fscod = bsi.fscod;
                e.bsid = bsi.bsid;
                e.bsmod = bsi.bsmod;
                e.acmod = bsi.acmod;
                e.lfeon = bsi.lfeon;
                e.reserved = 0;
                e.num_dep_sub = deps[bsi.substreamid];
                e.chan_loc = chan_locs[bsi.substreamid];
                e.reserved2 = 0;
                ec3.addEntry(e);
            }
            bitrate += bsi.bitrate;
            frameSize += bsi.frameSize;
        }

        ec3.setDataRate(bitrate / 1000);
        audioSampleEntry.addBox(ec3);
        sampleDescriptionBox.addBox(audioSampleEntry);

        trackMetaData.setCreationTime(new Date());
        trackMetaData.setModificationTime(new Date());
        trackMetaData.setLanguage(lang);
        trackMetaData.setTimescale(samplerate); // Audio tracks always use samplerate as timescale

        samples = new LinkedList<ByteBuffer>();
        if (!readSamples()) {
            throw new IOException();
        }
    
private booleanreadSamples()

        int read = frameSize;
        boolean ret = false;
        while (frameSize == read) {
            ret = true;
            byte[] data = new byte[frameSize];
            read = inputStream.read(data);
            if (read == frameSize) {
                samples.add(ByteBuffer.wrap(data));
                stts.add(new TimeToSampleBox.Entry(1, 1536));
            }
        }
        return ret;
    
private com.googlecode.mp4parser.authoring.tracks.EC3TrackImpl$BitStreamInforeadVariables()

        byte[] data = new byte[200];
        inputStream.mark(200);
        if (200 != inputStream.read(data, 0, 200)) {
            return null;
        }
        inputStream.reset(); // Rewind
        ByteBuffer bb = ByteBuffer.wrap(data);
        BitReaderBuffer brb = new BitReaderBuffer(bb);
        int syncword = brb.readBits(16);
        if (syncword != 0xb77) {
            return null;
        }

        BitStreamInfo entry = new BitStreamInfo();

        entry.strmtyp = brb.readBits(2);
        entry.substreamid = brb.readBits(3);
        int frmsiz = brb.readBits(11);
        entry.frameSize = 2 * (frmsiz + 1);

        entry.fscod = brb.readBits(2);
        int fscod2 = -1;
        int numblkscod;
        if (entry.fscod == 3) {
            fscod2 = brb.readBits(2);
            numblkscod = 3;
        } else {
            numblkscod = brb.readBits(2);
        }
        int numberOfBlocksPerSyncFrame = 0;
        switch (numblkscod) {
            case 0:
                numberOfBlocksPerSyncFrame = 1;
                break;

            case 1:
                numberOfBlocksPerSyncFrame = 2;
                break;

            case 2:
                numberOfBlocksPerSyncFrame = 3;
                break;

            case 3:
                numberOfBlocksPerSyncFrame = 6;
                break;

        }
        entry.frameSize *= (6 / numberOfBlocksPerSyncFrame);

        entry.acmod = brb.readBits(3);
        entry.lfeon = brb.readBits(1);
        entry.bsid = brb.readBits(5);
        brb.readBits(5);
        if (1 == brb.readBits(1)) {
            brb.readBits(8); // compr
        }
        if (0 == entry.acmod) {
            brb.readBits(5);
            if (1 == brb.readBits(1)) {
                brb.readBits(8);
            }
        }
        if (1 == entry.strmtyp) {
            if (1 == brb.readBits(1)) {
                entry.chanmap = brb.readBits(16);
            }
        }
        if (1 == brb.readBits(1)) {     // mixing metadata
            if (entry.acmod > 2) {
                brb.readBits(2);
            }
            if (1 == (entry.acmod & 1) && entry.acmod > 2) {
                brb.readBits(3);
                brb.readBits(3);
            }
            if (0 < (entry.acmod & 4)) {
                brb.readBits(3);
                brb.readBits(3);
            }
            if (1 == entry.lfeon) {
                if (1 == brb.readBits(1)) {
                    brb.readBits(5);
                }
            }
            if (0 == entry.strmtyp) {
                if (1 == brb.readBits(1)) {
                    brb.readBits(6);
                }
                if (0 == entry.acmod) {
                    if (1 == brb.readBits(1)) {
                        brb.readBits(6);
                    }
                }
                if (1 == brb.readBits(1)) {
                    brb.readBits(6);
                }
                int mixdef = brb.readBits(2);
                if (1 == mixdef) {
                    brb.readBits(5);
                } else if (2 == mixdef) {
                    brb.readBits(12);
                } else if (3 == mixdef) {
                    int mixdeflen = brb.readBits(5);
                    if (1 == brb.readBits(1)) {
                        brb.readBits(5);
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            brb.readBits(4);
                        }
                        if (1 == brb.readBits(1)) {
                            if (1 == brb.readBits(1)) {
                                brb.readBits(4);
                            }
                            if (1 == brb.readBits(1)) {
                                brb.readBits(4);
                            }
                        }
                    }
                    if (1 == brb.readBits(1)) {
                        brb.readBits(5);
                        if (1 == brb.readBits(1)) {
                            brb.readBits(7);
                            if (1 == brb.readBits(1)) {
                                brb.readBits(8);
                            }
                        }
                    }
                    for (int i = 0; i < (mixdeflen + 2); i++) {
                        brb.readBits(8);
                    }
                    brb.byteSync();
                }
                if (entry.acmod < 2) {
                    if (1 == brb.readBits(1)) {
                        brb.readBits(14);
                    }
                    if (0 == entry.acmod) {
                        if (1 == brb.readBits(1)) {
                            brb.readBits(14);
                        }
                    }
                    if (1 == brb.readBits(1)) {
                        if (numblkscod == 0) {
                            brb.readBits(5);
                        } else {
                            for (int i = 0; i < numberOfBlocksPerSyncFrame; i++) {
                                if (1 == brb.readBits(1)) {
                                    brb.readBits(5);
                                }
                            }
                        }

                    }
                }
            }
        }
        if (1 == brb.readBits(1)) { // infomdate
            entry.bsmod = brb.readBits(3);
        }

        switch (entry.fscod) {
            case 0:
                entry.samplerate = 48000;
                break;

            case 1:
                entry.samplerate = 44100;
                break;

            case 2:
                entry.samplerate = 32000;
                break;

            case 3: {
                switch (fscod2) {
                    case 0:
                        entry.samplerate = 24000;
                        break;

                    case 1:
                        entry.samplerate = 22050;
                        break;

                    case 2:
                        entry.samplerate = 16000;
                        break;

                    case 3:
                        entry.samplerate = 0;
                        break;
                }
                break;
            }

        }
        if (entry.samplerate == 0) {
            return null;
        }

        entry.bitrate = (int) (((double) entry.samplerate) / 1536.0 * entry.frameSize * 8);

        return entry;
    
public java.lang.StringtoString()

        return "EC3TrackImpl{" +
                "bitrate=" + bitrate +
                ", samplerate=" + samplerate +
                ", entries=" + entries +
                '}";