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

AACTrackImpl

public class AACTrackImpl extends com.googlecode.mp4parser.authoring.AbstractTrack

Fields Summary
public static Map
samplingFrequencyIndexMap
com.googlecode.mp4parser.authoring.TrackMetaData
trackMetaData
SampleDescriptionBox
sampleDescriptionBox
int
samplerate
int
bitrate
int
channelCount
int
channelconfig
int
bufferSizeDB
long
maxBitRate
long
avgBitRate
private BufferedInputStream
inputStream
private List
samples
boolean
readSamples
List
stts
private String
lang
Constructors Summary
public AACTrackImpl(InputStream inputStream, String lang)



           
        this.lang = lang;
        parse(inputStream);
     
public AACTrackImpl(InputStream inputStream)

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

        return null;
    
public java.util.ListgetDecodingTimeEntries()

        return stts;
    
public java.lang.StringgetHandler()

        return "soun";
    
public BoxgetMediaHeaderBox()

        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 inputStream)

        this.inputStream = new BufferedInputStream(inputStream);
        stts = new LinkedList<TimeToSampleBox.Entry>();

        if (!readVariables()) {
            throw new IOException();
        }

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

        double packetsPerSecond = (double)samplerate / 1024.0;
        double duration = samples.size() / packetsPerSecond;

        long dataSize = 0;
        LinkedList<Integer> queue = new LinkedList<Integer>();
        for (int i = 0; i < samples.size(); i++) {
            int size = samples.get(i).capacity();
            dataSize += size;
            queue.add(size);
            while (queue.size() > packetsPerSecond) {
                queue.pop();
            }
            if (queue.size() == (int) packetsPerSecond) {
                int currSize = 0;
                for (int j = 0 ; j < queue.size(); j++) {
                    currSize += queue.get(j);
                }
                double currBitrate = 8.0 * currSize / queue.size() * packetsPerSecond;
                if (currBitrate > maxBitRate) {
                    maxBitRate = (int)currBitrate;
                }
            }
        }

        avgBitRate = (int) (8 * dataSize / duration);

        bufferSizeDB = 1536; /* TODO: Calcultate this somehow! */

        sampleDescriptionBox = new SampleDescriptionBox();
        AudioSampleEntry audioSampleEntry = new AudioSampleEntry("mp4a");
        audioSampleEntry.setChannelCount(2);
        audioSampleEntry.setSampleRate(samplerate);
        audioSampleEntry.setDataReferenceIndex(1);
        audioSampleEntry.setSampleSize(16);


        ESDescriptorBox esds = new ESDescriptorBox();
        ESDescriptor descriptor = new ESDescriptor();
        descriptor.setEsId(0);

        SLConfigDescriptor slConfigDescriptor = new SLConfigDescriptor();
        slConfigDescriptor.setPredefined(2);
        descriptor.setSlConfigDescriptor(slConfigDescriptor);

        DecoderConfigDescriptor decoderConfigDescriptor = new DecoderConfigDescriptor();
        decoderConfigDescriptor.setObjectTypeIndication(0x40);
        decoderConfigDescriptor.setStreamType(5);
        decoderConfigDescriptor.setBufferSizeDB(bufferSizeDB);
        decoderConfigDescriptor.setMaxBitRate(maxBitRate);
        decoderConfigDescriptor.setAvgBitRate(avgBitRate);

        AudioSpecificConfig audioSpecificConfig = new AudioSpecificConfig();
        audioSpecificConfig.setAudioObjectType(2); // AAC LC
        audioSpecificConfig.setSamplingFrequencyIndex(samplingFrequencyIndexMap.get(samplerate));
        audioSpecificConfig.setChannelConfiguration(channelconfig);
        decoderConfigDescriptor.setAudioSpecificInfo(audioSpecificConfig);

        descriptor.setDecoderConfigDescriptor(decoderConfigDescriptor);

        ByteBuffer data = descriptor.serialize();
        esds.setData(data);
        audioSampleEntry.addBox(esds);
        sampleDescriptionBox.addBox(audioSampleEntry);

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

        if (readSamples) {
            return true;
        }

        readSamples = true;
        byte[] header = new byte[15];
        boolean ret = false;
        inputStream.mark(15);
        while (-1 != inputStream.read(header)) {
            ret = true;
            ByteBuffer bb = ByteBuffer.wrap(header);
            inputStream.reset();
            BitReaderBuffer brb = new BitReaderBuffer(bb);
            int syncword = brb.readBits(12);
            if (syncword != 0xfff) {
                return false;
            }
            brb.readBits(3);
            int protectionAbsent = brb.readBits(1);
            brb.readBits(14);
            int frameSize = brb.readBits(13);
            int bufferFullness = brb.readBits(11);
            int noBlocks = brb.readBits(2);
            int used = (int) Math.ceil(brb.getPosition() / 8.0);
            if (protectionAbsent == 0) {
                used += 2;
            }
            inputStream.skip(used);
            frameSize -= used;
//            System.out.println("Size: " + frameSize + " fullness: " + bufferFullness + " no blocks: " + noBlocks);
            byte[] data = new byte[frameSize];
            inputStream.read(data);
            samples.add(ByteBuffer.wrap(data));
            stts.add(new TimeToSampleBox.Entry(1, 1024));
            inputStream.mark(15);
        }
        return ret;
    
private booleanreadVariables()

        byte[] data = new byte[100];
        inputStream.mark(100);
        if (100 != inputStream.read(data, 0, 100)) {
            return false;
        }
        inputStream.reset(); // Rewind
        ByteBuffer bb = ByteBuffer.wrap(data);
        BitReaderBuffer brb = new BitReaderBuffer(bb);
        int syncword = brb.readBits(12);
        if (syncword != 0xfff) {
            return false;
        }
        int id = brb.readBits(1);
        int layer = brb.readBits(2);
        int protectionAbsent = brb.readBits(1);
        int profile = brb.readBits(2);
        samplerate = samplingFrequencyIndexMap.get(brb.readBits(4));
        brb.readBits(1);
        channelconfig = brb.readBits(3);
        int original = brb.readBits(1);
        int home = brb.readBits(1);
        int emphasis = brb.readBits(2);

        return true;
    
public java.lang.StringtoString()

        return "AACTrackImpl{" +
                "samplerate=" + samplerate +
                ", bitrate=" + bitrate +
                ", channelCount=" + channelCount +
                ", channelconfig=" + channelconfig +
                '}";