summaryrefslogtreecommitdiff
path: root/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/EC3TrackImpl.java.svn-base
diff options
context:
space:
mode:
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-base436
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 +
+ '}';
+ }
+}