diff options
Diffstat (limited to 'isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/EC3TrackImpl.java.svn-base')
-rw-r--r-- | isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/EC3TrackImpl.java.svn-base | 436 |
1 files changed, 436 insertions, 0 deletions
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/EC3TrackImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/EC3TrackImpl.java.svn-base new file mode 100644 index 0000000..d0b2d76 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/EC3TrackImpl.java.svn-base @@ -0,0 +1,436 @@ +package com.googlecode.mp4parser.authoring.tracks; + +import com.coremedia.iso.boxes.*; +import com.coremedia.iso.boxes.sampleentry.AudioSampleEntry; +import com.googlecode.mp4parser.authoring.AbstractTrack; +import com.googlecode.mp4parser.authoring.TrackMetaData; +import com.googlecode.mp4parser.boxes.EC3SpecificBox; +import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: magnus + * Date: 2012-03-14 + * Time: 10:39 + * To change this template use File | Settings | File Templates. + */ +public class EC3TrackImpl extends AbstractTrack { + TrackMetaData trackMetaData = new TrackMetaData(); + SampleDescriptionBox sampleDescriptionBox; + + int samplerate; + int bitrate; + int frameSize; + + List<BitStreamInfo> entries = new LinkedList<BitStreamInfo>(); + + private BufferedInputStream inputStream; + private List<ByteBuffer> samples; + List<TimeToSampleBox.Entry> stts = new LinkedList<TimeToSampleBox.Entry>(); + private String lang = "und"; + + public EC3TrackImpl(InputStream fin, String lang) throws IOException { + this.lang = lang; + parse(fin); + } + + public EC3TrackImpl(InputStream fin) throws IOException { + parse(fin); + } + + private void parse(InputStream fin) throws IOException { + 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(); + } + } + + + public List<ByteBuffer> getSamples() { + + return samples; + } + + public SampleDescriptionBox getSampleDescriptionBox() { + return sampleDescriptionBox; + } + + public List<TimeToSampleBox.Entry> getDecodingTimeEntries() { + return stts; + } + + public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() { + return null; + } + + public long[] getSyncSamples() { + return null; + } + + public List<SampleDependencyTypeBox.Entry> getSampleDependencies() { + return null; + } + + public TrackMetaData getTrackMetaData() { + return trackMetaData; + } + + public String getHandler() { + return "soun"; + } + + public AbstractMediaHeaderBox getMediaHeaderBox() { + return new SoundMediaHeaderBox(); + } + + public SubSampleInformationBox getSubsampleInformationBox() { + return null; + } + + private BitStreamInfo readVariables() throws IOException { + 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; + } + + private boolean readSamples() throws IOException { + 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; + } + + public static class BitStreamInfo extends EC3SpecificBox.Entry { + public int frameSize; + public int substreamid; + public int bitrate; + public int samplerate; + public int strmtyp; + public int chanmap; + + @Override + public String toString() { + return "BitStreamInfo{" + + "frameSize=" + frameSize + + ", substreamid=" + substreamid + + ", bitrate=" + bitrate + + ", samplerate=" + samplerate + + ", strmtyp=" + strmtyp + + ", chanmap=" + chanmap + + '}'; + } + } + + @Override + public String toString() { + return "EC3TrackImpl{" + + "bitrate=" + bitrate + + ", samplerate=" + samplerate + + ", entries=" + entries + + '}'; + } +} |