diff options
author | Teng-Hui Zhu <ztenghui@google.com> | 2012-09-23 14:06:01 -0700 |
---|---|---|
committer | Teng-Hui Zhu <ztenghui@google.com> | 2012-09-23 14:07:00 -0700 |
commit | d6072f0a479bb3bb6fe1ef2825b9ee6187827d96 (patch) | |
tree | 045d208ea840d3ee0821f0666c773e4e31affe7d /isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base | |
parent | dd9eb897ee7c7b507cbdcf80263bb4b5de6966bf (diff) | |
download | mp4parser-d6072f0a479bb3bb6fe1ef2825b9ee6187827d96.tar.gz |
Remove all the .svn directory
bug:7093055
Change-Id: Iea526bdda3ba27736440daf17ff8b25ff4fb3660
Diffstat (limited to 'isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base')
7 files changed, 0 insertions, 1078 deletions
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/AbstractManifestWriter.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/AbstractManifestWriter.java.svn-base deleted file mode 100644 index 6ee4ffa..0000000 --- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/AbstractManifestWriter.java.svn-base +++ /dev/null @@ -1,126 +0,0 @@ -package com.googlecode.mp4parser.authoring.adaptivestreaming;
-
-import com.coremedia.iso.boxes.OriginalFormatBox;
-import com.coremedia.iso.boxes.TimeToSampleBox;
-import com.coremedia.iso.boxes.sampleentry.SampleEntry;
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.builder.FragmentIntersectionFinder;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.logging.Logger;
-
-import static com.googlecode.mp4parser.util.CastUtils.l2i;
-
-/**
- * Created with IntelliJ IDEA.
- * User: mstattma
- * Date: 17.08.12
- * Time: 02:51
- * To change this template use File | Settings | File Templates.
- */
-public abstract class AbstractManifestWriter implements ManifestWriter {
- private static final Logger LOG = Logger.getLogger(AbstractManifestWriter.class.getName());
-
- private FragmentIntersectionFinder intersectionFinder;
- protected long[] audioFragmentsDurations;
- protected long[] videoFragmentsDurations;
-
- protected AbstractManifestWriter(FragmentIntersectionFinder intersectionFinder) {
- this.intersectionFinder = intersectionFinder;
- }
-
- /**
- * Calculates the length of each fragment in the given <code>track</code> (as part of <code>movie</code>).
- *
- * @param track target of calculation
- * @param movie the <code>track</code> must be part of this <code>movie</code>
- * @return the duration of each fragment in track timescale
- */
- public long[] calculateFragmentDurations(Track track, Movie movie) {
- long[] startSamples = intersectionFinder.sampleNumbers(track, movie);
- long[] durations = new long[startSamples.length];
- int currentFragment = 0;
- int currentSample = 1; // sync samples start with 1 !
-
- for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {
- for (int max = currentSample + l2i(entry.getCount()); currentSample < max; currentSample++) {
- // in this loop we go through the entry.getCount() samples starting from current sample.
- // the next entry.getCount() samples have the same decoding time.
- if (currentFragment != startSamples.length - 1 && currentSample == startSamples[currentFragment + 1]) {
- // we are not in the last fragment && the current sample is the start sample of the next fragment
- currentFragment++;
- }
- durations[currentFragment] += entry.getDelta();
-
-
- }
- }
- return durations;
-
- }
-
- public long getBitrate(Track track) {
- long bitrate = 0;
- for (ByteBuffer sample : track.getSamples()) {
- bitrate += sample.limit();
- }
- bitrate *= 8; // from bytes to bits
- bitrate /= ((double) getDuration(track)) / track.getTrackMetaData().getTimescale(); // per second
- return bitrate;
- }
-
- protected static long getDuration(Track track) {
- long duration = 0;
- for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {
- duration += entry.getCount() * entry.getDelta();
- }
- return duration;
- }
-
- protected long[] checkFragmentsAlign(long[] referenceTimes, long[] checkTimes) throws IOException {
-
- if (referenceTimes == null || referenceTimes.length == 0) {
- return checkTimes;
- }
- long[] referenceTimesMinusLast = new long[referenceTimes.length - 1];
- System.arraycopy(referenceTimes, 0, referenceTimesMinusLast, 0, referenceTimes.length - 1);
- long[] checkTimesMinusLast = new long[checkTimes.length - 1];
- System.arraycopy(checkTimes, 0, checkTimesMinusLast, 0, checkTimes.length - 1);
-
- if (!Arrays.equals(checkTimesMinusLast, referenceTimesMinusLast)) {
- String log = "";
- log += (referenceTimes.length);
- log += ("Reference : [");
- for (long l : referenceTimes) {
- log += (String.format("%10d,", l));
- }
- log += ("]");
- LOG.warning(log);
- log = "";
-
- log += (checkTimes.length);
- log += ("Current : [");
- for (long l : checkTimes) {
- log += (String.format("%10d,", l));
- }
- log += ("]");
- LOG.warning(log);
- throw new IOException("Track does not have the same fragment borders as its predecessor.");
-
- } else {
- return checkTimes;
- }
- }
-
- protected String getFormat(SampleEntry se) {
- String type = se.getType();
- if (type.equals("encv") || type.equals("enca") || type.equals("encv")) {
- OriginalFormatBox frma = se.getBoxes(OriginalFormatBox.class, true).get(0);
- type = frma.getDataFormat();
- }
- return type;
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/AudioQuality.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/AudioQuality.java.svn-base deleted file mode 100644 index 39e115f..0000000 --- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/AudioQuality.java.svn-base +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012 Sebastian Annies, Hamburg - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.googlecode.mp4parser.authoring.adaptivestreaming; - - -public class AudioQuality { - String fourCC; - long bitrate; - int audioTag; - long samplingRate; - int channels; - int bitPerSample; - int packetSize; - String language; - String codecPrivateData; -} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/FlatManifestWriterImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/FlatManifestWriterImpl.java.svn-base deleted file mode 100644 index 5cc9be9..0000000 --- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/FlatManifestWriterImpl.java.svn-base +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Copyright 2012 Sebastian Annies, Hamburg - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.googlecode.mp4parser.authoring.adaptivestreaming; - -import com.coremedia.iso.Hex; -import com.coremedia.iso.boxes.SampleDescriptionBox; -import com.coremedia.iso.boxes.SoundMediaHeaderBox; -import com.coremedia.iso.boxes.VideoMediaHeaderBox; -import com.coremedia.iso.boxes.h264.AvcConfigurationBox; -import com.coremedia.iso.boxes.sampleentry.AudioSampleEntry; -import com.coremedia.iso.boxes.sampleentry.VisualSampleEntry; -import com.googlecode.mp4parser.Version; -import com.googlecode.mp4parser.authoring.Movie; -import com.googlecode.mp4parser.authoring.Track; -import com.googlecode.mp4parser.authoring.builder.FragmentIntersectionFinder; -import com.googlecode.mp4parser.boxes.DTSSpecificBox; -import com.googlecode.mp4parser.boxes.EC3SpecificBox; -import com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox; -import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.AudioSpecificConfig; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.*; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.StringWriter; -import java.nio.ByteBuffer; -import java.util.LinkedList; -import java.util.List; -import java.util.logging.Logger; - -public class FlatManifestWriterImpl extends AbstractManifestWriter { - private static final Logger LOG = Logger.getLogger(FlatManifestWriterImpl.class.getName()); - - protected FlatManifestWriterImpl(FragmentIntersectionFinder intersectionFinder) { - super(intersectionFinder); - } - - /** - * Overwrite this method in subclasses to add your specialities. - * - * @param manifest the original manifest - * @return your customized version of the manifest - */ - protected Document customizeManifest(Document manifest) { - return manifest; - } - - public String getManifest(Movie movie) throws IOException { - - LinkedList<VideoQuality> videoQualities = new LinkedList<VideoQuality>(); - long videoTimescale = -1; - - LinkedList<AudioQuality> audioQualities = new LinkedList<AudioQuality>(); - long audioTimescale = -1; - - for (Track track : movie.getTracks()) { - if (track.getMediaHeaderBox() instanceof VideoMediaHeaderBox) { - videoFragmentsDurations = checkFragmentsAlign(videoFragmentsDurations, calculateFragmentDurations(track, movie)); - SampleDescriptionBox stsd = track.getSampleDescriptionBox(); - videoQualities.add(getVideoQuality(track, (VisualSampleEntry) stsd.getSampleEntry())); - if (videoTimescale == -1) { - videoTimescale = track.getTrackMetaData().getTimescale(); - } else { - assert videoTimescale == track.getTrackMetaData().getTimescale(); - } - } - if (track.getMediaHeaderBox() instanceof SoundMediaHeaderBox) { - audioFragmentsDurations = checkFragmentsAlign(audioFragmentsDurations, calculateFragmentDurations(track, movie)); - SampleDescriptionBox stsd = track.getSampleDescriptionBox(); - audioQualities.add(getAudioQuality(track, (AudioSampleEntry) stsd.getSampleEntry())); - if (audioTimescale == -1) { - audioTimescale = track.getTrackMetaData().getTimescale(); - } else { - assert audioTimescale == track.getTrackMetaData().getTimescale(); - } - - } - } - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder; - try { - documentBuilder = documentBuilderFactory.newDocumentBuilder(); - } catch (ParserConfigurationException e) { - throw new IOException(e); - } - Document document = documentBuilder.newDocument(); - - - Element smoothStreamingMedia = document.createElement("SmoothStreamingMedia"); - document.appendChild(smoothStreamingMedia); - smoothStreamingMedia.setAttribute("MajorVersion", "2"); - smoothStreamingMedia.setAttribute("MinorVersion", "1"); -// silverlight ignores the timescale attr smoothStreamingMedia.addAttribute(new Attribute("TimeScale", Long.toString(movieTimeScale))); - smoothStreamingMedia.setAttribute("Duration", "0"); - - smoothStreamingMedia.appendChild(document.createComment(Version.VERSION)); - Element videoStreamIndex = document.createElement("StreamIndex"); - videoStreamIndex.setAttribute("Type", "video"); - videoStreamIndex.setAttribute("TimeScale", Long.toString(videoTimescale)); // silverlight ignores the timescale attr - videoStreamIndex.setAttribute("Chunks", Integer.toString(videoFragmentsDurations.length)); - videoStreamIndex.setAttribute("Url", "video/{bitrate}/{start time}"); - videoStreamIndex.setAttribute("QualityLevels", Integer.toString(videoQualities.size())); - smoothStreamingMedia.appendChild(videoStreamIndex); - - for (int i = 0; i < videoQualities.size(); i++) { - VideoQuality vq = videoQualities.get(i); - Element qualityLevel = document.createElement("QualityLevel"); - qualityLevel.setAttribute("Index", Integer.toString(i)); - qualityLevel.setAttribute("Bitrate", Long.toString(vq.bitrate)); - qualityLevel.setAttribute("FourCC", vq.fourCC); - qualityLevel.setAttribute("MaxWidth", Long.toString(vq.width)); - qualityLevel.setAttribute("MaxHeight", Long.toString(vq.height)); - qualityLevel.setAttribute("CodecPrivateData", vq.codecPrivateData); - qualityLevel.setAttribute("NALUnitLengthField", Integer.toString(vq.nalLength)); - videoStreamIndex.appendChild(qualityLevel); - } - - for (int i = 0; i < videoFragmentsDurations.length; i++) { - Element c = document.createElement("c"); - c.setAttribute("n", Integer.toString(i)); - c.setAttribute("d", Long.toString(videoFragmentsDurations[i])); - videoStreamIndex.appendChild(c); - } - - if (audioFragmentsDurations != null) { - Element audioStreamIndex = document.createElement("StreamIndex"); - audioStreamIndex.setAttribute("Type", "audio"); - audioStreamIndex.setAttribute("TimeScale", Long.toString(audioTimescale)); // silverlight ignores the timescale attr - audioStreamIndex.setAttribute("Chunks", Integer.toString(audioFragmentsDurations.length)); - audioStreamIndex.setAttribute("Url", "audio/{bitrate}/{start time}"); - audioStreamIndex.setAttribute("QualityLevels", Integer.toString(audioQualities.size())); - smoothStreamingMedia.appendChild(audioStreamIndex); - - for (int i = 0; i < audioQualities.size(); i++) { - AudioQuality aq = audioQualities.get(i); - Element qualityLevel = document.createElement("QualityLevel"); - qualityLevel.setAttribute("Index", Integer.toString(i)); - qualityLevel.setAttribute("FourCC", aq.fourCC); - qualityLevel.setAttribute("Bitrate", Long.toString(aq.bitrate)); - qualityLevel.setAttribute("AudioTag", Integer.toString(aq.audioTag)); - qualityLevel.setAttribute("SamplingRate", Long.toString(aq.samplingRate)); - qualityLevel.setAttribute("Channels", Integer.toString(aq.channels)); - qualityLevel.setAttribute("BitsPerSample", Integer.toString(aq.bitPerSample)); - qualityLevel.setAttribute("PacketSize", Integer.toString(aq.packetSize)); - qualityLevel.setAttribute("CodecPrivateData", aq.codecPrivateData); - audioStreamIndex.appendChild(qualityLevel); - } - for (int i = 0; i < audioFragmentsDurations.length; i++) { - Element c = document.createElement("c"); - c.setAttribute("n", Integer.toString(i)); - c.setAttribute("d", Long.toString(audioFragmentsDurations[i])); - audioStreamIndex.appendChild(c); - } - } - - document.setXmlStandalone(true); - Source source = new DOMSource(document); - StringWriter stringWriter = new StringWriter(); - Result result = new StreamResult(stringWriter); - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer; - try { - transformer = factory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.transform(source, result); - } catch (TransformerConfigurationException e) { - throw new IOException(e); - } catch (TransformerException e) { - throw new IOException(e); - } - return stringWriter.getBuffer().toString(); - - - } - - private AudioQuality getAudioQuality(Track track, AudioSampleEntry ase) { - if (getFormat(ase).equals("mp4a")) { - return getAacAudioQuality(track, ase); - } else if (getFormat(ase).equals("ec-3")) { - return getEc3AudioQuality(track, ase); - } else if (getFormat(ase).startsWith("dts")) { - return getDtsAudioQuality(track, ase); - } else { - throw new InternalError("I don't know what to do with audio of type " + getFormat(ase)); - } - - } - - private AudioQuality getAacAudioQuality(Track track, AudioSampleEntry ase) { - AudioQuality l = new AudioQuality(); - final ESDescriptorBox esDescriptorBox = ase.getBoxes(ESDescriptorBox.class).get(0); - final AudioSpecificConfig audioSpecificConfig = esDescriptorBox.getEsDescriptor().getDecoderConfigDescriptor().getAudioSpecificInfo(); - if (audioSpecificConfig.getSbrPresentFlag() == 1) { - l.fourCC = "AACH"; - } else if (audioSpecificConfig.getPsPresentFlag() == 1) { - l.fourCC = "AACP"; //I'm not sure if that's what MS considers as AAC+ - because actually AAC+ and AAC-HE should be the same... - } else { - l.fourCC = "AACL"; - } - l.bitrate = getBitrate(track); - l.audioTag = 255; - l.samplingRate = ase.getSampleRate(); - l.channels = ase.getChannelCount(); - l.bitPerSample = ase.getSampleSize(); - l.packetSize = 4; - l.codecPrivateData = getAudioCodecPrivateData(audioSpecificConfig); - //Index="0" Bitrate="103000" AudioTag="255" SamplingRate="44100" Channels="2" BitsPerSample="16" packetSize="4" CodecPrivateData="" - return l; - } - - private AudioQuality getEc3AudioQuality(Track track, AudioSampleEntry ase) { - final EC3SpecificBox ec3SpecificBox = ase.getBoxes(EC3SpecificBox.class).get(0); - if (ec3SpecificBox == null) { - throw new RuntimeException("EC-3 track misses EC3SpecificBox!"); - } - - short nfchans = 0; //full bandwidth channels - short lfechans = 0; - byte dWChannelMaskFirstByte = 0; - byte dWChannelMaskSecondByte = 0; - for (EC3SpecificBox.Entry entry : ec3SpecificBox.getEntries()) { - /* - Table 4.3: Audio coding mode - acmod Audio coding mode Nfchans Channel array ordering - 000 1 + 1 2 Ch1, Ch2 - 001 1/0 1 C - 010 2/0 2 L, R - 011 3/0 3 L, C, R - 100 2/1 3 L, R, S - 101 3/1 4 L, C, R, S - 110 2/2 4 L, R, SL, SR - 111 3/2 5 L, C, R, SL, SR - - Table F.2: Chan_loc field bit assignments - Bit Location - 0 Lc/Rc pair - 1 Lrs/Rrs pair - 2 Cs - 3 Ts - 4 Lsd/Rsd pair - 5 Lw/Rw pair - 6 Lvh/Rvh pair - 7 Cvh - 8 LFE2 - */ - switch (entry.acmod) { - case 0: //1+1; Ch1, Ch2 - nfchans += 2; - throw new RuntimeException("Smooth Streaming doesn't support DDP 1+1 mode"); - case 1: //1/0; C - nfchans += 1; - if (entry.num_dep_sub > 0) { - DependentSubstreamMask dependentSubstreamMask = new DependentSubstreamMask(dWChannelMaskFirstByte, dWChannelMaskSecondByte, entry).process(); - dWChannelMaskFirstByte |= dependentSubstreamMask.getdWChannelMaskFirstByte(); - dWChannelMaskSecondByte |= dependentSubstreamMask.getdWChannelMaskSecondByte(); - } else { - dWChannelMaskFirstByte |= 0x20; - } - break; - case 2: //2/0; L, R - nfchans += 2; - if (entry.num_dep_sub > 0) { - DependentSubstreamMask dependentSubstreamMask = new DependentSubstreamMask(dWChannelMaskFirstByte, dWChannelMaskSecondByte, entry).process(); - dWChannelMaskFirstByte |= dependentSubstreamMask.getdWChannelMaskFirstByte(); - dWChannelMaskSecondByte |= dependentSubstreamMask.getdWChannelMaskSecondByte(); - } else { - dWChannelMaskFirstByte |= 0xC0; - } - break; - case 3: //3/0; L, C, R - nfchans += 3; - if (entry.num_dep_sub > 0) { - DependentSubstreamMask dependentSubstreamMask = new DependentSubstreamMask(dWChannelMaskFirstByte, dWChannelMaskSecondByte, entry).process(); - dWChannelMaskFirstByte |= dependentSubstreamMask.getdWChannelMaskFirstByte(); - dWChannelMaskSecondByte |= dependentSubstreamMask.getdWChannelMaskSecondByte(); - } else { - dWChannelMaskFirstByte |= 0xE0; - } - break; - case 4: //2/1; L, R, S - nfchans += 3; - if (entry.num_dep_sub > 0) { - DependentSubstreamMask dependentSubstreamMask = new DependentSubstreamMask(dWChannelMaskFirstByte, dWChannelMaskSecondByte, entry).process(); - dWChannelMaskFirstByte |= dependentSubstreamMask.getdWChannelMaskFirstByte(); - dWChannelMaskSecondByte |= dependentSubstreamMask.getdWChannelMaskSecondByte(); - } else { - dWChannelMaskFirstByte |= 0xC0; - dWChannelMaskSecondByte |= 0x80; - } - break; - case 5: //3/1; L, C, R, S - nfchans += 4; - if (entry.num_dep_sub > 0) { - DependentSubstreamMask dependentSubstreamMask = new DependentSubstreamMask(dWChannelMaskFirstByte, dWChannelMaskSecondByte, entry).process(); - dWChannelMaskFirstByte |= dependentSubstreamMask.getdWChannelMaskFirstByte(); - dWChannelMaskSecondByte |= dependentSubstreamMask.getdWChannelMaskSecondByte(); - } else { - dWChannelMaskFirstByte |= 0xE0; - dWChannelMaskSecondByte |= 0x80; - } - break; - case 6: //2/2; L, R, SL, SR - nfchans += 4; - if (entry.num_dep_sub > 0) { - DependentSubstreamMask dependentSubstreamMask = new DependentSubstreamMask(dWChannelMaskFirstByte, dWChannelMaskSecondByte, entry).process(); - dWChannelMaskFirstByte |= dependentSubstreamMask.getdWChannelMaskFirstByte(); - dWChannelMaskSecondByte |= dependentSubstreamMask.getdWChannelMaskSecondByte(); - } else { - dWChannelMaskFirstByte |= 0xCC; - } - break; - case 7: //3/2; L, C, R, SL, SR - nfchans += 5; - if (entry.num_dep_sub > 0) { - DependentSubstreamMask dependentSubstreamMask = new DependentSubstreamMask(dWChannelMaskFirstByte, dWChannelMaskSecondByte, entry).process(); - dWChannelMaskFirstByte |= dependentSubstreamMask.getdWChannelMaskFirstByte(); - dWChannelMaskSecondByte |= dependentSubstreamMask.getdWChannelMaskSecondByte(); - } else { - dWChannelMaskFirstByte |= 0xEC; - } - break; - } - if (entry.lfeon == 1) { - lfechans ++; - dWChannelMaskFirstByte |= 0x10; - } - } - - final ByteBuffer waveformatex = ByteBuffer.allocate(22); - waveformatex.put(new byte[]{0x00, 0x06}); //1536 wSamplesPerBlock - little endian - waveformatex.put(dWChannelMaskFirstByte); - waveformatex.put(dWChannelMaskSecondByte); - waveformatex.put(new byte[]{0x00, 0x00}); //pad dwChannelMask to 32bit - waveformatex.put(new byte[]{(byte)0xAF, (byte)0x87, (byte)0xFB, (byte)0xA7, 0x02, 0x2D, (byte)0xFB, 0x42, (byte)0xA4, (byte)0xD4, 0x05, (byte)0xCD, (byte)0x93, (byte)0x84, 0x3B, (byte)0xDD}); //SubFormat - Dolby Digital Plus GUID - - final ByteBuffer dec3Content = ByteBuffer.allocate((int) ec3SpecificBox.getContentSize()); - ec3SpecificBox.getContent(dec3Content); - - AudioQuality l = new AudioQuality(); - l.fourCC = "EC-3"; - l.bitrate = getBitrate(track); - l.audioTag = 65534; - l.samplingRate = ase.getSampleRate(); - l.channels = nfchans + lfechans; - l.bitPerSample = 16; - l.packetSize = track.getSamples().get(0).limit(); //assuming all are same size - l.codecPrivateData = Hex.encodeHex(waveformatex.array()) + Hex.encodeHex(dec3Content.array()); //append EC3SpecificBox (big endian) at the end of waveformatex - return l; - } - - private AudioQuality getDtsAudioQuality(Track track, AudioSampleEntry ase) { - final DTSSpecificBox dtsSpecificBox = ase.getBoxes(DTSSpecificBox.class).get(0); - if (dtsSpecificBox == null) { - throw new RuntimeException("DTS track misses DTSSpecificBox!"); - } - - final ByteBuffer waveformatex = ByteBuffer.allocate(22); - final int frameDuration = dtsSpecificBox.getFrameDuration(); - short samplesPerBlock = 0; - switch (frameDuration) { - case 0: - samplesPerBlock = 512; - break; - case 1: - samplesPerBlock = 1024; - break; - case 2: - samplesPerBlock = 2048; - break; - case 3: - samplesPerBlock = 4096; - break; - } - waveformatex.put((byte) (samplesPerBlock & 0xff)); - waveformatex.put((byte) (samplesPerBlock >>> 8)); - final int dwChannelMask = getNumChannelsAndMask(dtsSpecificBox)[1]; - waveformatex.put((byte) (dwChannelMask & 0xff)); - waveformatex.put((byte) (dwChannelMask >>> 8)); - waveformatex.put((byte) (dwChannelMask >>> 16)); - waveformatex.put((byte) (dwChannelMask >>> 24)); - waveformatex.put(new byte[]{(byte)0xAE, (byte)0xE4, (byte)0xBF, (byte)0x5E, (byte)0x61, (byte)0x5E, (byte)0x41, (byte)0x87, (byte)0x92, (byte)0xFC, (byte)0xA4, (byte)0x81, (byte)0x26, (byte)0x99, (byte)0x02, (byte)0x11}); //DTS-HD GUID - - final ByteBuffer dtsCodecPrivateData = ByteBuffer.allocate(8); - dtsCodecPrivateData.put((byte) dtsSpecificBox.getStreamConstruction()); - - final int channelLayout = dtsSpecificBox.getChannelLayout(); - dtsCodecPrivateData.put((byte) (channelLayout & 0xff)); - dtsCodecPrivateData.put((byte) (channelLayout >>> 8)); - dtsCodecPrivateData.put((byte) (channelLayout >>> 16)); - dtsCodecPrivateData.put((byte) (channelLayout >>> 24)); - - byte dtsFlags = (byte) (dtsSpecificBox.getMultiAssetFlag() << 1); - dtsFlags |= dtsSpecificBox.getLBRDurationMod(); - dtsCodecPrivateData.put(dtsFlags); - dtsCodecPrivateData.put(new byte[]{0x00, 0x00}); //reserved - - AudioQuality l = new AudioQuality(); - l.fourCC = getFormat(ase); - l.bitrate = dtsSpecificBox.getAvgBitRate(); - l.audioTag = 65534; - l.samplingRate = dtsSpecificBox.getDTSSamplingFrequency(); - l.channels = getNumChannelsAndMask(dtsSpecificBox)[0]; - l.bitPerSample = 16; - l.packetSize = track.getSamples().get(0).limit(); //assuming all are same size - l.codecPrivateData = Hex.encodeHex(waveformatex.array()) + Hex.encodeHex(dtsCodecPrivateData.array()); - return l; - - } - - /* dwChannelMask - L SPEAKER_FRONT_LEFT 0x00000001 - R SPEAKER_FRONT_RIGHT 0x00000002 - C SPEAKER_FRONT_CENTER 0x00000004 - LFE1 SPEAKER_LOW_FREQUENCY 0x00000008 - Ls or Lsr* SPEAKER_BACK_LEFT 0x00000010 - Rs or Rsr* SPEAKER_BACK_RIGHT 0x00000020 - Lc SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040 - Rc SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080 - Cs SPEAKER_BACK_CENTER 0x00000100 - Lss SPEAKER_SIDE_LEFT 0x00000200 - Rss SPEAKER_SIDE_RIGHT 0x00000400 - Oh SPEAKER_TOP_CENTER 0x00000800 - Lh SPEAKER_TOP_FRONT_LEFT 0x00001000 - Ch SPEAKER_TOP_FRONT_CENTER 0x00002000 - Rh SPEAKER_TOP_FRONT_RIGHT 0x00004000 - Lhr SPEAKER_TOP_BACK_LEFT 0x00008000 - Chf SPEAKER_TOP_BACK_CENTER 0x00010000 - Rhr SPEAKER_TOP_BACK_RIGHT 0x00020000 - SPEAKER_RESERVED 0x80000000 - - * if Lss, Rss exist, then this position is equivalent to Lsr, Rsr respectively - */ - private int[] getNumChannelsAndMask(DTSSpecificBox dtsSpecificBox) { - final int channelLayout = dtsSpecificBox.getChannelLayout(); - int numChannels = 0; - int dwChannelMask = 0; - if ((channelLayout & 0x0001) == 0x0001) { - //0001h Center in front of listener 1 - numChannels += 1; - dwChannelMask |= 0x00000004; //SPEAKER_FRONT_CENTER - } - if ((channelLayout & 0x0002) == 0x0002) { - //0002h Left/Right in front 2 - numChannels += 2; - dwChannelMask |= 0x00000001; //SPEAKER_FRONT_LEFT - dwChannelMask |= 0x00000002; //SPEAKER_FRONT_RIGHT - } - if ((channelLayout & 0x0004) == 0x0004) { - //0004h Left/Right surround on side in rear 2 - numChannels += 2; - //* if Lss, Rss exist, then this position is equivalent to Lsr, Rsr respectively - dwChannelMask |= 0x00000010; //SPEAKER_BACK_LEFT - dwChannelMask |= 0x00000020; //SPEAKER_BACK_RIGHT - } - if ((channelLayout & 0x0008) == 0x0008) { - //0008h Low frequency effects subwoofer 1 - numChannels += 1; - dwChannelMask |= 0x00000008; //SPEAKER_LOW_FREQUENCY - } - if ((channelLayout & 0x0010) == 0x0010) { - //0010h Center surround in rear 1 - numChannels += 1; - dwChannelMask |= 0x00000100; //SPEAKER_BACK_CENTER - } - if ((channelLayout & 0x0020) == 0x0020) { - //0020h Left/Right height in front 2 - numChannels += 2; - dwChannelMask |= 0x00001000; //SPEAKER_TOP_FRONT_LEFT - dwChannelMask |= 0x00004000; //SPEAKER_TOP_FRONT_RIGHT - } - if ((channelLayout & 0x0040) == 0x0040) { - //0040h Left/Right surround in rear 2 - numChannels += 2; - dwChannelMask |= 0x00000010; //SPEAKER_BACK_LEFT - dwChannelMask |= 0x00000020; //SPEAKER_BACK_RIGHT - } - if ((channelLayout & 0x0080) == 0x0080) { - //0080h Center Height in front 1 - numChannels += 1; - dwChannelMask |= 0x00002000; //SPEAKER_TOP_FRONT_CENTER - } - if ((channelLayout & 0x0100) == 0x0100) { - //0100h Over the listener’s head 1 - numChannels += 1; - dwChannelMask |= 0x00000800; //SPEAKER_TOP_CENTER - } - if ((channelLayout & 0x0200) == 0x0200) { - //0200h Between left/right and center in front 2 - numChannels += 2; - dwChannelMask |= 0x00000040; //SPEAKER_FRONT_LEFT_OF_CENTER - dwChannelMask |= 0x00000080; //SPEAKER_FRONT_RIGHT_OF_CENTER - } - if ((channelLayout & 0x0400) == 0x0400) { - //0400h Left/Right on side in front 2 - numChannels += 2; - dwChannelMask |= 0x00000200; //SPEAKER_SIDE_LEFT - dwChannelMask |= 0x00000400; //SPEAKER_SIDE_RIGHT - } - if ((channelLayout & 0x0800) == 0x0800) { - //0800h Left/Right surround on side 2 - numChannels += 2; - //* if Lss, Rss exist, then this position is equivalent to Lsr, Rsr respectively - dwChannelMask |= 0x00000010; //SPEAKER_BACK_LEFT - dwChannelMask |= 0x00000020; //SPEAKER_BACK_RIGHT - } - if ((channelLayout & 0x1000) == 0x1000) { - //1000h Second low frequency effects subwoofer 1 - numChannels += 1; - dwChannelMask |= 0x00000008; //SPEAKER_LOW_FREQUENCY - } - if ((channelLayout & 0x2000) == 0x2000) { - //2000h Left/Right height on side 2 - numChannels += 2; - dwChannelMask |= 0x00000010; //SPEAKER_BACK_LEFT - dwChannelMask |= 0x00000020; //SPEAKER_BACK_RIGHT - } - if ((channelLayout & 0x4000) == 0x4000) { - //4000h Center height in rear 1 - numChannels += 1; - dwChannelMask |= 0x00010000; //SPEAKER_TOP_BACK_CENTER - } - if ((channelLayout & 0x8000) == 0x8000) { - //8000h Left/Right height in rear 2 - numChannels += 2; - dwChannelMask |= 0x00008000; //SPEAKER_TOP_BACK_LEFT - dwChannelMask |= 0x00020000; //SPEAKER_TOP_BACK_RIGHT - } - if ((channelLayout & 0x10000) == 0x10000) { - //10000h Center below in front - numChannels += 1; - } - if ((channelLayout & 0x20000) == 0x20000) { - //20000h Left/Right below in front - numChannels += 2; - } - return new int[]{numChannels, dwChannelMask}; - } - - private String getAudioCodecPrivateData(AudioSpecificConfig audioSpecificConfig) { - byte[] configByteArray = audioSpecificConfig.getConfigBytes(); - return Hex.encodeHex(configByteArray); - } - - private VideoQuality getVideoQuality(Track track, VisualSampleEntry vse) { - VideoQuality l; - if ("avc1".equals(getFormat(vse))) { - AvcConfigurationBox avcConfigurationBox = vse.getBoxes(AvcConfigurationBox.class).get(0); - l = new VideoQuality(); - l.bitrate = getBitrate(track); - l.codecPrivateData = Hex.encodeHex(getAvcCodecPrivateData(avcConfigurationBox)); - l.fourCC = "AVC1"; - l.width = vse.getWidth(); - l.height = vse.getHeight(); - l.nalLength = avcConfigurationBox.getLengthSizeMinusOne() + 1; - } else { - throw new InternalError("I don't know how to handle video of type " + getFormat(vse)); - } - return l; - } - - private byte[] getAvcCodecPrivateData(AvcConfigurationBox avcConfigurationBox) { - List<byte[]> sps = avcConfigurationBox.getSequenceParameterSets(); - List<byte[]> pps = avcConfigurationBox.getPictureParameterSets(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - baos.write(new byte[]{0, 0, 0, 1}); - - for (byte[] sp : sps) { - baos.write(sp); - } - baos.write(new byte[]{0, 0, 0, 1}); - for (byte[] pp : pps) { - baos.write(pp); - } - } catch (IOException ex) { - throw new RuntimeException("ByteArrayOutputStream do not throw IOException ?!?!?"); - } - return baos.toByteArray(); - } - - private class DependentSubstreamMask { - private byte dWChannelMaskFirstByte; - private byte dWChannelMaskSecondByte; - private EC3SpecificBox.Entry entry; - - public DependentSubstreamMask(byte dWChannelMaskFirstByte, byte dWChannelMaskSecondByte, EC3SpecificBox.Entry entry) { - this.dWChannelMaskFirstByte = dWChannelMaskFirstByte; - this.dWChannelMaskSecondByte = dWChannelMaskSecondByte; - this.entry = entry; - } - - public byte getdWChannelMaskFirstByte() { - return dWChannelMaskFirstByte; - } - - public byte getdWChannelMaskSecondByte() { - return dWChannelMaskSecondByte; - } - - public DependentSubstreamMask process() { - switch (entry.chan_loc) { - case 0: - dWChannelMaskFirstByte |= 0x3; - break; - case 1: - dWChannelMaskFirstByte |= 0xC; - break; - case 2: - dWChannelMaskSecondByte |= 0x80; - break; - case 3: - dWChannelMaskSecondByte |= 0x8; - break; - case 6: - dWChannelMaskSecondByte |= 0x5; - break; - case 7: - dWChannelMaskSecondByte |= 0x2; - break; - } - return this; - } - } -} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/FlatPackageWriterImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/FlatPackageWriterImpl.java.svn-base deleted file mode 100644 index 3e3847c..0000000 --- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/FlatPackageWriterImpl.java.svn-base +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2012 Sebastian Annies, Hamburg - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.googlecode.mp4parser.authoring.adaptivestreaming; - -import com.coremedia.iso.IsoFile; -import com.coremedia.iso.boxes.Box; -import com.coremedia.iso.boxes.SoundMediaHeaderBox; -import com.coremedia.iso.boxes.VideoMediaHeaderBox; -import com.coremedia.iso.boxes.fragment.MovieFragmentBox; -import com.googlecode.mp4parser.authoring.Movie; -import com.googlecode.mp4parser.authoring.Track; -import com.googlecode.mp4parser.authoring.builder.*; -import com.googlecode.mp4parser.authoring.tracks.ChangeTimeScaleTrack; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.channels.FileChannel; -import java.util.Iterator; -import java.util.logging.Logger; - -public class FlatPackageWriterImpl implements PackageWriter { - private static Logger LOG = Logger.getLogger(FlatPackageWriterImpl.class.getName()); - long timeScale = 10000000; - - private File outputDirectory; - private boolean debugOutput; - private FragmentedMp4Builder ismvBuilder; - ManifestWriter manifestWriter; - - public FlatPackageWriterImpl() { - ismvBuilder = new FragmentedMp4Builder(); - FragmentIntersectionFinder intersectionFinder = new SyncSampleIntersectFinderImpl(); - ismvBuilder.setIntersectionFinder(intersectionFinder); - manifestWriter = new FlatManifestWriterImpl(intersectionFinder); - } - - /** - * Creates a factory for a smooth streaming package. A smooth streaming package is - * a collection of files that can be served by a webserver as a smooth streaming - * stream. - * @param minFragmentDuration the smallest allowable duration of a fragment (0 == no restriction). - */ - public FlatPackageWriterImpl(int minFragmentDuration) { - ismvBuilder = new FragmentedMp4Builder(); - FragmentIntersectionFinder intersectionFinder = new SyncSampleIntersectFinderImpl(minFragmentDuration); - ismvBuilder.setIntersectionFinder(intersectionFinder); - manifestWriter = new FlatManifestWriterImpl(intersectionFinder); - } - - public void setOutputDirectory(File outputDirectory) { - assert outputDirectory.isDirectory(); - this.outputDirectory = outputDirectory; - - } - - public void setDebugOutput(boolean debugOutput) { - this.debugOutput = debugOutput; - } - - public void setIsmvBuilder(FragmentedMp4Builder ismvBuilder) { - this.ismvBuilder = ismvBuilder; - this.manifestWriter = new FlatManifestWriterImpl(ismvBuilder.getFragmentIntersectionFinder()); - } - - public void setManifestWriter(ManifestWriter manifestWriter) { - this.manifestWriter = manifestWriter; - } - - /** - * Writes the movie given as <code>qualities</code> flattened into the - * <code>outputDirectory</code>. - * - * @param source the source movie with all qualities - * @throws IOException - */ - public void write(Movie source) throws IOException { - - if (debugOutput) { - outputDirectory.mkdirs(); - DefaultMp4Builder defaultMp4Builder = new DefaultMp4Builder(); - IsoFile muxed = defaultMp4Builder.build(source); - File muxedFile = new File(outputDirectory, "debug_1_muxed.mp4"); - FileOutputStream muxedFileOutputStream = new FileOutputStream(muxedFile); - muxed.getBox(muxedFileOutputStream.getChannel()); - muxedFileOutputStream.close(); - } - Movie cleanedSource = removeUnknownTracks(source); - Movie movieWithAdjustedTimescale = correctTimescale(cleanedSource); - - if (debugOutput) { - DefaultMp4Builder defaultMp4Builder = new DefaultMp4Builder(); - IsoFile muxed = defaultMp4Builder.build(movieWithAdjustedTimescale); - File muxedFile = new File(outputDirectory, "debug_2_timescale.mp4"); - FileOutputStream muxedFileOutputStream = new FileOutputStream(muxedFile); - muxed.getBox(muxedFileOutputStream.getChannel()); - muxedFileOutputStream.close(); - } - IsoFile isoFile = ismvBuilder.build(movieWithAdjustedTimescale); - if (debugOutput) { - File allQualities = new File(outputDirectory, "debug_3_fragmented.mp4"); - FileOutputStream allQualis = new FileOutputStream(allQualities); - isoFile.getBox(allQualis.getChannel()); - allQualis.close(); - } - - - for (Track track : movieWithAdjustedTimescale.getTracks()) { - String bitrate = Long.toString(manifestWriter.getBitrate(track)); - long trackId = track.getTrackMetaData().getTrackId(); - Iterator<Box> boxIt = isoFile.getBoxes().iterator(); - File mediaOutDir; - if (track.getMediaHeaderBox() instanceof SoundMediaHeaderBox) { - mediaOutDir = new File(outputDirectory, "audio"); - - } else if (track.getMediaHeaderBox() instanceof VideoMediaHeaderBox) { - mediaOutDir = new File(outputDirectory, "video"); - } else { - System.err.println("Skipping Track with handler " + track.getHandler() + " and " + track.getMediaHeaderBox().getClass().getSimpleName()); - continue; - } - File bitRateOutputDir = new File(mediaOutDir, bitrate); - bitRateOutputDir.mkdirs(); - LOG.finer("Created : " + bitRateOutputDir.getCanonicalPath()); - - long[] fragmentTimes = manifestWriter.calculateFragmentDurations(track, movieWithAdjustedTimescale); - long startTime = 0; - int currentFragment = 0; - while (boxIt.hasNext()) { - Box b = boxIt.next(); - if (b instanceof MovieFragmentBox) { - assert ((MovieFragmentBox) b).getTrackCount() == 1; - if (((MovieFragmentBox) b).getTrackNumbers()[0] == trackId) { - FileOutputStream fos = new FileOutputStream(new File(bitRateOutputDir, Long.toString(startTime))); - startTime += fragmentTimes[currentFragment++]; - FileChannel fc = fos.getChannel(); - Box mdat = boxIt.next(); - assert mdat.getType().equals("mdat"); - b.getBox(fc); // moof - mdat.getBox(fc); // mdat - fc.truncate(fc.position()); - fc.close(); - } - } - - } - } - FileWriter fw = new FileWriter(new File(outputDirectory, "Manifest")); - fw.write(manifestWriter.getManifest(movieWithAdjustedTimescale)); - fw.close(); - - } - - private Movie removeUnknownTracks(Movie source) { - Movie nuMovie = new Movie(); - for (Track track : source.getTracks()) { - if ("vide".equals(track.getHandler()) || "soun".equals(track.getHandler())) { - nuMovie.addTrack(track); - } else { - LOG.fine("Removed track " + track); - } - } - return nuMovie; - } - - - /** - * Returns a new <code>Movie</code> in that all tracks have the timescale 10000000. CTS & DTS are modified - * in a way that even with more than one framerate the fragments exactly begin at the same time. - * - * @param movie - * @return a movie with timescales suitable for smooth streaming manifests - */ - public Movie correctTimescale(Movie movie) { - Movie nuMovie = new Movie(); - for (Track track : movie.getTracks()) { - nuMovie.addTrack(new ChangeTimeScaleTrack(track, timeScale, ismvBuilder.getFragmentIntersectionFinder().sampleNumbers(track, movie))); - } - return nuMovie; - - } - -} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/ManifestWriter.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/ManifestWriter.java.svn-base deleted file mode 100644 index 2b2ba7d..0000000 --- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/ManifestWriter.java.svn-base +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012 Sebastian Annies, Hamburg - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.googlecode.mp4parser.authoring.adaptivestreaming; - - -import com.googlecode.mp4parser.authoring.Movie; -import com.googlecode.mp4parser.authoring.Track; - -import java.io.IOException; - -public interface ManifestWriter { - String getManifest(Movie inputs) throws IOException; - - long getBitrate(Track track); - - long[] calculateFragmentDurations(Track track, Movie movie); - -} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/PackageWriter.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/PackageWriter.java.svn-base deleted file mode 100644 index 0d97fc5..0000000 --- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/PackageWriter.java.svn-base +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2012 Sebastian Annies, Hamburg - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.googlecode.mp4parser.authoring.adaptivestreaming; - -import com.googlecode.mp4parser.authoring.Movie; - -import java.io.IOException; - -/** - * Writes the whole package. - */ -public interface PackageWriter { - public void write(Movie qualities) throws IOException; -} diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/VideoQuality.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/VideoQuality.java.svn-base deleted file mode 100644 index 4a70e47..0000000 --- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/VideoQuality.java.svn-base +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2012 Sebastian Annies, Hamburg - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.googlecode.mp4parser.authoring.adaptivestreaming; - -class VideoQuality { - long bitrate; - String fourCC; - int width; - int height; - String codecPrivateData; - int nalLength; -} |