summaryrefslogtreecommitdiff
path: root/isoparser/src/main/java/com/googlecode/mp4parser/authoring
diff options
context:
space:
mode:
Diffstat (limited to 'isoparser/src/main/java/com/googlecode/mp4parser/authoring')
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/all-wcprops41
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/entries244
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/AbstractTrack.java.svn-base60
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/DateHelper.java.svn-base44
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Movie.java.svn-base91
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Mp4TrackImpl.java.svn-base219
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Track.java.svn-base60
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/TrackMetaData.java.svn-base130
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/all-wcprops47
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/entries266
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/AbstractManifestWriter.java.svn-base126
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/AudioQuality.java.svn-base29
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/FlatManifestWriterImpl.java.svn-base643
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/FlatPackageWriterImpl.java.svn-base197
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/ManifestWriter.java.svn-base31
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/PackageWriter.java.svn-base27
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/text-base/VideoQuality.java.svn-base25
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/all-wcprops47
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/entries266
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/ByteBufferHelper.java.svn-base50
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/DefaultMp4Builder.java.svn-base576
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/FragmentIntersectionFinder.java.svn-base34
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/FragmentedMp4Builder.java.svn-base742
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/Mp4Builder.java.svn-base35
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/SyncSampleIntersectFinderImpl.java.svn-base334
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/TwoSecondIntersectionFinder.java.svn-base86
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/.svn/all-wcprops5
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/.svn/entries31
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/all-wcprops11
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/entries62
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/text-base/MovieCreator.java.svn-base40
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/all-wcprops89
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/entries504
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AACTrackImpl.java.svn-base292
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AC3TrackImpl.java.svn-base513
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/Amf0Track.java.svn-base116
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AppendTrack.java.svn-base348
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/ChangeTimeScaleTrack.java.svn-base203
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/CroppedTrack.java.svn-base151
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/DivideTimeScaleTrack.java.svn-base126
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/EC3TrackImpl.java.svn-base436
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/H264TrackImpl.java.svn-base740
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/MultiplyTimeScaleTrack.java.svn-base130
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/QuicktimeTextTrackImpl.java.svn-base165
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/ReplaceSampleTrack.java.svn-base104
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/SilenceTrackImpl.java.svn-base98
-rw-r--r--isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/TextTrackImpl.java.svn-base165
47 files changed, 0 insertions, 8779 deletions
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/all-wcprops
deleted file mode 100644
index 89054c9..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/all-wcprops
+++ /dev/null
@@ -1,41 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 82
-/svn/!svn/ver/776/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring
-END
-Movie.java
-K 25
-svn:wc:ra_dav:version-url
-V 93
-/svn/!svn/ver/514/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/Movie.java
-END
-Track.java
-K 25
-svn:wc:ra_dav:version-url
-V 93
-/svn/!svn/ver/686/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/Track.java
-END
-TrackMetaData.java
-K 25
-svn:wc:ra_dav:version-url
-V 101
-/svn/!svn/ver/745/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/TrackMetaData.java
-END
-Mp4TrackImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 100
-/svn/!svn/ver/765/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/Mp4TrackImpl.java
-END
-AbstractTrack.java
-K 25
-svn:wc:ra_dav:version-url
-V 101
-/svn/!svn/ver/418/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/AbstractTrack.java
-END
-DateHelper.java
-K 25
-svn:wc:ra_dav:version-url
-V 98
-/svn/!svn/ver/418/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/DateHelper.java
-END
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/entries
deleted file mode 100644
index 7d2b29e..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/entries
+++ /dev/null
@@ -1,244 +0,0 @@
-10
-
-dir
-778
-http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring
-http://mp4parser.googlecode.com/svn
-
-
-
-2012-09-10T14:34:23.574807Z
-776
-sebastian.annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7decde4b-c250-0410-a0da-51896bc88be6
-
-Movie.java
-file
-
-
-
-
-2012-09-14T17:27:50.517219Z
-e3a56133cfdfacb92ed0a54177e847b4
-2012-04-22T10:09:06.632613Z
-514
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2558
-
-container
-dir
-
-Track.java
-file
-
-
-
-
-2012-09-14T17:27:50.517219Z
-9537fa79b71fe26727e56e84e94bbdb8
-2012-06-24T19:52:05.961412Z
-686
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1607
-
-TrackMetaData.java
-file
-
-
-
-
-2012-09-14T17:27:50.527219Z
-cbb770cca0ee421026eec0a2f40d2376
-2012-08-14T19:18:50.777750Z
-745
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2948
-
-builder
-dir
-
-adaptivestreaming
-dir
-
-tracks
-dir
-
-Mp4TrackImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.527219Z
-c57930172e9d0da9e881d8dc8ecf2924
-2012-08-29T08:26:56.932482Z
-765
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-10958
-
-AbstractTrack.java
-file
-
-
-
-
-2012-09-14T17:27:50.527219Z
-973f4f354fb6f575dd1a0c8a68d54653
-2012-03-11T20:54:45.638478Z
-418
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1481
-
-DateHelper.java
-file
-
-
-
-
-2012-09-14T17:27:50.527219Z
-765e3f37d7bb369f569aa91e326a90b8
-2012-03-11T20:54:45.638478Z
-418
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1349
-
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/AbstractTrack.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/AbstractTrack.java.svn-base
deleted file mode 100644
index fb0e224..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/AbstractTrack.java.svn-base
+++ /dev/null
@@ -1,60 +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;
-
-/**
- *
- */
-public abstract class AbstractTrack implements Track {
- private boolean enabled = true;
- private boolean inMovie = true;
- private boolean inPreview = true;
- private boolean inPoster = true;
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public boolean isInMovie() {
- return inMovie;
- }
-
- public boolean isInPreview() {
- return inPreview;
- }
-
- public boolean isInPoster() {
- return inPoster;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- public void setInMovie(boolean inMovie) {
- this.inMovie = inMovie;
- }
-
- public void setInPreview(boolean inPreview) {
- this.inPreview = inPreview;
- }
-
- public void setInPoster(boolean inPoster) {
- this.inPoster = inPoster;
- }
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/DateHelper.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/DateHelper.java.svn-base
deleted file mode 100644
index 0252859..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/DateHelper.java.svn-base
+++ /dev/null
@@ -1,44 +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;
-
-import java.util.Date;
-
-/**
- * Converts ISO Dates (seconds since 1/1/1904) to Date and vice versa.
- */
-public class DateHelper {
- /**
- * Converts a long value with seconds since 1/1/1904 to Date.
- *
- * @param secondsSince seconds since 1/1/1904
- * @return date the corresponding <code>Date</code>
- */
- static public Date convert(long secondsSince) {
- return new Date((secondsSince - 2082844800L) * 1000L);
- }
-
-
- /**
- * Converts a date as long to a mac date as long
- *
- * @param date date to convert
- * @return date in mac format
- */
- static public long convert(Date date) {
- return (date.getTime() / 1000L) + 2082844800L;
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Movie.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Movie.java.svn-base
deleted file mode 100644
index 0658682..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Movie.java.svn-base
+++ /dev/null
@@ -1,91 +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;
-
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- *
- */
-public class Movie {
- List<Track> tracks = new LinkedList<Track>();
-
- public List<Track> getTracks() {
- return tracks;
- }
-
- public void setTracks(List<Track> tracks) {
- this.tracks = tracks;
- }
-
- public void addTrack(Track nuTrack) {
- // do some checking
- // perhaps the movie needs to get longer!
- if (getTrackByTrackId(nuTrack.getTrackMetaData().getTrackId()) != null) {
- // We already have a track with that trackId. Create a new one
- nuTrack.getTrackMetaData().setTrackId(getNextTrackId());
- }
- tracks.add(nuTrack);
- }
-
-
- @Override
- public String toString() {
- String s = "Movie{ ";
- for (Track track : tracks) {
- s += "track_" + track.getTrackMetaData().getTrackId() + " (" + track.getHandler() + ") ";
- }
-
- s += '}';
- return s;
- }
-
- public long getNextTrackId() {
- long nextTrackId = 0;
- for (Track track : tracks) {
- nextTrackId = nextTrackId < track.getTrackMetaData().getTrackId() ? track.getTrackMetaData().getTrackId() : nextTrackId;
- }
- return ++nextTrackId;
- }
-
-
- public Track getTrackByTrackId(long trackId) {
- for (Track track : tracks) {
- if (track.getTrackMetaData().getTrackId() == trackId) {
- return track;
- }
- }
- return null;
- }
-
-
- public long getTimescale() {
- long timescale = this.getTracks().iterator().next().getTrackMetaData().getTimescale();
- for (Track track : this.getTracks()) {
- timescale = gcd(track.getTrackMetaData().getTimescale(), timescale);
- }
- return timescale;
- }
-
- public static long gcd(long a, long b) {
- if (b == 0) {
- return a;
- }
- return gcd(b, a % b);
- }
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Mp4TrackImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Mp4TrackImpl.java.svn-base
deleted file mode 100644
index 3bff1a5..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Mp4TrackImpl.java.svn-base
+++ /dev/null
@@ -1,219 +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;
-
-import com.coremedia.iso.boxes.*;
-import com.coremedia.iso.boxes.fragment.*;
-import com.coremedia.iso.boxes.mdat.SampleList;
-
-import java.nio.ByteBuffer;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import static com.googlecode.mp4parser.util.CastUtils.l2i;
-
-/**
- * Represents a single track of an MP4 file.
- */
-public class Mp4TrackImpl extends AbstractTrack {
- private List<ByteBuffer> samples;
- private SampleDescriptionBox sampleDescriptionBox;
- private List<TimeToSampleBox.Entry> decodingTimeEntries;
- private List<CompositionTimeToSample.Entry> compositionTimeEntries;
- private long[] syncSamples = new long[0];
- private List<SampleDependencyTypeBox.Entry> sampleDependencies;
- private TrackMetaData trackMetaData = new TrackMetaData();
- private String handler;
- private AbstractMediaHeaderBox mihd;
-
- public Mp4TrackImpl(TrackBox trackBox) {
- final long trackId = trackBox.getTrackHeaderBox().getTrackId();
- samples = new SampleList(trackBox);
- SampleTableBox stbl = trackBox.getMediaBox().getMediaInformationBox().getSampleTableBox();
- handler = trackBox.getMediaBox().getHandlerBox().getHandlerType();
-
- mihd = trackBox.getMediaBox().getMediaInformationBox().getMediaHeaderBox();
- decodingTimeEntries = new LinkedList<TimeToSampleBox.Entry>();
- compositionTimeEntries = new LinkedList<CompositionTimeToSample.Entry>();
- sampleDependencies = new LinkedList<SampleDependencyTypeBox.Entry>();
-
- decodingTimeEntries.addAll(stbl.getTimeToSampleBox().getEntries());
- if (stbl.getCompositionTimeToSample() != null) {
- compositionTimeEntries.addAll(stbl.getCompositionTimeToSample().getEntries());
- }
- if (stbl.getSampleDependencyTypeBox() != null) {
- sampleDependencies.addAll(stbl.getSampleDependencyTypeBox().getEntries());
- }
- if (stbl.getSyncSampleBox() != null) {
- syncSamples = stbl.getSyncSampleBox().getSampleNumber();
- }
-
-
- sampleDescriptionBox = stbl.getSampleDescriptionBox();
- final List<MovieExtendsBox> movieExtendsBoxes = trackBox.getParent().getBoxes(MovieExtendsBox.class);
- if (movieExtendsBoxes.size() > 0) {
- for (MovieExtendsBox mvex : movieExtendsBoxes) {
- final List<TrackExtendsBox> trackExtendsBoxes = mvex.getBoxes(TrackExtendsBox.class);
- for (TrackExtendsBox trex : trackExtendsBoxes) {
- if (trex.getTrackId() == trackId) {
- List<Long> syncSampleList = new LinkedList<Long>();
-
- long sampleNumber = 1;
- for (MovieFragmentBox movieFragmentBox : trackBox.getIsoFile().getBoxes(MovieFragmentBox.class)) {
- List<TrackFragmentBox> trafs = movieFragmentBox.getBoxes(TrackFragmentBox.class);
- for (TrackFragmentBox traf : trafs) {
- if (traf.getTrackFragmentHeaderBox().getTrackId() == trackId) {
- List<TrackRunBox> truns = traf.getBoxes(TrackRunBox.class);
- for (TrackRunBox trun : truns) {
- final TrackFragmentHeaderBox tfhd = ((TrackFragmentBox) trun.getParent()).getTrackFragmentHeaderBox();
- boolean first = true;
- for (TrackRunBox.Entry entry : trun.getEntries()) {
- if (trun.isSampleDurationPresent()) {
- if (decodingTimeEntries.size() == 0 ||
- decodingTimeEntries.get(decodingTimeEntries.size() - 1).getDelta() != entry.getSampleDuration()) {
- decodingTimeEntries.add(new TimeToSampleBox.Entry(1, entry.getSampleDuration()));
- } else {
- TimeToSampleBox.Entry e = decodingTimeEntries.get(decodingTimeEntries.size() - 1);
- e.setCount(e.getCount() + 1);
- }
- } else {
- if (tfhd.hasDefaultSampleDuration()) {
- decodingTimeEntries.add(new TimeToSampleBox.Entry(1, tfhd.getDefaultSampleDuration()));
- } else {
- decodingTimeEntries.add(new TimeToSampleBox.Entry(1, trex.getDefaultSampleDuration()));
- }
- }
-
- if (trun.isSampleCompositionTimeOffsetPresent()) {
- if (compositionTimeEntries.size() == 0 ||
- compositionTimeEntries.get(compositionTimeEntries.size() - 1).getOffset() != entry.getSampleCompositionTimeOffset()) {
- compositionTimeEntries.add(new CompositionTimeToSample.Entry(1, l2i(entry.getSampleCompositionTimeOffset())));
- } else {
- CompositionTimeToSample.Entry e = compositionTimeEntries.get(compositionTimeEntries.size() - 1);
- e.setCount(e.getCount() + 1);
- }
- }
- final SampleFlags sampleFlags;
- if (trun.isSampleFlagsPresent()) {
- sampleFlags = entry.getSampleFlags();
- } else {
- if (first && trun.isFirstSampleFlagsPresent()) {
- sampleFlags = trun.getFirstSampleFlags();
- } else {
- if (tfhd.hasDefaultSampleFlags()) {
- sampleFlags = tfhd.getDefaultSampleFlags();
- } else {
- sampleFlags = trex.getDefaultSampleFlags();
- }
- }
- }
- if (sampleFlags != null && !sampleFlags.isSampleIsDifferenceSample()) {
- //iframe
- syncSampleList.add(sampleNumber);
- }
- sampleNumber++;
- first = false;
- }
- }
- }
- }
- }
- // Warning: Crappy code
- long[] oldSS = syncSamples;
- syncSamples = new long[syncSamples.length + syncSampleList.size()];
- System.arraycopy(oldSS, 0, syncSamples, 0, oldSS.length);
- final Iterator<Long> iterator = syncSampleList.iterator();
- int i = oldSS.length;
- while (iterator.hasNext()) {
- Long syncSampleNumber = iterator.next();
- syncSamples[i++] = syncSampleNumber;
- }
- }
- }
- }
- }
- MediaHeaderBox mdhd = trackBox.getMediaBox().getMediaHeaderBox();
- TrackHeaderBox tkhd = trackBox.getTrackHeaderBox();
-
- setEnabled(tkhd.isEnabled());
- setInMovie(tkhd.isInMovie());
- setInPoster(tkhd.isInPoster());
- setInPreview(tkhd.isInPreview());
-
- trackMetaData.setTrackId(tkhd.getTrackId());
- trackMetaData.setCreationTime(DateHelper.convert(mdhd.getCreationTime()));
- trackMetaData.setLanguage(mdhd.getLanguage());
-/* System.err.println(mdhd.getModificationTime());
- System.err.println(DateHelper.convert(mdhd.getModificationTime()));
- System.err.println(DateHelper.convert(DateHelper.convert(mdhd.getModificationTime())));
- System.err.println(DateHelper.convert(DateHelper.convert(DateHelper.convert(mdhd.getModificationTime()))));*/
-
- trackMetaData.setModificationTime(DateHelper.convert(mdhd.getModificationTime()));
- trackMetaData.setTimescale(mdhd.getTimescale());
- trackMetaData.setHeight(tkhd.getHeight());
- trackMetaData.setWidth(tkhd.getWidth());
- trackMetaData.setLayer(tkhd.getLayer());
- }
-
- public List<ByteBuffer> getSamples() {
- return samples;
- }
-
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return sampleDescriptionBox;
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- return decodingTimeEntries;
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- return compositionTimeEntries;
- }
-
- public long[] getSyncSamples() {
- return syncSamples;
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- return sampleDependencies;
- }
-
- public TrackMetaData getTrackMetaData() {
- return trackMetaData;
- }
-
- public String getHandler() {
- return handler;
- }
-
- public AbstractMediaHeaderBox getMediaHeaderBox() {
- return mihd;
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return null;
- }
-
- @Override
- public String toString() {
- return "Mp4TrackImpl{" +
- "handler='" + handler + '\'' +
- '}';
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Track.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Track.java.svn-base
deleted file mode 100644
index 1f4b363..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Track.java.svn-base
+++ /dev/null
@@ -1,60 +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;
-
-import com.coremedia.iso.boxes.*;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-/**
- * Represents a Track. A track is a timed sequence of related samples.
- * <p/>
- * <b>NOTE: </b><br/
- * For media data, a track corresponds to a sequence of images or sampled audio; for hint tracks, a track
- * corresponds to a streaming channel.
- */
-public interface Track {
-
- SampleDescriptionBox getSampleDescriptionBox();
-
- List<TimeToSampleBox.Entry> getDecodingTimeEntries();
-
- List<CompositionTimeToSample.Entry> getCompositionTimeEntries();
-
- long[] getSyncSamples();
-
- List<SampleDependencyTypeBox.Entry> getSampleDependencies();
-
- TrackMetaData getTrackMetaData();
-
- String getHandler();
-
- boolean isEnabled();
-
- boolean isInMovie();
-
- boolean isInPreview();
-
- boolean isInPoster();
-
- List<ByteBuffer> getSamples();
-
- public Box getMediaHeaderBox();
-
- public SubSampleInformationBox getSubsampleInformationBox();
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/TrackMetaData.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/TrackMetaData.java.svn-base
deleted file mode 100644
index c262309..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/TrackMetaData.java.svn-base
+++ /dev/null
@@ -1,130 +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;
-
-import java.util.Date;
-
-/**
- *
- */
-public class TrackMetaData implements Cloneable {
- private String language;
- private long timescale;
- private Date modificationTime = new Date();
- private Date creationTime = new Date();
- private double width;
- private double height;
- private float volume;
- private long trackId = 1; // zero is not allowed
- private int group = 0;
-
-
- /**
- * specifies the front-to-back ordering of video tracks; tracks with lower
- * numbers are closer to the viewer. 0 is the normal value, and -1 would be
- * in front of track 0, and so on.
- */
- int layer;
-
- public String getLanguage() {
- return language;
- }
-
- public void setLanguage(String language) {
- this.language = language;
- }
-
- public long getTimescale() {
- return timescale;
- }
-
- public void setTimescale(long timescale) {
- this.timescale = timescale;
- }
-
- public Date getModificationTime() {
- return modificationTime;
- }
-
- public void setModificationTime(Date modificationTime) {
- this.modificationTime = modificationTime;
- }
-
- public Date getCreationTime() {
- return creationTime;
- }
-
- public void setCreationTime(Date creationTime) {
- this.creationTime = creationTime;
- }
-
- public double getWidth() {
- return width;
- }
-
- public void setWidth(double width) {
- this.width = width;
- }
-
- public double getHeight() {
- return height;
- }
-
- public void setHeight(double height) {
- this.height = height;
- }
-
- public long getTrackId() {
- return trackId;
- }
-
- public void setTrackId(long trackId) {
- this.trackId = trackId;
- }
-
- public int getLayer() {
- return layer;
- }
-
- public void setLayer(int layer) {
- this.layer = layer;
- }
-
- public float getVolume() {
- return volume;
- }
-
- public void setVolume(float volume) {
- this.volume = volume;
- }
-
- public int getGroup() {
- return group;
- }
-
- public void setGroup(int group) {
- this.group = group;
- }
-
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- return null;
- }
- }
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/all-wcprops
deleted file mode 100644
index 7d70c40..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/all-wcprops
+++ /dev/null
@@ -1,47 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 100
-/svn/!svn/ver/773/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming
-END
-VideoQuality.java
-K 25
-svn:wc:ra_dav:version-url
-V 118
-/svn/!svn/ver/760/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/VideoQuality.java
-END
-FlatPackageWriterImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 127
-/svn/!svn/ver/760/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/FlatPackageWriterImpl.java
-END
-ManifestWriter.java
-K 25
-svn:wc:ra_dav:version-url
-V 120
-/svn/!svn/ver/755/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/ManifestWriter.java
-END
-AbstractManifestWriter.java
-K 25
-svn:wc:ra_dav:version-url
-V 128
-/svn/!svn/ver/757/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/AbstractManifestWriter.java
-END
-PackageWriter.java
-K 25
-svn:wc:ra_dav:version-url
-V 119
-/svn/!svn/ver/755/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/PackageWriter.java
-END
-AudioQuality.java
-K 25
-svn:wc:ra_dav:version-url
-V 118
-/svn/!svn/ver/760/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/AudioQuality.java
-END
-FlatManifestWriterImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 128
-/svn/!svn/ver/773/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/FlatManifestWriterImpl.java
-END
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/entries
deleted file mode 100644
index 619b17c..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming/.svn/entries
+++ /dev/null
@@ -1,266 +0,0 @@
-10
-
-dir
-778
-http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/adaptivestreaming
-http://mp4parser.googlecode.com/svn
-
-
-
-2012-09-01T21:55:19.768646Z
-773
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7decde4b-c250-0410-a0da-51896bc88be6
-
-VideoQuality.java
-file
-
-
-
-
-2012-09-14T17:27:50.317216Z
-356fcadf80f684d83b5f30afd5cb26e4
-2012-08-17T15:20:10.783404Z
-760
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-807
-
-FlatPackageWriterImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.317216Z
-f38a8b91e1b8abd48e1ae26b23b060fa
-2012-08-17T15:20:10.783404Z
-760
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-8285
-
-ManifestWriter.java
-file
-
-
-
-
-2012-09-14T17:27:50.317216Z
-4fc006c7919c1ab4ed498340dfa133b3
-2012-08-17T01:13:17.213046Z
-755
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-992
-
-AbstractManifestWriter.java
-file
-
-
-
-
-2012-09-14T17:27:50.317216Z
-1ce766c781ae825fb0620a61eb2b2e1c
-2012-08-17T05:55:12.215481Z
-757
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-5030
-
-PackageWriter.java
-file
-
-
-
-
-2012-09-14T17:27:50.317216Z
-ffdb02efc14eeadf6c1ba9c5e500e76c
-2012-08-17T01:13:17.213046Z
-755
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-878
-
-AudioQuality.java
-file
-
-
-
-
-2012-09-14T17:27:50.317216Z
-c2b5ada192ff228aac261452067773fd
-2012-08-17T15:20:10.783404Z
-760
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-887
-
-FlatManifestWriterImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.317216Z
-d45a45107db5f4c43765d95708382310
-2012-09-01T21:55:19.768646Z
-773
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-30095
-
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;
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/all-wcprops
deleted file mode 100644
index 9204edf..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/all-wcprops
+++ /dev/null
@@ -1,47 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 90
-/svn/!svn/ver/776/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder
-END
-FragmentIntersectionFinder.java
-K 25
-svn:wc:ra_dav:version-url
-V 122
-/svn/!svn/ver/455/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/FragmentIntersectionFinder.java
-END
-TwoSecondIntersectionFinder.java
-K 25
-svn:wc:ra_dav:version-url
-V 123
-/svn/!svn/ver/658/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/TwoSecondIntersectionFinder.java
-END
-FragmentedMp4Builder.java
-K 25
-svn:wc:ra_dav:version-url
-V 116
-/svn/!svn/ver/707/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/FragmentedMp4Builder.java
-END
-Mp4Builder.java
-K 25
-svn:wc:ra_dav:version-url
-V 106
-/svn/!svn/ver/672/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/Mp4Builder.java
-END
-SyncSampleIntersectFinderImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 125
-/svn/!svn/ver/774/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/SyncSampleIntersectFinderImpl.java
-END
-DefaultMp4Builder.java
-K 25
-svn:wc:ra_dav:version-url
-V 113
-/svn/!svn/ver/776/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/DefaultMp4Builder.java
-END
-ByteBufferHelper.java
-K 25
-svn:wc:ra_dav:version-url
-V 112
-/svn/!svn/ver/530/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/ByteBufferHelper.java
-END
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/entries
deleted file mode 100644
index 2c6e266..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/entries
+++ /dev/null
@@ -1,266 +0,0 @@
-10
-
-dir
-778
-http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder
-http://mp4parser.googlecode.com/svn
-
-
-
-2012-09-10T14:34:23.574807Z
-776
-sebastian.annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7decde4b-c250-0410-a0da-51896bc88be6
-
-FragmentIntersectionFinder.java
-file
-
-
-
-
-2012-09-14T17:27:50.237215Z
-979df582987d3797c42ae315b3d2555a
-2012-04-10T10:20:46.357991Z
-455
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1160
-
-TwoSecondIntersectionFinder.java
-file
-
-
-
-
-2012-09-14T17:27:50.237215Z
-47aa683919ce24da51b82236e8f27426
-2012-06-06T10:36:10.590512Z
-658
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2817
-
-FragmentedMp4Builder.java
-file
-
-
-
-
-2012-09-14T17:27:50.237215Z
-f81cbeb22aee5ab0405ad38e67b9e4e1
-2012-07-10T16:32:53.757675Z
-707
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-31005
-
-Mp4Builder.java
-file
-
-
-
-
-2012-09-14T17:27:50.237215Z
-ea548a5ace2a4480472b90d9f820bceb
-2012-06-11T22:10:18.183835Z
-672
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1156
-
-SyncSampleIntersectFinderImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.237215Z
-d49823bb95a5920f2df6899195c28a72
-2012-09-06T12:33:39.419429Z
-774
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-14915
-
-DefaultMp4Builder.java
-file
-
-
-
-
-2012-09-14T17:27:50.237215Z
-15d93ea29e24e257604301ad5e73d623
-2012-09-10T14:34:23.574807Z
-776
-sebastian.annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-22096
-
-ByteBufferHelper.java
-file
-
-
-
-
-2012-09-14T17:27:50.237215Z
-a103511eeddf1e0d1962704ae23ba4a5
-2012-04-27T09:17:25.544414Z
-530
-hoemmagnus@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2344
-
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/ByteBufferHelper.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/ByteBufferHelper.java.svn-base
deleted file mode 100644
index ad21b11..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/ByteBufferHelper.java.svn-base
+++ /dev/null
@@ -1,50 +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.builder;
-
-import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Used to merge adjacent byte buffers.
- */
-public class ByteBufferHelper {
- public static List<ByteBuffer> mergeAdjacentBuffers(List<ByteBuffer> samples) {
- ArrayList<ByteBuffer> nuSamples = new ArrayList<ByteBuffer>(samples.size());
- for (ByteBuffer buffer : samples) {
- int lastIndex = nuSamples.size() - 1;
- if (lastIndex >= 0 && buffer.hasArray() && nuSamples.get(lastIndex).hasArray() && buffer.array() == nuSamples.get(lastIndex).array() &&
- nuSamples.get(lastIndex).arrayOffset() + nuSamples.get(lastIndex).limit() == buffer.arrayOffset()) {
- ByteBuffer oldBuffer = nuSamples.remove(lastIndex);
- ByteBuffer nu = ByteBuffer.wrap(buffer.array(), oldBuffer.arrayOffset(), oldBuffer.limit() + buffer.limit()).slice();
- // We need to slice here since wrap([], offset, length) just sets position and not the arrayOffset.
- nuSamples.add(nu);
- } else if (lastIndex >= 0 &&
- buffer instanceof MappedByteBuffer && nuSamples.get(lastIndex) instanceof MappedByteBuffer &&
- nuSamples.get(lastIndex).limit() == nuSamples.get(lastIndex).capacity() - buffer.capacity()) {
- // This can go wrong - but will it?
- ByteBuffer oldBuffer = nuSamples.get(lastIndex);
- oldBuffer.limit(buffer.limit() + oldBuffer.limit());
- } else {
- buffer.rewind();
- nuSamples.add(buffer);
- }
- }
- return nuSamples;
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/DefaultMp4Builder.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/DefaultMp4Builder.java.svn-base
deleted file mode 100644
index 9bd1ca6..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/DefaultMp4Builder.java.svn-base
+++ /dev/null
@@ -1,576 +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.builder;
-
-import com.coremedia.iso.BoxParser;
-import com.coremedia.iso.IsoFile;
-import com.coremedia.iso.IsoTypeWriter;
-import com.coremedia.iso.boxes.Box;
-import com.coremedia.iso.boxes.CompositionTimeToSample;
-import com.coremedia.iso.boxes.ContainerBox;
-import com.coremedia.iso.boxes.DataEntryUrlBox;
-import com.coremedia.iso.boxes.DataInformationBox;
-import com.coremedia.iso.boxes.DataReferenceBox;
-import com.coremedia.iso.boxes.FileTypeBox;
-import com.coremedia.iso.boxes.HandlerBox;
-import com.coremedia.iso.boxes.MediaBox;
-import com.coremedia.iso.boxes.MediaHeaderBox;
-import com.coremedia.iso.boxes.MediaInformationBox;
-import com.coremedia.iso.boxes.MovieBox;
-import com.coremedia.iso.boxes.MovieHeaderBox;
-import com.coremedia.iso.boxes.SampleDependencyTypeBox;
-import com.coremedia.iso.boxes.SampleSizeBox;
-import com.coremedia.iso.boxes.SampleTableBox;
-import com.coremedia.iso.boxes.SampleToChunkBox;
-import com.coremedia.iso.boxes.StaticChunkOffsetBox;
-import com.coremedia.iso.boxes.SyncSampleBox;
-import com.coremedia.iso.boxes.TimeToSampleBox;
-import com.coremedia.iso.boxes.TrackBox;
-import com.coremedia.iso.boxes.TrackHeaderBox;
-import com.googlecode.mp4parser.authoring.DateHelper;
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Track;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.GatheringByteChannel;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.WritableByteChannel;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import static com.googlecode.mp4parser.util.CastUtils.l2i;
-
-/**
- * Creates a plain MP4 file from a video. Plain as plain can be.
- */
-public class DefaultMp4Builder implements Mp4Builder {
-
- public int STEPSIZE = 64;
- Set<StaticChunkOffsetBox> chunkOffsetBoxes = new HashSet<StaticChunkOffsetBox>();
- private static Logger LOG = Logger.getLogger(DefaultMp4Builder.class.getName());
-
- HashMap<Track, List<ByteBuffer>> track2Sample = new HashMap<Track, List<ByteBuffer>>();
- HashMap<Track, long[]> track2SampleSizes = new HashMap<Track, long[]>();
- private FragmentIntersectionFinder intersectionFinder = new TwoSecondIntersectionFinder();
-
- public void setIntersectionFinder(FragmentIntersectionFinder intersectionFinder) {
- this.intersectionFinder = intersectionFinder;
- }
-
- /**
- * {@inheritDoc}
- */
- public IsoFile build(Movie movie) {
- LOG.fine("Creating movie " + movie);
- for (Track track : movie.getTracks()) {
- // getting the samples may be a time consuming activity
- List<ByteBuffer> samples = track.getSamples();
- putSamples(track, samples);
- long[] sizes = new long[samples.size()];
- for (int i = 0; i < sizes.length; i++) {
- sizes[i] = samples.get(i).limit();
- }
- putSampleSizes(track, sizes);
- }
-
- IsoFile isoFile = new IsoFile();
- // ouch that is ugly but I don't know how to do it else
- List<String> minorBrands = new LinkedList<String>();
- minorBrands.add("isom");
- minorBrands.add("iso2");
- minorBrands.add("avc1");
-
- isoFile.addBox(new FileTypeBox("isom", 0, minorBrands));
- isoFile.addBox(createMovieBox(movie));
- InterleaveChunkMdat mdat = new InterleaveChunkMdat(movie);
- isoFile.addBox(mdat);
-
- /*
- dataOffset is where the first sample starts. In this special mdat the samples always start
- at offset 16 so that we can use the same offset for large boxes and small boxes
- */
- long dataOffset = mdat.getDataOffset();
- for (StaticChunkOffsetBox chunkOffsetBox : chunkOffsetBoxes) {
- long[] offsets = chunkOffsetBox.getChunkOffsets();
- for (int i = 0; i < offsets.length; i++) {
- offsets[i] += dataOffset;
- }
- }
-
-
- return isoFile;
- }
-
- public FragmentIntersectionFinder getFragmentIntersectionFinder() {
- throw new UnsupportedOperationException("No fragment intersection finder in default MP4 builder!");
- }
-
- protected long[] putSampleSizes(Track track, long[] sizes) {
- return track2SampleSizes.put(track, sizes);
- }
-
- protected List<ByteBuffer> putSamples(Track track, List<ByteBuffer> samples) {
- return track2Sample.put(track, samples);
- }
-
- private MovieBox createMovieBox(Movie movie) {
- MovieBox movieBox = new MovieBox();
- MovieHeaderBox mvhd = new MovieHeaderBox();
-
- mvhd.setCreationTime(DateHelper.convert(new Date()));
- mvhd.setModificationTime(DateHelper.convert(new Date()));
-
- long movieTimeScale = getTimescale(movie);
- long duration = 0;
-
- for (Track track : movie.getTracks()) {
- long tracksDuration = getDuration(track) * movieTimeScale / track.getTrackMetaData().getTimescale();
- if (tracksDuration > duration) {
- duration = tracksDuration;
- }
-
-
- }
-
- mvhd.setDuration(duration);
- mvhd.setTimescale(movieTimeScale);
- // find the next available trackId
- long nextTrackId = 0;
- for (Track track : movie.getTracks()) {
- nextTrackId = nextTrackId < track.getTrackMetaData().getTrackId() ? track.getTrackMetaData().getTrackId() : nextTrackId;
- }
- mvhd.setNextTrackId(++nextTrackId);
- if (mvhd.getCreationTime() >= 1l << 32 ||
- mvhd.getModificationTime() >= 1l << 32 ||
- mvhd.getDuration() >= 1l << 32) {
- mvhd.setVersion(1);
- }
-
- movieBox.addBox(mvhd);
- for (Track track : movie.getTracks()) {
- movieBox.addBox(createTrackBox(track, movie));
- }
- // metadata here
- Box udta = createUdta(movie);
- if (udta != null) {
- movieBox.addBox(udta);
- }
- return movieBox;
-
- }
-
- /**
- * Override to create a user data box that may contain metadata.
- *
- * @return a 'udta' box or <code>null</code> if none provided
- */
- protected Box createUdta(Movie movie) {
- return null;
- }
-
- private TrackBox createTrackBox(Track track, Movie movie) {
-
- LOG.info("Creating Mp4TrackImpl " + track);
- TrackBox trackBox = new TrackBox();
- TrackHeaderBox tkhd = new TrackHeaderBox();
- int flags = 0;
- if (track.isEnabled()) {
- flags += 1;
- }
-
- if (track.isInMovie()) {
- flags += 2;
- }
-
- if (track.isInPreview()) {
- flags += 4;
- }
-
- if (track.isInPoster()) {
- flags += 8;
- }
- tkhd.setFlags(flags);
-
- tkhd.setAlternateGroup(track.getTrackMetaData().getGroup());
- tkhd.setCreationTime(DateHelper.convert(track.getTrackMetaData().getCreationTime()));
- // We need to take edit list box into account in trackheader duration
- // but as long as I don't support edit list boxes it is sufficient to
- // just translate media duration to movie timescale
- tkhd.setDuration(getDuration(track) * getTimescale(movie) / track.getTrackMetaData().getTimescale());
- tkhd.setHeight(track.getTrackMetaData().getHeight());
- tkhd.setWidth(track.getTrackMetaData().getWidth());
- tkhd.setLayer(track.getTrackMetaData().getLayer());
- tkhd.setModificationTime(DateHelper.convert(new Date()));
- tkhd.setTrackId(track.getTrackMetaData().getTrackId());
- tkhd.setVolume(track.getTrackMetaData().getVolume());
- if (tkhd.getCreationTime() >= 1l << 32 ||
- tkhd.getModificationTime() >= 1l << 32 ||
- tkhd.getDuration() >= 1l << 32) {
- tkhd.setVersion(1);
- }
-
- trackBox.addBox(tkhd);
-
-/*
- EditBox edit = new EditBox();
- EditListBox editListBox = new EditListBox();
- editListBox.setEntries(Collections.singletonList(
- new EditListBox.Entry(editListBox, (long) (track.getTrackMetaData().getStartTime() * getTimescale(movie)), -1, 1)));
- edit.addBox(editListBox);
- trackBox.addBox(edit);
-*/
-
- MediaBox mdia = new MediaBox();
- trackBox.addBox(mdia);
- MediaHeaderBox mdhd = new MediaHeaderBox();
- mdhd.setCreationTime(DateHelper.convert(track.getTrackMetaData().getCreationTime()));
- mdhd.setDuration(getDuration(track));
- mdhd.setTimescale(track.getTrackMetaData().getTimescale());
- mdhd.setLanguage(track.getTrackMetaData().getLanguage());
- mdia.addBox(mdhd);
- HandlerBox hdlr = new HandlerBox();
- mdia.addBox(hdlr);
-
- hdlr.setHandlerType(track.getHandler());
-
- MediaInformationBox minf = new MediaInformationBox();
- minf.addBox(track.getMediaHeaderBox());
-
- // dinf: all these three boxes tell us is that the actual
- // data is in the current file and not somewhere external
- DataInformationBox dinf = new DataInformationBox();
- DataReferenceBox dref = new DataReferenceBox();
- dinf.addBox(dref);
- DataEntryUrlBox url = new DataEntryUrlBox();
- url.setFlags(1);
- dref.addBox(url);
- minf.addBox(dinf);
- //
-
- SampleTableBox stbl = new SampleTableBox();
-
- stbl.addBox(track.getSampleDescriptionBox());
-
- List<TimeToSampleBox.Entry> decodingTimeToSampleEntries = track.getDecodingTimeEntries();
- if (decodingTimeToSampleEntries != null && !track.getDecodingTimeEntries().isEmpty()) {
- TimeToSampleBox stts = new TimeToSampleBox();
- stts.setEntries(track.getDecodingTimeEntries());
- stbl.addBox(stts);
- }
-
- List<CompositionTimeToSample.Entry> compositionTimeToSampleEntries = track.getCompositionTimeEntries();
- if (compositionTimeToSampleEntries != null && !compositionTimeToSampleEntries.isEmpty()) {
- CompositionTimeToSample ctts = new CompositionTimeToSample();
- ctts.setEntries(compositionTimeToSampleEntries);
- stbl.addBox(ctts);
- }
-
- long[] syncSamples = track.getSyncSamples();
- if (syncSamples != null && syncSamples.length > 0) {
- SyncSampleBox stss = new SyncSampleBox();
- stss.setSampleNumber(syncSamples);
- stbl.addBox(stss);
- }
-
- if (track.getSampleDependencies() != null && !track.getSampleDependencies().isEmpty()) {
- SampleDependencyTypeBox sdtp = new SampleDependencyTypeBox();
- sdtp.setEntries(track.getSampleDependencies());
- stbl.addBox(sdtp);
- }
- HashMap<Track, int[]> track2ChunkSizes = new HashMap<Track, int[]>();
- for (Track current : movie.getTracks()) {
- track2ChunkSizes.put(current, getChunkSizes(current, movie));
- }
- int[] tracksChunkSizes = track2ChunkSizes.get(track);
-
- SampleToChunkBox stsc = new SampleToChunkBox();
- stsc.setEntries(new LinkedList<SampleToChunkBox.Entry>());
- long lastChunkSize = Integer.MIN_VALUE; // to be sure the first chunks hasn't got the same size
- for (int i = 0; i < tracksChunkSizes.length; i++) {
- // The sample description index references the sample description box
- // that describes the samples of this chunk. My Tracks cannot have more
- // than one sample description box. Therefore 1 is always right
- // the first chunk has the number '1'
- if (lastChunkSize != tracksChunkSizes[i]) {
- stsc.getEntries().add(new SampleToChunkBox.Entry(i + 1, tracksChunkSizes[i], 1));
- lastChunkSize = tracksChunkSizes[i];
- }
- }
- stbl.addBox(stsc);
-
- SampleSizeBox stsz = new SampleSizeBox();
- stsz.setSampleSizes(track2SampleSizes.get(track));
-
- stbl.addBox(stsz);
- // The ChunkOffsetBox we create here is just a stub
- // since we haven't created the whole structure we can't tell where the
- // first chunk starts (mdat box). So I just let the chunk offset
- // start at zero and I will add the mdat offset later.
- StaticChunkOffsetBox stco = new StaticChunkOffsetBox();
- this.chunkOffsetBoxes.add(stco);
- long offset = 0;
- long[] chunkOffset = new long[tracksChunkSizes.length];
- // all tracks have the same number of chunks
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("Calculating chunk offsets for track_" + track.getTrackMetaData().getTrackId());
- }
-
-
- for (int i = 0; i < tracksChunkSizes.length; i++) {
- // The filelayout will be:
- // chunk_1_track_1,... ,chunk_1_track_n, chunk_2_track_1,... ,chunk_2_track_n, ... , chunk_m_track_1,... ,chunk_m_track_n
- // calculating the offsets
- if (LOG.isLoggable(Level.FINER)) {
- LOG.finer("Calculating chunk offsets for track_" + track.getTrackMetaData().getTrackId() + " chunk " + i);
- }
- for (Track current : movie.getTracks()) {
- if (LOG.isLoggable(Level.FINEST)) {
- LOG.finest("Adding offsets of track_" + current.getTrackMetaData().getTrackId());
- }
- int[] chunkSizes = track2ChunkSizes.get(current);
- long firstSampleOfChunk = 0;
- for (int j = 0; j < i; j++) {
- firstSampleOfChunk += chunkSizes[j];
- }
- if (current == track) {
- chunkOffset[i] = offset;
- }
- for (int j = l2i(firstSampleOfChunk); j < firstSampleOfChunk + chunkSizes[i]; j++) {
- offset += track2SampleSizes.get(current)[j];
- }
- }
- }
- stco.setChunkOffsets(chunkOffset);
- stbl.addBox(stco);
- minf.addBox(stbl);
- mdia.addBox(minf);
-
- return trackBox;
- }
-
- private class InterleaveChunkMdat implements Box {
- List<Track> tracks;
- List<ByteBuffer> samples = new ArrayList<ByteBuffer>();
- ContainerBox parent;
-
- long contentSize = 0;
-
- public ContainerBox getParent() {
- return parent;
- }
-
- public void setParent(ContainerBox parent) {
- this.parent = parent;
- }
-
- public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {
- }
-
- private InterleaveChunkMdat(Movie movie) {
-
- tracks = movie.getTracks();
- Map<Track, int[]> chunks = new HashMap<Track, int[]>();
- for (Track track : movie.getTracks()) {
- chunks.put(track, getChunkSizes(track, movie));
- }
-
- for (int i = 0; i < chunks.values().iterator().next().length; i++) {
- for (Track track : tracks) {
-
- int[] chunkSizes = chunks.get(track);
- long firstSampleOfChunk = 0;
- for (int j = 0; j < i; j++) {
- firstSampleOfChunk += chunkSizes[j];
- }
-
- for (int j = l2i(firstSampleOfChunk); j < firstSampleOfChunk + chunkSizes[i]; j++) {
-
- ByteBuffer s = DefaultMp4Builder.this.track2Sample.get(track).get(j);
- contentSize += s.limit();
- samples.add((ByteBuffer) s.rewind());
- }
-
- }
-
- }
-
- }
-
- public long getDataOffset() {
- Box b = this;
- long offset = 16;
- while (b.getParent() != null) {
- for (Box box : b.getParent().getBoxes()) {
- if (b == box) {
- break;
- }
- offset += box.getSize();
- }
- b = b.getParent();
- }
- return offset;
- }
-
-
- public String getType() {
- return "mdat";
- }
-
- public long getSize() {
- return 16 + contentSize;
- }
-
- private boolean isSmallBox(long contentSize) {
- return (contentSize + 8) < 4294967296L;
- }
-
-
- public void getBox(WritableByteChannel writableByteChannel) throws IOException {
- ByteBuffer bb = ByteBuffer.allocate(16);
- long size = getSize();
- if (isSmallBox(size)) {
- IsoTypeWriter.writeUInt32(bb, size);
- } else {
- IsoTypeWriter.writeUInt32(bb, 1);
- }
- bb.put(IsoFile.fourCCtoBytes("mdat"));
- if (isSmallBox(size)) {
- bb.put(new byte[8]);
- } else {
- IsoTypeWriter.writeUInt64(bb, size);
- }
- bb.rewind();
- writableByteChannel.write(bb);
- if (writableByteChannel instanceof GatheringByteChannel) {
- List<ByteBuffer> nuSamples = unifyAdjacentBuffers(samples);
-
-
- for (int i = 0; i < Math.ceil((double) nuSamples.size() / STEPSIZE); i++) {
- List<ByteBuffer> sublist = nuSamples.subList(
- i * STEPSIZE, // start
- (i + 1) * STEPSIZE < nuSamples.size() ? (i + 1) * STEPSIZE : nuSamples.size()); // end
- ByteBuffer sampleArray[] = sublist.toArray(new ByteBuffer[sublist.size()]);
- do {
- ((GatheringByteChannel) writableByteChannel).write(sampleArray);
- } while (sampleArray[sampleArray.length - 1].remaining() > 0);
- }
- //System.err.println(bytesWritten);
- } else {
- for (ByteBuffer sample : samples) {
- sample.rewind();
- writableByteChannel.write(sample);
- }
- }
- }
-
- }
-
- /**
- * Gets the chunk sizes for the given track.
- *
- * @param track
- * @param movie
- * @return
- */
- int[] getChunkSizes(Track track, Movie movie) {
-
- long[] referenceChunkStarts = intersectionFinder.sampleNumbers(track, movie);
- int[] chunkSizes = new int[referenceChunkStarts.length];
-
-
- for (int i = 0; i < referenceChunkStarts.length; i++) {
- long start = referenceChunkStarts[i] - 1;
- long end;
- if (referenceChunkStarts.length == i + 1) {
- end = track.getSamples().size();
- } else {
- end = referenceChunkStarts[i + 1] - 1;
- }
-
- chunkSizes[i] = l2i(end - start);
- // The Stretch makes sure that there are as much audio and video chunks!
- }
- assert DefaultMp4Builder.this.track2Sample.get(track).size() == sum(chunkSizes) : "The number of samples and the sum of all chunk lengths must be equal";
- return chunkSizes;
-
-
- }
-
-
- private static long sum(int[] ls) {
- long rc = 0;
- for (long l : ls) {
- rc += l;
- }
- return rc;
- }
-
- protected static long getDuration(Track track) {
- long duration = 0;
- for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {
- duration += entry.getCount() * entry.getDelta();
- }
- return duration;
- }
-
- public long getTimescale(Movie movie) {
- long timescale = movie.getTracks().iterator().next().getTrackMetaData().getTimescale();
- for (Track track : movie.getTracks()) {
- timescale = gcd(track.getTrackMetaData().getTimescale(), timescale);
- }
- return timescale;
- }
-
- public static long gcd(long a, long b) {
- if (b == 0) {
- return a;
- }
- return gcd(b, a % b);
- }
-
- public List<ByteBuffer> unifyAdjacentBuffers(List<ByteBuffer> samples) {
- ArrayList<ByteBuffer> nuSamples = new ArrayList<ByteBuffer>(samples.size());
- for (ByteBuffer buffer : samples) {
- int lastIndex = nuSamples.size() - 1;
- if (lastIndex >= 0 && buffer.hasArray() && nuSamples.get(lastIndex).hasArray() && buffer.array() == nuSamples.get(lastIndex).array() &&
- nuSamples.get(lastIndex).arrayOffset() + nuSamples.get(lastIndex).limit() == buffer.arrayOffset()) {
- ByteBuffer oldBuffer = nuSamples.remove(lastIndex);
- ByteBuffer nu = ByteBuffer.wrap(buffer.array(), oldBuffer.arrayOffset(), oldBuffer.limit() + buffer.limit()).slice();
- // We need to slice here since wrap([], offset, length) just sets position and not the arrayOffset.
- nuSamples.add(nu);
- } else if (lastIndex >= 0 &&
- buffer instanceof MappedByteBuffer && nuSamples.get(lastIndex) instanceof MappedByteBuffer &&
- nuSamples.get(lastIndex).limit() == nuSamples.get(lastIndex).capacity() - buffer.capacity()) {
- // This can go wrong - but will it?
- ByteBuffer oldBuffer = nuSamples.get(lastIndex);
- oldBuffer.limit(buffer.limit() + oldBuffer.limit());
- } else {
- nuSamples.add(buffer);
- }
- }
- return nuSamples;
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/FragmentIntersectionFinder.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/FragmentIntersectionFinder.java.svn-base
deleted file mode 100644
index 1224bbf..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/FragmentIntersectionFinder.java.svn-base
+++ /dev/null
@@ -1,34 +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.builder;
-
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Track;
-
-/**
- *
- */
-public interface FragmentIntersectionFinder {
- /**
- * Gets the ordinal number of the samples which will be the first sample
- * in each fragment.
- *
- * @param track concerned track
- * @param movie the context of the track
- * @return an array containing the ordinal of each fragment's first sample
- */
- public long[] sampleNumbers(Track track, Movie movie);
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/FragmentedMp4Builder.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/FragmentedMp4Builder.java.svn-base
deleted file mode 100644
index c65ff1c..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/FragmentedMp4Builder.java.svn-base
+++ /dev/null
@@ -1,742 +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.builder;
-
-import com.coremedia.iso.BoxParser;
-import com.coremedia.iso.IsoFile;
-import com.coremedia.iso.IsoTypeWriter;
-import com.coremedia.iso.boxes.*;
-import com.coremedia.iso.boxes.fragment.*;
-import com.googlecode.mp4parser.authoring.DateHelper;
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Track;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.GatheringByteChannel;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.WritableByteChannel;
-import java.util.*;
-import java.util.logging.Logger;
-
-import static com.googlecode.mp4parser.util.CastUtils.l2i;
-
-/**
- * Creates a fragmented MP4 file.
- */
-public class FragmentedMp4Builder implements Mp4Builder {
- private static final Logger LOG = Logger.getLogger(FragmentedMp4Builder.class.getName());
-
- protected FragmentIntersectionFinder intersectionFinder;
-
- public FragmentedMp4Builder() {
- this.intersectionFinder = new SyncSampleIntersectFinderImpl();
- }
-
- public List<String> getAllowedHandlers() {
- return Arrays.asList("soun", "vide");
- }
-
- public Box createFtyp(Movie movie) {
- List<String> minorBrands = new LinkedList<String>();
- minorBrands.add("isom");
- minorBrands.add("iso2");
- minorBrands.add("avc1");
- return new FileTypeBox("isom", 0, minorBrands);
- }
-
- /**
- * Some formats require sorting of the fragments. E.g. Ultraviolet CFF files are required
- * to contain the fragments size sort:
- * <ul>
- * <li>video[1].getBytes().length < audio[1].getBytes().length < subs[1].getBytes().length</li>
- * <li> audio[2].getBytes().length < video[2].getBytes().length < subs[2].getBytes().length</li>
- * </ul>
- *
- * make this fragment:
- *
- * <ol>
- * <li>video[1]</li>
- * <li>audio[1]</li>
- * <li>subs[1]</li>
- * <li>audio[2]</li>
- * <li>video[2]</li>
- * <li>subs[2]</li>
- * </ol>
- *
- * @param tracks the list of tracks to returned sorted
- * @param cycle current fragment (sorting may vary between the fragments)
- * @param intersectionMap a map from tracks to their fragments' first samples.
- * @return the list of tracks in order of appearance in the fragment
- */
- protected List<Track> sortTracksInSequence(List<Track> tracks, final int cycle, final Map<Track, long[]> intersectionMap) {
- tracks = new LinkedList<Track>(tracks);
- Collections.sort(tracks, new Comparator<Track>() {
- public int compare(Track o1, Track o2) {
- long[] startSamples1 = intersectionMap.get(o1);
- long startSample1 = startSamples1[cycle];
- // one based sample numbers - the first sample is 1
- long endSample1 = cycle + 1 < startSamples1.length ? startSamples1[cycle + 1] : o1.getSamples().size() + 1;
- long[] startSamples2 = intersectionMap.get(o2);
- long startSample2 = startSamples2[cycle];
- // one based sample numbers - the first sample is 1
- long endSample2 = cycle + 1 < startSamples2.length ? startSamples2[cycle + 1] : o2.getSamples().size() + 1;
- List<ByteBuffer> samples1 = o1.getSamples().subList(l2i(startSample1) - 1, l2i(endSample1) - 1);
- List<ByteBuffer> samples2 = o2.getSamples().subList(l2i(startSample2) - 1, l2i(endSample2) - 1);
- int size1 = 0;
- for (ByteBuffer byteBuffer : samples1) {
- size1 += byteBuffer.limit();
- }
- int size2 = 0;
- for (ByteBuffer byteBuffer : samples2) {
- size2 += byteBuffer.limit();
- }
- return size1 - size2;
- }
- });
- return tracks;
- }
-
- protected List<Box> createMoofMdat(final Movie movie) {
- List<Box> boxes = new LinkedList<Box>();
- HashMap<Track, long[]> intersectionMap = new HashMap<Track, long[]>();
- int maxNumberOfFragments = 0;
- for (Track track : movie.getTracks()) {
- long[] intersects = intersectionFinder.sampleNumbers(track, movie);
- intersectionMap.put(track, intersects);
- maxNumberOfFragments = Math.max(maxNumberOfFragments, intersects.length);
- }
-
-
- int sequence = 1;
- // this loop has two indices:
-
- for (int cycle = 0; cycle < maxNumberOfFragments; cycle++) {
-
- final List<Track> sortedTracks = sortTracksInSequence(movie.getTracks(), cycle, intersectionMap);
-
- for (Track track : sortedTracks) {
- if (getAllowedHandlers().isEmpty() || getAllowedHandlers().contains(track.getHandler())) {
- long[] startSamples = intersectionMap.get(track);
- //some tracks may have less fragments -> skip them
- if (cycle < startSamples.length) {
-
- long startSample = startSamples[cycle];
- // one based sample numbers - the first sample is 1
- long endSample = cycle + 1 < startSamples.length ? startSamples[cycle + 1] : track.getSamples().size() + 1;
-
- // if startSample == endSample the cycle is empty!
- if (startSample != endSample) {
- boxes.add(createMoof(startSample, endSample, track, sequence));
- boxes.add(createMdat(startSample, endSample, track, sequence++));
- }
- }
- }
- }
- }
- return boxes;
- }
-
- /**
- * {@inheritDoc}
- */
- public IsoFile build(Movie movie) {
- LOG.fine("Creating movie " + movie);
- IsoFile isoFile = new IsoFile();
-
-
- isoFile.addBox(createFtyp(movie));
- isoFile.addBox(createMoov(movie));
-
- for (Box box : createMoofMdat(movie)) {
- isoFile.addBox(box);
- }
- isoFile.addBox(createMfra(movie, isoFile));
-
- return isoFile;
- }
-
- protected Box createMdat(final long startSample, final long endSample, final Track track, final int i) {
-
- class Mdat implements Box {
- ContainerBox parent;
-
- public ContainerBox getParent() {
- return parent;
- }
-
- public void setParent(ContainerBox parent) {
- this.parent = parent;
- }
-
- public long getSize() {
- long size = 8; // I don't expect 2gig fragments
- for (ByteBuffer sample : getSamples(startSample, endSample, track, i)) {
- size += sample.limit();
- }
- return size;
- }
-
- public String getType() {
- return "mdat";
- }
-
- public void getBox(WritableByteChannel writableByteChannel) throws IOException {
- List<ByteBuffer> bbs = getSamples(startSample, endSample, track, i);
- final List<ByteBuffer> samples = ByteBufferHelper.mergeAdjacentBuffers(bbs);
- ByteBuffer header = ByteBuffer.allocate(8);
- IsoTypeWriter.writeUInt32(header, l2i(getSize()));
- header.put(IsoFile.fourCCtoBytes(getType()));
- header.rewind();
- writableByteChannel.write(header);
- if (writableByteChannel instanceof GatheringByteChannel) {
-
- int STEPSIZE = 1024;
- // This is required to prevent android from crashing
- // it seems that {@link GatheringByteChannel#write(java.nio.ByteBuffer[])}
- // just handles up to 1024 buffers
- for (int i = 0; i < Math.ceil((double) samples.size() / STEPSIZE); i++) {
- List<ByteBuffer> sublist = samples.subList(
- i * STEPSIZE, // start
- (i + 1) * STEPSIZE < samples.size() ? (i + 1) * STEPSIZE : samples.size()); // end
- ByteBuffer sampleArray[] = sublist.toArray(new ByteBuffer[sublist.size()]);
- do {
- ((GatheringByteChannel) writableByteChannel).write(sampleArray);
- } while (sampleArray[sampleArray.length - 1].remaining() > 0);
- }
- //System.err.println(bytesWritten);
- } else {
- for (ByteBuffer sample : samples) {
- sample.rewind();
- writableByteChannel.write(sample);
- }
- }
-
- }
-
- public void parse(ReadableByteChannel readableByteChannel, ByteBuffer header, long contentSize, BoxParser boxParser) throws IOException {
-
- }
- }
-
- return new Mdat();
- }
-
- protected Box createTfhd(long startSample, long endSample, Track track, int sequenceNumber) {
- TrackFragmentHeaderBox tfhd = new TrackFragmentHeaderBox();
- SampleFlags sf = new SampleFlags();
-
- tfhd.setDefaultSampleFlags(sf);
- tfhd.setBaseDataOffset(-1);
- tfhd.setTrackId(track.getTrackMetaData().getTrackId());
- return tfhd;
- }
-
- protected Box createMfhd(long startSample, long endSample, Track track, int sequenceNumber) {
- MovieFragmentHeaderBox mfhd = new MovieFragmentHeaderBox();
- mfhd.setSequenceNumber(sequenceNumber);
- return mfhd;
- }
-
- protected Box createTraf(long startSample, long endSample, Track track, int sequenceNumber) {
- TrackFragmentBox traf = new TrackFragmentBox();
- traf.addBox(createTfhd(startSample, endSample, track, sequenceNumber));
- for (Box trun : createTruns(startSample, endSample, track, sequenceNumber)) {
- traf.addBox(trun);
- }
-
- return traf;
- }
-
-
- /**
- * Gets the all samples starting with <code>startSample</code> (one based -> one is the first) and
- * ending with <code>endSample</code> (exclusive).
- *
- * @param startSample low endpoint (inclusive) of the sample sequence
- * @param endSample high endpoint (exclusive) of the sample sequence
- * @param track source of the samples
- * @param sequenceNumber the fragment index of the requested list of samples
- * @return a <code>List&lt;ByteBuffer></code> of raw samples
- */
- protected List<ByteBuffer> getSamples(long startSample, long endSample, Track track, int sequenceNumber) {
- // since startSample and endSample are one-based substract 1 before addressing list elements
- return track.getSamples().subList(l2i(startSample) - 1, l2i(endSample) - 1);
- }
-
- /**
- * Gets the sizes of a sequence of samples-
- *
- * @param startSample low endpoint (inclusive) of the sample sequence
- * @param endSample high endpoint (exclusive) of the sample sequence
- * @param track source of the samples
- * @param sequenceNumber the fragment index of the requested list of samples
- * @return
- */
- protected long[] getSampleSizes(long startSample, long endSample, Track track, int sequenceNumber) {
- List<ByteBuffer> samples = getSamples(startSample, endSample, track, sequenceNumber);
-
- long[] sampleSizes = new long[samples.size()];
- for (int i = 0; i < sampleSizes.length; i++) {
- sampleSizes[i] = samples.get(i).limit();
- }
- return sampleSizes;
- }
-
- /**
- * Creates one or more track run boxes for a given sequence.
- *
- * @param startSample low endpoint (inclusive) of the sample sequence
- * @param endSample high endpoint (exclusive) of the sample sequence
- * @param track source of the samples
- * @param sequenceNumber the fragment index of the requested list of samples
- * @return the list of TrackRun boxes.
- */
- protected List<? extends Box> createTruns(long startSample, long endSample, Track track, int sequenceNumber) {
- TrackRunBox trun = new TrackRunBox();
- long[] sampleSizes = getSampleSizes(startSample, endSample, track, sequenceNumber);
-
- trun.setSampleDurationPresent(true);
- trun.setSampleSizePresent(true);
- List<TrackRunBox.Entry> entries = new ArrayList<TrackRunBox.Entry>(l2i(endSample - startSample));
-
-
- Queue<TimeToSampleBox.Entry> timeQueue = new LinkedList<TimeToSampleBox.Entry>(track.getDecodingTimeEntries());
- long left = startSample - 1;
- long curEntryLeft = timeQueue.peek().getCount();
- while (left > curEntryLeft) {
- left -= curEntryLeft;
- timeQueue.remove();
- curEntryLeft = timeQueue.peek().getCount();
- }
- curEntryLeft -= left;
-
-
- Queue<CompositionTimeToSample.Entry> compositionTimeQueue =
- track.getCompositionTimeEntries() != null && track.getCompositionTimeEntries().size() > 0 ?
- new LinkedList<CompositionTimeToSample.Entry>(track.getCompositionTimeEntries()) : null;
- long compositionTimeEntriesLeft = compositionTimeQueue != null ? compositionTimeQueue.peek().getCount() : -1;
-
-
- trun.setSampleCompositionTimeOffsetPresent(compositionTimeEntriesLeft > 0);
-
- // fast forward composition stuff
- for (long i = 1; i < startSample; i++) {
- if (compositionTimeQueue != null) {
- //trun.setSampleCompositionTimeOffsetPresent(true);
- if (--compositionTimeEntriesLeft == 0 && compositionTimeQueue.size() > 1) {
- compositionTimeQueue.remove();
- compositionTimeEntriesLeft = compositionTimeQueue.element().getCount();
- }
- }
- }
-
- boolean sampleFlagsRequired = (track.getSampleDependencies() != null && !track.getSampleDependencies().isEmpty() ||
- track.getSyncSamples() != null && track.getSyncSamples().length != 0);
-
- trun.setSampleFlagsPresent(sampleFlagsRequired);
-
- for (int i = 0; i < sampleSizes.length; i++) {
- TrackRunBox.Entry entry = new TrackRunBox.Entry();
- entry.setSampleSize(sampleSizes[i]);
- if (sampleFlagsRequired) {
- //if (false) {
- SampleFlags sflags = new SampleFlags();
-
- if (track.getSampleDependencies() != null && !track.getSampleDependencies().isEmpty()) {
- SampleDependencyTypeBox.Entry e = track.getSampleDependencies().get(i);
- sflags.setSampleDependsOn(e.getSampleDependsOn());
- sflags.setSampleIsDependedOn(e.getSampleIsDependentOn());
- sflags.setSampleHasRedundancy(e.getSampleHasRedundancy());
- }
- if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
- // we have to mark non-sync samples!
- if (Arrays.binarySearch(track.getSyncSamples(), startSample + i) >= 0) {
- sflags.setSampleIsDifferenceSample(false);
- sflags.setSampleDependsOn(2);
- } else {
- sflags.setSampleIsDifferenceSample(true);
- sflags.setSampleDependsOn(1);
- }
- }
- // i don't have sample degradation
- entry.setSampleFlags(sflags);
-
- }
-
- entry.setSampleDuration(timeQueue.peek().getDelta());
- if (--curEntryLeft == 0 && timeQueue.size() > 1) {
- timeQueue.remove();
- curEntryLeft = timeQueue.peek().getCount();
- }
-
- if (compositionTimeQueue != null) {
- entry.setSampleCompositionTimeOffset(compositionTimeQueue.peek().getOffset());
- if (--compositionTimeEntriesLeft == 0 && compositionTimeQueue.size() > 1) {
- compositionTimeQueue.remove();
- compositionTimeEntriesLeft = compositionTimeQueue.element().getCount();
- }
- }
- entries.add(entry);
- }
-
- trun.setEntries(entries);
-
- return Collections.singletonList(trun);
- }
-
- /**
- * Creates a 'moof' box for a given sequence of samples.
- *
- * @param startSample low endpoint (inclusive) of the sample sequence
- * @param endSample high endpoint (exclusive) of the sample sequence
- * @param track source of the samples
- * @param sequenceNumber the fragment index of the requested list of samples
- * @return the list of TrackRun boxes.
- */
- protected Box createMoof(long startSample, long endSample, Track track, int sequenceNumber) {
- MovieFragmentBox moof = new MovieFragmentBox();
- moof.addBox(createMfhd(startSample, endSample, track, sequenceNumber));
- moof.addBox(createTraf(startSample, endSample, track, sequenceNumber));
-
- TrackRunBox firstTrun = moof.getTrackRunBoxes().get(0);
- firstTrun.setDataOffset(1); // dummy to make size correct
- firstTrun.setDataOffset((int) (8 + moof.getSize())); // mdat header + moof size
-
- return moof;
- }
-
- /**
- * Creates a single 'mvhd' movie header box for a given movie.
- *
- * @param movie the concerned movie
- * @return an 'mvhd' box
- */
- protected Box createMvhd(Movie movie) {
- MovieHeaderBox mvhd = new MovieHeaderBox();
- mvhd.setVersion(1);
- mvhd.setCreationTime(DateHelper.convert(new Date()));
- mvhd.setModificationTime(DateHelper.convert(new Date()));
- long movieTimeScale = movie.getTimescale();
- long duration = 0;
-
- for (Track track : movie.getTracks()) {
- long tracksDuration = getDuration(track) * movieTimeScale / track.getTrackMetaData().getTimescale();
- if (tracksDuration > duration) {
- duration = tracksDuration;
- }
-
-
- }
-
- mvhd.setDuration(duration);
- mvhd.setTimescale(movieTimeScale);
- // find the next available trackId
- long nextTrackId = 0;
- for (Track track : movie.getTracks()) {
- nextTrackId = nextTrackId < track.getTrackMetaData().getTrackId() ? track.getTrackMetaData().getTrackId() : nextTrackId;
- }
- mvhd.setNextTrackId(++nextTrackId);
- return mvhd;
- }
-
- /**
- * Creates a fully populated 'moov' box with all child boxes. Child boxes are:
- * <ul>
- * <li>{@link #createMvhd(com.googlecode.mp4parser.authoring.Movie) mvhd}</li>
- * <li>{@link #createMvex(com.googlecode.mp4parser.authoring.Movie) mvex}</li>
- * <li>a {@link #createTrak(com.googlecode.mp4parser.authoring.Track, com.googlecode.mp4parser.authoring.Movie) trak} for every track</li>
- * </ul>
- *
- * @param movie the concerned movie
- * @return fully populated 'moov'
- */
- protected Box createMoov(Movie movie) {
- MovieBox movieBox = new MovieBox();
-
- movieBox.addBox(createMvhd(movie));
- movieBox.addBox(createMvex(movie));
-
- for (Track track : movie.getTracks()) {
- movieBox.addBox(createTrak(track, movie));
- }
- // metadata here
- return movieBox;
-
- }
-
- /**
- * Creates a 'tfra' - track fragment random access box for the given track with the isoFile.
- * The tfra contains a map of random access points with time as key and offset within the isofile
- * as value.
- *
- * @param track the concerned track
- * @param isoFile the track is contained in
- * @return a track fragment random access box.
- */
- protected Box createTfra(Track track, IsoFile isoFile) {
- TrackFragmentRandomAccessBox tfra = new TrackFragmentRandomAccessBox();
- tfra.setVersion(1); // use long offsets and times
- List<TrackFragmentRandomAccessBox.Entry> offset2timeEntries = new LinkedList<TrackFragmentRandomAccessBox.Entry>();
- List<Box> boxes = isoFile.getBoxes();
- long offset = 0;
- long duration = 0;
- for (Box box : boxes) {
- if (box instanceof MovieFragmentBox) {
- List<TrackFragmentBox> trafs = ((MovieFragmentBox) box).getBoxes(TrackFragmentBox.class);
- for (int i = 0; i < trafs.size(); i++) {
- TrackFragmentBox traf = trafs.get(i);
- if (traf.getTrackFragmentHeaderBox().getTrackId() == track.getTrackMetaData().getTrackId()) {
- // here we are at the offset required for the current entry.
- List<TrackRunBox> truns = traf.getBoxes(TrackRunBox.class);
- for (int j = 0; j < truns.size(); j++) {
- List<TrackFragmentRandomAccessBox.Entry> offset2timeEntriesThisTrun = new LinkedList<TrackFragmentRandomAccessBox.Entry>();
- TrackRunBox trun = truns.get(j);
- for (int k = 0; k < trun.getEntries().size(); k++) {
- TrackRunBox.Entry trunEntry = trun.getEntries().get(k);
- SampleFlags sf = null;
- if (k == 0 && trun.isFirstSampleFlagsPresent()) {
- sf = trun.getFirstSampleFlags();
- } else if (trun.isSampleFlagsPresent()) {
- sf = trunEntry.getSampleFlags();
- } else {
- List<MovieExtendsBox> mvexs = isoFile.getMovieBox().getBoxes(MovieExtendsBox.class);
- for (MovieExtendsBox mvex : mvexs) {
- List<TrackExtendsBox> trexs = mvex.getBoxes(TrackExtendsBox.class);
- for (TrackExtendsBox trex : trexs) {
- if (trex.getTrackId() == track.getTrackMetaData().getTrackId()) {
- sf = trex.getDefaultSampleFlags();
- }
- }
- }
-
- }
- if (sf == null) {
- throw new RuntimeException("Could not find any SampleFlags to indicate random access or not");
- }
- if (sf.getSampleDependsOn() == 2) {
- offset2timeEntriesThisTrun.add(new TrackFragmentRandomAccessBox.Entry(
- duration,
- offset,
- i + 1, j + 1, k + 1));
- }
- duration += trunEntry.getSampleDuration();
- }
- if (offset2timeEntriesThisTrun.size() == trun.getEntries().size() && trun.getEntries().size() > 0) {
- // Oooops every sample seems to be random access sample
- // is this an audio track? I don't care.
- // I just use the first for trun sample for tfra random access
- offset2timeEntries.add(offset2timeEntriesThisTrun.get(0));
- } else {
- offset2timeEntries.addAll(offset2timeEntriesThisTrun);
- }
- }
- }
- }
- }
-
-
- offset += box.getSize();
- }
- tfra.setEntries(offset2timeEntries);
- tfra.setTrackId(track.getTrackMetaData().getTrackId());
- return tfra;
- }
-
- /**
- * Creates a 'mfra' - movie fragment random access box for the given movie in the given
- * isofile. Uses {@link #createTfra(com.googlecode.mp4parser.authoring.Track, com.coremedia.iso.IsoFile)}
- * to generate the child boxes.
- *
- * @param movie concerned movie
- * @param isoFile concerned isofile
- * @return a complete 'mfra' box
- */
- protected Box createMfra(Movie movie, IsoFile isoFile) {
- MovieFragmentRandomAccessBox mfra = new MovieFragmentRandomAccessBox();
- for (Track track : movie.getTracks()) {
- mfra.addBox(createTfra(track, isoFile));
- }
-
- MovieFragmentRandomAccessOffsetBox mfro = new MovieFragmentRandomAccessOffsetBox();
- mfra.addBox(mfro);
- mfro.setMfraSize(mfra.getSize());
- return mfra;
- }
-
- protected Box createTrex(Movie movie, Track track) {
- TrackExtendsBox trex = new TrackExtendsBox();
- trex.setTrackId(track.getTrackMetaData().getTrackId());
- trex.setDefaultSampleDescriptionIndex(1);
- trex.setDefaultSampleDuration(0);
- trex.setDefaultSampleSize(0);
- SampleFlags sf = new SampleFlags();
- if ("soun".equals(track.getHandler())) {
- // as far as I know there is no audio encoding
- // where the sample are not self contained.
- sf.setSampleDependsOn(2);
- sf.setSampleIsDependedOn(2);
- }
- trex.setDefaultSampleFlags(sf);
- return trex;
- }
-
- /**
- * Creates a 'mvex' - movie extends box and populates it with 'trex' boxes
- * by calling {@link #createTrex(com.googlecode.mp4parser.authoring.Movie, com.googlecode.mp4parser.authoring.Track)}
- * for each track to generate them
- *
- * @param movie the source movie
- * @return a complete 'mvex'
- */
- protected Box createMvex(Movie movie) {
- MovieExtendsBox mvex = new MovieExtendsBox();
- final MovieExtendsHeaderBox mved = new MovieExtendsHeaderBox();
- for (Track track : movie.getTracks()) {
- final long trackDuration = getTrackDuration(movie, track);
- if (mved.getFragmentDuration() < trackDuration) {
- mved.setFragmentDuration(trackDuration);
- }
- }
- mvex.addBox(mved);
-
- for (Track track : movie.getTracks()) {
- mvex.addBox(createTrex(movie, track));
- }
- return mvex;
- }
-
- protected Box createTkhd(Movie movie, Track track) {
- TrackHeaderBox tkhd = new TrackHeaderBox();
- tkhd.setVersion(1);
- int flags = 0;
- if (track.isEnabled()) {
- flags += 1;
- }
-
- if (track.isInMovie()) {
- flags += 2;
- }
-
- if (track.isInPreview()) {
- flags += 4;
- }
-
- if (track.isInPoster()) {
- flags += 8;
- }
- tkhd.setFlags(flags);
-
- tkhd.setAlternateGroup(track.getTrackMetaData().getGroup());
- tkhd.setCreationTime(DateHelper.convert(track.getTrackMetaData().getCreationTime()));
- // We need to take edit list box into account in trackheader duration
- // but as long as I don't support edit list boxes it is sufficient to
- // just translate media duration to movie timescale
- tkhd.setDuration(getTrackDuration(movie, track));
- tkhd.setHeight(track.getTrackMetaData().getHeight());
- tkhd.setWidth(track.getTrackMetaData().getWidth());
- tkhd.setLayer(track.getTrackMetaData().getLayer());
- tkhd.setModificationTime(DateHelper.convert(new Date()));
- tkhd.setTrackId(track.getTrackMetaData().getTrackId());
- tkhd.setVolume(track.getTrackMetaData().getVolume());
- return tkhd;
- }
-
- private long getTrackDuration(Movie movie, Track track) {
- return getDuration(track) * movie.getTimescale() / track.getTrackMetaData().getTimescale();
- }
-
- protected Box createMdhd(Movie movie, Track track) {
- MediaHeaderBox mdhd = new MediaHeaderBox();
- mdhd.setCreationTime(DateHelper.convert(track.getTrackMetaData().getCreationTime()));
- mdhd.setDuration(getDuration(track));
- mdhd.setTimescale(track.getTrackMetaData().getTimescale());
- mdhd.setLanguage(track.getTrackMetaData().getLanguage());
- return mdhd;
- }
-
- protected Box createStbl(Movie movie, Track track) {
- SampleTableBox stbl = new SampleTableBox();
-
- stbl.addBox(track.getSampleDescriptionBox());
- stbl.addBox(new TimeToSampleBox());
- //stbl.addBox(new SampleToChunkBox());
- stbl.addBox(new StaticChunkOffsetBox());
- return stbl;
- }
-
- protected Box createMinf(Track track, Movie movie) {
- MediaInformationBox minf = new MediaInformationBox();
- minf.addBox(track.getMediaHeaderBox());
- minf.addBox(createDinf(movie, track));
- minf.addBox(createStbl(movie, track));
- return minf;
- }
-
- protected Box createMdiaHdlr(Track track, Movie movie) {
- HandlerBox hdlr = new HandlerBox();
- hdlr.setHandlerType(track.getHandler());
- return hdlr;
- }
-
- protected Box createMdia(Track track, Movie movie) {
- MediaBox mdia = new MediaBox();
- mdia.addBox(createMdhd(movie, track));
-
-
- mdia.addBox(createMdiaHdlr(track, movie));
-
-
- mdia.addBox(createMinf(track, movie));
- return mdia;
- }
-
- protected Box createTrak(Track track, Movie movie) {
- LOG.fine("Creating Track " + track);
- TrackBox trackBox = new TrackBox();
- trackBox.addBox(createTkhd(movie, track));
- trackBox.addBox(createMdia(track, movie));
- return trackBox;
- }
-
- protected DataInformationBox createDinf(Movie movie, Track track) {
- DataInformationBox dinf = new DataInformationBox();
- DataReferenceBox dref = new DataReferenceBox();
- dinf.addBox(dref);
- DataEntryUrlBox url = new DataEntryUrlBox();
- url.setFlags(1);
- dref.addBox(url);
- return dinf;
- }
-
- public FragmentIntersectionFinder getFragmentIntersectionFinder() {
- return intersectionFinder;
- }
-
- public void setIntersectionFinder(FragmentIntersectionFinder intersectionFinder) {
- this.intersectionFinder = intersectionFinder;
- }
-
- protected long getDuration(Track track) {
- long duration = 0;
- for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {
- duration += entry.getCount() * entry.getDelta();
- }
- return duration;
- }
-
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/Mp4Builder.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/Mp4Builder.java.svn-base
deleted file mode 100644
index 725745e..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/Mp4Builder.java.svn-base
+++ /dev/null
@@ -1,35 +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.builder;
-
-import com.coremedia.iso.IsoFile;
-import com.googlecode.mp4parser.authoring.Movie;
-
-/**
- * Transforms a <code>Movie</code> object to an IsoFile. Implementations can
- * determine the specific format: Fragmented MP4, MP4, MP4 with Apple Metadata,
- * MP4 with 3GPP Metadata, MOV.
- */
-public interface Mp4Builder {
- /**
- * Builds the actual IsoFile from the Movie.
- *
- * @param movie data source
- * @return the freshly built IsoFile
- */
- public IsoFile build(Movie movie);
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/SyncSampleIntersectFinderImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/SyncSampleIntersectFinderImpl.java.svn-base
deleted file mode 100644
index 2766c5e..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/SyncSampleIntersectFinderImpl.java.svn-base
+++ /dev/null
@@ -1,334 +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.builder;
-
-import com.coremedia.iso.boxes.TimeToSampleBox;
-import com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Track;
-
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
-
-import static com.googlecode.mp4parser.util.Math.lcm;
-
-/**
- * This <code>FragmentIntersectionFinder</code> cuts the input movie video tracks in
- * fragments of the same length exactly before the sync samples. Audio tracks are cut
- * into pieces of similar length.
- */
-public class SyncSampleIntersectFinderImpl implements FragmentIntersectionFinder {
-
- private static Logger LOG = Logger.getLogger(SyncSampleIntersectFinderImpl.class.getName());
- private static Map<CacheTuple, long[]> getTimesCache = new ConcurrentHashMap<CacheTuple, long[]>();
- private static Map<CacheTuple, long[]> getSampleNumbersCache = new ConcurrentHashMap<CacheTuple, long[]>();
-
- private final int minFragmentDurationSeconds;
-
- public SyncSampleIntersectFinderImpl() {
- minFragmentDurationSeconds = 0;
- }
-
- /**
- * Creates a <code>SyncSampleIntersectFinderImpl</code> that will not create any fragment
- * smaller than the given <code>minFragmentDurationSeconds</code>
- *
- * @param minFragmentDurationSeconds the smallest allowable duration of a fragment.
- */
- public SyncSampleIntersectFinderImpl(int minFragmentDurationSeconds) {
- this.minFragmentDurationSeconds = minFragmentDurationSeconds;
- }
-
- /**
- * Gets an array of sample numbers that are meant to be the first sample of each
- * chunk or fragment.
- *
- * @param track concerned track
- * @param movie the context of the track
- * @return an array containing the ordinal of each fragment's first sample
- */
- public long[] sampleNumbers(Track track, Movie movie) {
- final CacheTuple key = new CacheTuple(track, movie);
- final long[] result = getSampleNumbersCache.get(key);
- if (result != null) {
- return result;
- }
-
- if ("vide".equals(track.getHandler())) {
- if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
- List<long[]> times = getSyncSamplesTimestamps(movie, track);
- final long[] commonIndices = getCommonIndices(track.getSyncSamples(), getTimes(track, movie), track.getTrackMetaData().getTimescale(), times.toArray(new long[times.size()][]));
- getSampleNumbersCache.put(key, commonIndices);
- return commonIndices;
- } else {
- throw new RuntimeException("Video Tracks need sync samples. Only tracks other than video may have no sync samples.");
- }
- } else if ("soun".equals(track.getHandler())) {
- Track referenceTrack = null;
- for (Track candidate : movie.getTracks()) {
- if (candidate.getSyncSamples() != null && "vide".equals(candidate.getHandler()) && candidate.getSyncSamples().length > 0) {
- referenceTrack = candidate;
- }
- }
- if (referenceTrack != null) {
-
- // Gets the reference track's fra
- long[] refSyncSamples = sampleNumbers(referenceTrack, movie);
-
- int refSampleCount = referenceTrack.getSamples().size();
-
- long[] syncSamples = new long[refSyncSamples.length];
- long minSampleRate = 192000;
- for (Track testTrack : movie.getTracks()) {
- if ("soun".equals(testTrack.getHandler())) {
- AudioSampleEntry ase = (AudioSampleEntry) testTrack.getSampleDescriptionBox().getSampleEntry();
- if (ase.getSampleRate() < minSampleRate) {
- minSampleRate = ase.getSampleRate();
- long sc = testTrack.getSamples().size();
- double stretch = (double) sc / refSampleCount;
- TimeToSampleBox.Entry sttsEntry = testTrack.getDecodingTimeEntries().get(0);
- long samplesPerFrame = sttsEntry.getDelta(); // Assuming all audio tracks have the same number of samples per frame, which they do for all known types
-
- for (int i = 0; i < syncSamples.length; i++) {
- long start = (long) Math.ceil(stretch * (refSyncSamples[i] - 1) * samplesPerFrame);
- syncSamples[i] = start;
- // The Stretch makes sure that there are as much audio and video chunks!
- }
- break;
- }
- }
- }
- AudioSampleEntry ase = (AudioSampleEntry) track.getSampleDescriptionBox().getSampleEntry();
- TimeToSampleBox.Entry sttsEntry = track.getDecodingTimeEntries().get(0);
- long samplesPerFrame = sttsEntry.getDelta(); // Assuming all audio tracks have the same number of samples per frame, which they do for all known types
- double factor = (double) ase.getSampleRate() / (double) minSampleRate;
- if (factor != Math.rint(factor)) { // Not an integer
- throw new RuntimeException("Sample rates must be a multiple of the lowest sample rate to create a correct file!");
- }
- for (int i = 0; i < syncSamples.length; i++) {
- syncSamples[i] = (long) (1 + syncSamples[i] * factor / (double) samplesPerFrame);
- }
- getSampleNumbersCache.put(key, syncSamples);
- return syncSamples;
- }
- throw new RuntimeException("There was absolutely no Track with sync samples. I can't work with that!");
- } else {
- // Ok, my track has no sync samples - let's find one with sync samples.
- for (Track candidate : movie.getTracks()) {
- if (candidate.getSyncSamples() != null && candidate.getSyncSamples().length > 0) {
- long[] refSyncSamples = sampleNumbers(candidate, movie);
- int refSampleCount = candidate.getSamples().size();
-
- long[] syncSamples = new long[refSyncSamples.length];
- long sc = track.getSamples().size();
- double stretch = (double) sc / refSampleCount;
-
- for (int i = 0; i < syncSamples.length; i++) {
- long start = (long) Math.ceil(stretch * (refSyncSamples[i] - 1)) + 1;
- syncSamples[i] = start;
- // The Stretch makes sure that there are as much audio and video chunks!
- }
- getSampleNumbersCache.put(key, syncSamples);
- return syncSamples;
- }
- }
- throw new RuntimeException("There was absolutely no Track with sync samples. I can't work with that!");
- }
-
-
- }
-
- /**
- * Calculates the timestamp of all tracks' sync samples.
- *
- * @param movie
- * @param track
- * @return
- */
- public static List<long[]> getSyncSamplesTimestamps(Movie movie, Track track) {
- List<long[]> times = new LinkedList<long[]>();
- for (Track currentTrack : movie.getTracks()) {
- if (currentTrack.getHandler().equals(track.getHandler())) {
- long[] currentTrackSyncSamples = currentTrack.getSyncSamples();
- if (currentTrackSyncSamples != null && currentTrackSyncSamples.length > 0) {
- final long[] currentTrackTimes = getTimes(currentTrack, movie);
- times.add(currentTrackTimes);
- }
- }
- }
- return times;
- }
-
- public long[] getCommonIndices(long[] syncSamples, long[] syncSampleTimes, long timeScale, long[]... otherTracksTimes) {
- List<Long> nuSyncSamples = new LinkedList<Long>();
- List<Long> nuSyncSampleTimes = new LinkedList<Long>();
-
-
- for (int i = 0; i < syncSampleTimes.length; i++) {
- boolean foundInEveryRef = true;
- for (long[] times : otherTracksTimes) {
- foundInEveryRef &= (Arrays.binarySearch(times, syncSampleTimes[i]) >= 0);
- }
-
- if (foundInEveryRef) {
- // use sample only if found in every other track.
- nuSyncSamples.add(syncSamples[i]);
- nuSyncSampleTimes.add(syncSampleTimes[i]);
- }
- }
- // We have two arrays now:
- // nuSyncSamples: Contains all common sync samples
- // nuSyncSampleTimes: Contains the times of all sync samples
-
- // Start: Warn user if samples are not matching!
- if (nuSyncSamples.size() < (syncSamples.length * 0.25)) {
- String log = "";
- log += String.format("%5d - Common: [", nuSyncSamples.size());
- for (long l : nuSyncSamples) {
- log += (String.format("%10d,", l));
- }
- log += ("]");
- LOG.warning(log);
- log = "";
-
- log += String.format("%5d - In : [", syncSamples.length);
- for (long l : syncSamples) {
- log += (String.format("%10d,", l));
- }
- log += ("]");
- LOG.warning(log);
- LOG.warning("There are less than 25% of common sync samples in the given track.");
- throw new RuntimeException("There are less than 25% of common sync samples in the given track.");
- } else if (nuSyncSamples.size() < (syncSamples.length * 0.5)) {
- LOG.fine("There are less than 50% of common sync samples in the given track. This is implausible but I'm ok to continue.");
- } else if (nuSyncSamples.size() < syncSamples.length) {
- LOG.finest("Common SyncSample positions vs. this tracks SyncSample positions: " + nuSyncSamples.size() + " vs. " + syncSamples.length);
- }
- // End: Warn user if samples are not matching!
-
-
-
-
- List<Long> finalSampleList = new LinkedList<Long>();
-
- if (minFragmentDurationSeconds > 0) {
- // if minFragmentDurationSeconds is greater 0
- // we need to throw away certain samples.
- long lastSyncSampleTime = -1;
- Iterator<Long> nuSyncSamplesIterator = nuSyncSamples.iterator();
- Iterator<Long> nuSyncSampleTimesIterator = nuSyncSampleTimes.iterator();
- while (nuSyncSamplesIterator.hasNext() && nuSyncSampleTimesIterator.hasNext()) {
- long curSyncSample = nuSyncSamplesIterator.next();
- long curSyncSampleTime = nuSyncSampleTimesIterator.next();
- if (lastSyncSampleTime == -1 || (curSyncSampleTime - lastSyncSampleTime) / timeScale >= minFragmentDurationSeconds) {
- finalSampleList.add(curSyncSample);
- lastSyncSampleTime = curSyncSampleTime;
- }
- }
- } else {
- // the list of all samples is the final list of samples
- // since minFragmentDurationSeconds ist not used.
- finalSampleList = nuSyncSamples;
- }
-
-
- // transform the list to an array
- long[] finalSampleArray = new long[finalSampleList.size()];
- for (int i = 0; i < finalSampleArray.length; i++) {
- finalSampleArray[i] = finalSampleList.get(i);
- }
- return finalSampleArray;
-
- }
-
-
- private static long[] getTimes(Track track, Movie m) {
- final CacheTuple key = new CacheTuple(track, m);
- final long[] result = getTimesCache.get(key);
- if (result != null) {
- return result;
- }
-
- long[] syncSamples = track.getSyncSamples();
- long[] syncSampleTimes = new long[syncSamples.length];
- Queue<TimeToSampleBox.Entry> timeQueue = new LinkedList<TimeToSampleBox.Entry>(track.getDecodingTimeEntries());
-
- int currentSample = 1; // first syncsample is 1
- long currentDuration = 0;
- long currentDelta = 0;
- int currentSyncSampleIndex = 0;
- long left = 0;
-
- final long scalingFactor = calculateTracktimesScalingFactor(m, track);
-
- while (currentSample <= syncSamples[syncSamples.length - 1]) {
- if (currentSample++ == syncSamples[currentSyncSampleIndex]) {
- syncSampleTimes[currentSyncSampleIndex++] = currentDuration * scalingFactor;
- }
- if (left-- == 0) {
- TimeToSampleBox.Entry entry = timeQueue.poll();
- left = entry.getCount() - 1;
- currentDelta = entry.getDelta();
- }
- currentDuration += currentDelta;
- }
- getTimesCache.put(key, syncSampleTimes);
- return syncSampleTimes;
- }
-
- private static long calculateTracktimesScalingFactor(Movie m, Track track) {
- long timeScale = 1;
- for (Track track1 : m.getTracks()) {
- if (track1.getHandler().equals(track.getHandler())) {
- if (track1.getTrackMetaData().getTimescale() != track.getTrackMetaData().getTimescale()) {
- timeScale = lcm(timeScale, track1.getTrackMetaData().getTimescale());
- }
- }
- }
- return timeScale;
- }
-
- public static class CacheTuple {
- Track track;
- Movie movie;
-
- public CacheTuple(Track track, Movie movie) {
- this.track = track;
- this.movie = movie;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- CacheTuple that = (CacheTuple) o;
-
- if (movie != null ? !movie.equals(that.movie) : that.movie != null) return false;
- if (track != null ? !track.equals(that.track) : that.track != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = track != null ? track.hashCode() : 0;
- result = 31 * result + (movie != null ? movie.hashCode() : 0);
- return result;
- }
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/TwoSecondIntersectionFinder.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/TwoSecondIntersectionFinder.java.svn-base
deleted file mode 100644
index 88aa4ab..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/builder/.svn/text-base/TwoSecondIntersectionFinder.java.svn-base
+++ /dev/null
@@ -1,86 +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.builder;
-
-import com.coremedia.iso.boxes.TimeToSampleBox;
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Track;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * This <code>FragmentIntersectionFinder</code> cuts the input movie in 2 second
- * snippets.
- */
-public class TwoSecondIntersectionFinder implements FragmentIntersectionFinder {
-
- protected long getDuration(Track track) {
- long duration = 0;
- for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {
- duration += entry.getCount() * entry.getDelta();
- }
- return duration;
- }
-
- /**
- * {@inheritDoc}
- */
- public long[] sampleNumbers(Track track, Movie movie) {
- List<TimeToSampleBox.Entry> entries = track.getDecodingTimeEntries();
-
- double trackLength = 0;
- for (Track thisTrack : movie.getTracks()) {
- double thisTracksLength = getDuration(thisTrack) / thisTrack.getTrackMetaData().getTimescale();
- if (trackLength < thisTracksLength) {
- trackLength = thisTracksLength;
- }
- }
-
- int fragmentCount = (int)Math.ceil(trackLength / 2) - 1;
- if (fragmentCount < 1) {
- fragmentCount = 1;
- }
-
- long fragments[] = new long[fragmentCount];
- Arrays.fill(fragments, -1);
- fragments[0] = 1;
-
- long time = 0;
- int samples = 0;
- for (TimeToSampleBox.Entry entry : entries) {
- for (int i = 0; i < entry.getCount(); i++) {
- int currentFragment = (int) (time / track.getTrackMetaData().getTimescale() / 2) + 1;
- if (currentFragment >= fragments.length) {
- break;
- }
- fragments[currentFragment] = samples++ + 1;
- time += entry.getDelta();
- }
- }
- long last = samples + 1;
- // fill all -1 ones.
- for (int i = fragments.length - 1; i >= 0; i--) {
- if (fragments[i] == -1) {
- fragments[i] = last ;
- }
- last = fragments[i];
- }
- return fragments;
-
- }
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/.svn/all-wcprops
deleted file mode 100644
index a7245be..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/.svn/all-wcprops
+++ /dev/null
@@ -1,5 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 92
-/svn/!svn/ver/418/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container
-END
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/.svn/entries
deleted file mode 100644
index bde4d0e..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/.svn/entries
+++ /dev/null
@@ -1,31 +0,0 @@
-10
-
-dir
-778
-http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container
-http://mp4parser.googlecode.com/svn
-
-
-
-2012-03-11T20:54:45.638478Z
-418
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7decde4b-c250-0410-a0da-51896bc88be6
-
-mp4
-dir
-
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/all-wcprops
deleted file mode 100644
index ec2a4f9..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/all-wcprops
+++ /dev/null
@@ -1,11 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 96
-/svn/!svn/ver/418/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4
-END
-MovieCreator.java
-K 25
-svn:wc:ra_dav:version-url
-V 114
-/svn/!svn/ver/418/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/MovieCreator.java
-END
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/entries
deleted file mode 100644
index d7d7f30..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/entries
+++ /dev/null
@@ -1,62 +0,0 @@
-10
-
-dir
-778
-http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4
-http://mp4parser.googlecode.com/svn
-
-
-
-2012-03-11T20:54:45.638478Z
-418
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7decde4b-c250-0410-a0da-51896bc88be6
-
-MovieCreator.java
-file
-
-
-
-
-2012-09-14T17:27:49.987212Z
-ecb22de8d79473683de67e40f494641d
-2012-03-11T20:54:45.638478Z
-418
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-1404
-
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/text-base/MovieCreator.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/text-base/MovieCreator.java.svn-base
deleted file mode 100644
index ed9d15f..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/container/mp4/.svn/text-base/MovieCreator.java.svn-base
+++ /dev/null
@@ -1,40 +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.container.mp4;
-
-import com.coremedia.iso.IsoFile;
-import com.coremedia.iso.boxes.TrackBox;
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Mp4TrackImpl;
-
-import java.io.IOException;
-import java.nio.channels.ReadableByteChannel;
-import java.util.List;
-
-/**
- * Shortcut to build a movie from an MP4 file.
- */
-public class MovieCreator {
- public static Movie build(ReadableByteChannel channel) throws IOException {
- IsoFile isoFile = new IsoFile(channel);
- Movie m = new Movie();
- List<TrackBox> trackBoxes = isoFile.getMovieBox().getBoxes(TrackBox.class);
- for (TrackBox trackBox : trackBoxes) {
- m.addTrack(new Mp4TrackImpl(trackBox));
- }
- return m;
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/all-wcprops b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/all-wcprops
deleted file mode 100644
index 496d7bb..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/all-wcprops
+++ /dev/null
@@ -1,89 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 89
-/svn/!svn/ver/756/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks
-END
-DivideTimeScaleTrack.java
-K 25
-svn:wc:ra_dav:version-url
-V 115
-/svn/!svn/ver/686/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/DivideTimeScaleTrack.java
-END
-CroppedTrack.java
-K 25
-svn:wc:ra_dav:version-url
-V 107
-/svn/!svn/ver/686/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/CroppedTrack.java
-END
-ChangeTimeScaleTrack.java
-K 25
-svn:wc:ra_dav:version-url
-V 115
-/svn/!svn/ver/686/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/ChangeTimeScaleTrack.java
-END
-EC3TrackImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 107
-/svn/!svn/ver/756/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/EC3TrackImpl.java
-END
-ReplaceSampleTrack.java
-K 25
-svn:wc:ra_dav:version-url
-V 113
-/svn/!svn/ver/686/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/ReplaceSampleTrack.java
-END
-QuicktimeTextTrackImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 117
-/svn/!svn/ver/691/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/QuicktimeTextTrackImpl.java
-END
-Amf0Track.java
-K 25
-svn:wc:ra_dav:version-url
-V 104
-/svn/!svn/ver/686/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/Amf0Track.java
-END
-SilenceTrackImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 111
-/svn/!svn/ver/698/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/SilenceTrackImpl.java
-END
-H264TrackImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 108
-/svn/!svn/ver/756/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/H264TrackImpl.java
-END
-TextTrackImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 108
-/svn/!svn/ver/684/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/TextTrackImpl.java
-END
-AACTrackImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 107
-/svn/!svn/ver/756/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/AACTrackImpl.java
-END
-MultiplyTimeScaleTrack.java
-K 25
-svn:wc:ra_dav:version-url
-V 117
-/svn/!svn/ver/686/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/MultiplyTimeScaleTrack.java
-END
-AppendTrack.java
-K 25
-svn:wc:ra_dav:version-url
-V 106
-/svn/!svn/ver/714/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/AppendTrack.java
-END
-AC3TrackImpl.java
-K 25
-svn:wc:ra_dav:version-url
-V 107
-/svn/!svn/ver/756/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/AC3TrackImpl.java
-END
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/entries b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/entries
deleted file mode 100644
index dbe8ae3..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/entries
+++ /dev/null
@@ -1,504 +0,0 @@
-10
-
-dir
-778
-http://mp4parser.googlecode.com/svn/trunk/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks
-http://mp4parser.googlecode.com/svn
-
-
-
-2012-08-17T01:19:11.953078Z
-756
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7decde4b-c250-0410-a0da-51896bc88be6
-
-DivideTimeScaleTrack.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-6aa41cdb7489e16e879ddebd68b7ac52
-2012-06-24T19:52:05.961412Z
-686
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3893
-
-CroppedTrack.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-5d9c65d9aac52a26372aa3fdf6f1b7ea
-2012-06-24T19:52:05.961412Z
-686
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-6025
-
-ChangeTimeScaleTrack.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-ba01d30ac4b7c4fa9a2c6538ee537594
-2012-06-24T19:52:05.961412Z
-686
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-7152
-
-EC3TrackImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-1d568bfaa0f41c3771986a7790347072
-2012-08-17T01:19:11.953078Z
-756
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-13623
-
-ReplaceSampleTrack.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-f6846b7a262ab0e530da46f4d7e34850
-2012-06-24T19:52:05.961412Z
-686
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3139
-
-QuicktimeTextTrackImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-7ccd01a58545fb02b507b57892eb53e5
-2012-06-24T21:35:59.546504Z
-691
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-5128
-
-Amf0Track.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-4718a34bc271adf4517de9829ac74a9d
-2012-06-24T19:52:05.961412Z
-686
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-3858
-
-SilenceTrackImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-a897677e602dfa0d64af1b0d33a04ca8
-2012-06-26T08:37:32.910396Z
-698
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-2623
-
-H264TrackImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-76abb4b21c13d11215a2ac4cb0c7e461
-2012-08-17T01:19:11.953078Z
-756
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-28816
-
-TextTrackImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-5a643c876754eb5c7bcf75b4b71114a1
-2012-06-24T14:45:45.932648Z
-684
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4963
-
-AACTrackImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-ece8d364a9a5aeabf6a281f6d428e3cf
-2012-08-17T01:19:11.953078Z
-756
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-10097
-
-MultiplyTimeScaleTrack.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-b0ea53239c124607a26a181f594f82a1
-2012-06-24T19:52:05.961412Z
-686
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4192
-
-AppendTrack.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-e7814aebc4500724771fd0582455a7ca
-2012-07-18T23:22:45.506793Z
-714
-Sebastian.Annies@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-15783
-
-AC3TrackImpl.java
-file
-
-
-
-
-2012-09-14T17:27:50.507219Z
-fbd724739cd9a5f2b28f16b412b27309
-2012-08-17T01:19:11.953078Z
-756
-michael.stattmann@gmail.com
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-19303
-
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AACTrackImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AACTrackImpl.java.svn-base
deleted file mode 100644
index df51a1a..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AACTrackImpl.java.svn-base
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright 2012 castLabs GmbH, Berlin
- *
- * 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.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.AC3SpecificBox;
-import com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox;
-import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.*;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.*;
-
-/**
- */
-public class AACTrackImpl extends AbstractTrack {
- public static Map<Integer, Integer> samplingFrequencyIndexMap = new HashMap<Integer, Integer>();
-
- static {
- samplingFrequencyIndexMap.put(96000, 0);
- samplingFrequencyIndexMap.put(88200, 1);
- samplingFrequencyIndexMap.put(64000, 2);
- samplingFrequencyIndexMap.put(48000, 3);
- samplingFrequencyIndexMap.put(44100, 4);
- samplingFrequencyIndexMap.put(32000, 5);
- samplingFrequencyIndexMap.put(24000, 6);
- samplingFrequencyIndexMap.put(22050, 7);
- samplingFrequencyIndexMap.put(16000, 8);
- samplingFrequencyIndexMap.put(12000, 9);
- samplingFrequencyIndexMap.put(11025, 10);
- samplingFrequencyIndexMap.put(8000, 11);
- samplingFrequencyIndexMap.put(0x0, 96000);
- samplingFrequencyIndexMap.put(0x1, 88200);
- samplingFrequencyIndexMap.put(0x2, 64000);
- samplingFrequencyIndexMap.put(0x3, 48000);
- samplingFrequencyIndexMap.put(0x4, 44100);
- samplingFrequencyIndexMap.put(0x5, 32000);
- samplingFrequencyIndexMap.put(0x6, 24000);
- samplingFrequencyIndexMap.put(0x7, 22050);
- samplingFrequencyIndexMap.put(0x8, 16000);
- samplingFrequencyIndexMap.put(0x9, 12000);
- samplingFrequencyIndexMap.put(0xa, 11025);
- samplingFrequencyIndexMap.put(0xb, 8000);
- }
-
- TrackMetaData trackMetaData = new TrackMetaData();
- SampleDescriptionBox sampleDescriptionBox;
-
- int samplerate;
- int bitrate;
- int channelCount;
- int channelconfig;
-
- int bufferSizeDB;
- long maxBitRate;
- long avgBitRate;
-
- private BufferedInputStream inputStream;
- private List<ByteBuffer> samples;
- boolean readSamples = false;
- List<TimeToSampleBox.Entry> stts;
- private String lang = "und";
-
-
- public AACTrackImpl(InputStream inputStream, String lang) throws IOException {
- this.lang = lang;
- parse(inputStream);
- }
-
- public AACTrackImpl(InputStream inputStream) throws IOException {
- parse(inputStream);
- }
-
- private void parse(InputStream inputStream) throws IOException {
- 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
- }
-
- 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 List<ByteBuffer> getSamples() {
- return samples;
- }
-
- public Box getMediaHeaderBox() {
- return new SoundMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return null;
- }
-
- private boolean readVariables() throws IOException {
- 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;
- }
-
- private boolean readSamples() throws IOException {
- 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;
- }
-
- @Override
- public String toString() {
- return "AACTrackImpl{" +
- "samplerate=" + samplerate +
- ", bitrate=" + bitrate +
- ", channelCount=" + channelCount +
- ", channelconfig=" + channelconfig +
- '}';
- }
-}
-
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AC3TrackImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AC3TrackImpl.java.svn-base
deleted file mode 100644
index 5e5b2cd..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AC3TrackImpl.java.svn-base
+++ /dev/null
@@ -1,513 +0,0 @@
-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.AC3SpecificBox;
-import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.BitReaderBuffer;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-public class AC3TrackImpl extends AbstractTrack {
- TrackMetaData trackMetaData = new TrackMetaData();
- SampleDescriptionBox sampleDescriptionBox;
-
- int samplerate;
- int bitrate;
- int channelCount;
-
- int fscod;
- int bsid;
- int bsmod;
- int acmod;
- int lfeon;
- int frmsizecod;
-
- int frameSize;
- int[][][][] bitRateAndFrameSizeTable;
-
- private InputStream inputStream;
- private List<ByteBuffer> samples;
- boolean readSamples = false;
- List<TimeToSampleBox.Entry> stts;
- private String lang = "und";
-
- public AC3TrackImpl(InputStream fin, String lang) throws IOException {
- this.lang = lang;
- parse(fin);
- }
-
- public AC3TrackImpl(InputStream fin) throws IOException {
- parse(fin);
- }
-
- private void parse(InputStream fin) throws IOException {
- inputStream = fin;
- bitRateAndFrameSizeTable = new int[19][2][3][2];
- stts = new LinkedList<TimeToSampleBox.Entry>();
- initBitRateAndFrameSizeTable();
- if (!readVariables()) {
- throw new IOException();
- }
-
- sampleDescriptionBox = new SampleDescriptionBox();
- AudioSampleEntry audioSampleEntry = new AudioSampleEntry("ac-3");
- audioSampleEntry.setChannelCount(2); // According to ETSI TS 102 366 Annex F
- audioSampleEntry.setSampleRate(samplerate);
- audioSampleEntry.setDataReferenceIndex(1);
- audioSampleEntry.setSampleSize(16);
-
- AC3SpecificBox ac3 = new AC3SpecificBox();
- ac3.setAcmod(acmod);
- ac3.setBitRateCode(frmsizecod >> 1);
- ac3.setBsid(bsid);
- ac3.setBsmod(bsmod);
- ac3.setFscod(fscod);
- ac3.setLfeon(lfeon);
- ac3.setReserved(0);
-
- audioSampleEntry.addBox(ac3);
- 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 Box getMediaHeaderBox() {
- return new SoundMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return null;
- }
-
- private boolean readVariables() throws IOException {
- 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(16);
- if (syncword != 0xb77) {
- return false;
- }
- brb.readBits(16); // CRC-1
- fscod = brb.readBits(2);
-
- switch (fscod) {
- case 0:
- samplerate = 48000;
- break;
-
- case 1:
- samplerate = 44100;
- break;
-
- case 2:
- samplerate = 32000;
- break;
-
- case 3:
- samplerate = 0;
- break;
-
- }
- if (samplerate == 0) {
- return false;
- }
-
- frmsizecod = brb.readBits(6);
-
- if (!calcBitrateAndFrameSize(frmsizecod)) {
- return false;
- }
-
- if (frameSize == 0) {
- return false;
- }
- bsid = brb.readBits(5);
- bsmod = brb.readBits(3);
- acmod = brb.readBits(3);
-
- if (bsid == 9) {
- samplerate /= 2;
- } else if (bsid != 8 && bsid != 6) {
- return false;
- }
-
- if ((acmod != 1) && ((acmod & 1) == 1)) {
- brb.readBits(2);
- }
-
- if (0 != (acmod & 4)) {
- brb.readBits(2);
- }
-
- if (acmod == 2) {
- brb.readBits(2);
- }
-
- switch (acmod) {
- case 0:
- channelCount = 2;
- break;
-
- case 1:
- channelCount = 1;
- break;
-
- case 2:
- channelCount = 2;
- break;
-
- case 3:
- channelCount = 3;
- break;
-
- case 4:
- channelCount = 3;
- break;
-
- case 5:
- channelCount = 4;
- break;
-
- case 6:
- channelCount = 4;
- break;
-
- case 7:
- channelCount = 5;
- break;
-
- }
-
- lfeon = brb.readBits(1);
-
- if (lfeon == 1) {
- channelCount++;
- }
- return true;
- }
-
- private boolean calcBitrateAndFrameSize(int code) {
- int frmsizecode = code >>> 1;
- int flag = code & 1;
- if (frmsizecode > 18 || flag > 1 || fscod > 2) {
- return false;
- }
- bitrate = bitRateAndFrameSizeTable[frmsizecode][flag][fscod][0];
- frameSize = 2 * bitRateAndFrameSizeTable[frmsizecode][flag][fscod][1];
- return true;
- }
-
- private boolean readSamples() throws IOException {
- if (readSamples) {
- return true;
- }
- readSamples = true;
- byte[] header = new byte[5];
- boolean ret = false;
- inputStream.mark(5);
- while (-1 != inputStream.read(header)) {
- ret = true;
- int frmsizecode = header[4] & 63;
- calcBitrateAndFrameSize(frmsizecode);
- inputStream.reset();
- byte[] data = new byte[frameSize];
- inputStream.read(data);
- samples.add(ByteBuffer.wrap(data));
- stts.add(new TimeToSampleBox.Entry(1, 1536));
- inputStream.mark(5);
- }
- return ret;
- }
-
- private void initBitRateAndFrameSizeTable() {
- // ETSI 102 366 Table 4.13, in frmsizecod, flag, fscod, bitrate/size order. Note that all sizes are in words, and all bitrates in kbps
-
- // 48kHz
- bitRateAndFrameSizeTable[0][0][0][0] = 32;
- bitRateAndFrameSizeTable[0][1][0][0] = 32;
- bitRateAndFrameSizeTable[0][0][0][1] = 64;
- bitRateAndFrameSizeTable[0][1][0][1] = 64;
- bitRateAndFrameSizeTable[1][0][0][0] = 40;
- bitRateAndFrameSizeTable[1][1][0][0] = 40;
- bitRateAndFrameSizeTable[1][0][0][1] = 80;
- bitRateAndFrameSizeTable[1][1][0][1] = 80;
- bitRateAndFrameSizeTable[2][0][0][0] = 48;
- bitRateAndFrameSizeTable[2][1][0][0] = 48;
- bitRateAndFrameSizeTable[2][0][0][1] = 96;
- bitRateAndFrameSizeTable[2][1][0][1] = 96;
- bitRateAndFrameSizeTable[3][0][0][0] = 56;
- bitRateAndFrameSizeTable[3][1][0][0] = 56;
- bitRateAndFrameSizeTable[3][0][0][1] = 112;
- bitRateAndFrameSizeTable[3][1][0][1] = 112;
- bitRateAndFrameSizeTable[4][0][0][0] = 64;
- bitRateAndFrameSizeTable[4][1][0][0] = 64;
- bitRateAndFrameSizeTable[4][0][0][1] = 128;
- bitRateAndFrameSizeTable[4][1][0][1] = 128;
- bitRateAndFrameSizeTable[5][0][0][0] = 80;
- bitRateAndFrameSizeTable[5][1][0][0] = 80;
- bitRateAndFrameSizeTable[5][0][0][1] = 160;
- bitRateAndFrameSizeTable[5][1][0][1] = 160;
- bitRateAndFrameSizeTable[6][0][0][0] = 96;
- bitRateAndFrameSizeTable[6][1][0][0] = 96;
- bitRateAndFrameSizeTable[6][0][0][1] = 192;
- bitRateAndFrameSizeTable[6][1][0][1] = 192;
- bitRateAndFrameSizeTable[7][0][0][0] = 112;
- bitRateAndFrameSizeTable[7][1][0][0] = 112;
- bitRateAndFrameSizeTable[7][0][0][1] = 224;
- bitRateAndFrameSizeTable[7][1][0][1] = 224;
- bitRateAndFrameSizeTable[8][0][0][0] = 128;
- bitRateAndFrameSizeTable[8][1][0][0] = 128;
- bitRateAndFrameSizeTable[8][0][0][1] = 256;
- bitRateAndFrameSizeTable[8][1][0][1] = 256;
- bitRateAndFrameSizeTable[9][0][0][0] = 160;
- bitRateAndFrameSizeTable[9][1][0][0] = 160;
- bitRateAndFrameSizeTable[9][0][0][1] = 320;
- bitRateAndFrameSizeTable[9][1][0][1] = 320;
- bitRateAndFrameSizeTable[10][0][0][0] = 192;
- bitRateAndFrameSizeTable[10][1][0][0] = 192;
- bitRateAndFrameSizeTable[10][0][0][1] = 384;
- bitRateAndFrameSizeTable[10][1][0][1] = 384;
- bitRateAndFrameSizeTable[11][0][0][0] = 224;
- bitRateAndFrameSizeTable[11][1][0][0] = 224;
- bitRateAndFrameSizeTable[11][0][0][1] = 448;
- bitRateAndFrameSizeTable[11][1][0][1] = 448;
- bitRateAndFrameSizeTable[12][0][0][0] = 256;
- bitRateAndFrameSizeTable[12][1][0][0] = 256;
- bitRateAndFrameSizeTable[12][0][0][1] = 512;
- bitRateAndFrameSizeTable[12][1][0][1] = 512;
- bitRateAndFrameSizeTable[13][0][0][0] = 320;
- bitRateAndFrameSizeTable[13][1][0][0] = 320;
- bitRateAndFrameSizeTable[13][0][0][1] = 640;
- bitRateAndFrameSizeTable[13][1][0][1] = 640;
- bitRateAndFrameSizeTable[14][0][0][0] = 384;
- bitRateAndFrameSizeTable[14][1][0][0] = 384;
- bitRateAndFrameSizeTable[14][0][0][1] = 768;
- bitRateAndFrameSizeTable[14][1][0][1] = 768;
- bitRateAndFrameSizeTable[15][0][0][0] = 448;
- bitRateAndFrameSizeTable[15][1][0][0] = 448;
- bitRateAndFrameSizeTable[15][0][0][1] = 896;
- bitRateAndFrameSizeTable[15][1][0][1] = 896;
- bitRateAndFrameSizeTable[16][0][0][0] = 512;
- bitRateAndFrameSizeTable[16][1][0][0] = 512;
- bitRateAndFrameSizeTable[16][0][0][1] = 1024;
- bitRateAndFrameSizeTable[16][1][0][1] = 1024;
- bitRateAndFrameSizeTable[17][0][0][0] = 576;
- bitRateAndFrameSizeTable[17][1][0][0] = 576;
- bitRateAndFrameSizeTable[17][0][0][1] = 1152;
- bitRateAndFrameSizeTable[17][1][0][1] = 1152;
- bitRateAndFrameSizeTable[18][0][0][0] = 640;
- bitRateAndFrameSizeTable[18][1][0][0] = 640;
- bitRateAndFrameSizeTable[18][0][0][1] = 1280;
- bitRateAndFrameSizeTable[18][1][0][1] = 1280;
-
- // 44.1 kHz
- bitRateAndFrameSizeTable[0][0][1][0] = 32;
- bitRateAndFrameSizeTable[0][1][1][0] = 32;
- bitRateAndFrameSizeTable[0][0][1][1] = 69;
- bitRateAndFrameSizeTable[0][1][1][1] = 70;
- bitRateAndFrameSizeTable[1][0][1][0] = 40;
- bitRateAndFrameSizeTable[1][1][1][0] = 40;
- bitRateAndFrameSizeTable[1][0][1][1] = 87;
- bitRateAndFrameSizeTable[1][1][1][1] = 88;
- bitRateAndFrameSizeTable[2][0][1][0] = 48;
- bitRateAndFrameSizeTable[2][1][1][0] = 48;
- bitRateAndFrameSizeTable[2][0][1][1] = 104;
- bitRateAndFrameSizeTable[2][1][1][1] = 105;
- bitRateAndFrameSizeTable[3][0][1][0] = 56;
- bitRateAndFrameSizeTable[3][1][1][0] = 56;
- bitRateAndFrameSizeTable[3][0][1][1] = 121;
- bitRateAndFrameSizeTable[3][1][1][1] = 122;
- bitRateAndFrameSizeTable[4][0][1][0] = 64;
- bitRateAndFrameSizeTable[4][1][1][0] = 64;
- bitRateAndFrameSizeTable[4][0][1][1] = 139;
- bitRateAndFrameSizeTable[4][1][1][1] = 140;
- bitRateAndFrameSizeTable[5][0][1][0] = 80;
- bitRateAndFrameSizeTable[5][1][1][0] = 80;
- bitRateAndFrameSizeTable[5][0][1][1] = 174;
- bitRateAndFrameSizeTable[5][1][1][1] = 175;
- bitRateAndFrameSizeTable[6][0][1][0] = 96;
- bitRateAndFrameSizeTable[6][1][1][0] = 96;
- bitRateAndFrameSizeTable[6][0][1][1] = 208;
- bitRateAndFrameSizeTable[6][1][1][1] = 209;
- bitRateAndFrameSizeTable[7][0][1][0] = 112;
- bitRateAndFrameSizeTable[7][1][1][0] = 112;
- bitRateAndFrameSizeTable[7][0][1][1] = 243;
- bitRateAndFrameSizeTable[7][1][1][1] = 244;
- bitRateAndFrameSizeTable[8][0][1][0] = 128;
- bitRateAndFrameSizeTable[8][1][1][0] = 128;
- bitRateAndFrameSizeTable[8][0][1][1] = 278;
- bitRateAndFrameSizeTable[8][1][1][1] = 279;
- bitRateAndFrameSizeTable[9][0][1][0] = 160;
- bitRateAndFrameSizeTable[9][1][1][0] = 160;
- bitRateAndFrameSizeTable[9][0][1][1] = 348;
- bitRateAndFrameSizeTable[9][1][1][1] = 349;
- bitRateAndFrameSizeTable[10][0][1][0] = 192;
- bitRateAndFrameSizeTable[10][1][1][0] = 192;
- bitRateAndFrameSizeTable[10][0][1][1] = 417;
- bitRateAndFrameSizeTable[10][1][1][1] = 418;
- bitRateAndFrameSizeTable[11][0][1][0] = 224;
- bitRateAndFrameSizeTable[11][1][1][0] = 224;
- bitRateAndFrameSizeTable[11][0][1][1] = 487;
- bitRateAndFrameSizeTable[11][1][1][1] = 488;
- bitRateAndFrameSizeTable[12][0][1][0] = 256;
- bitRateAndFrameSizeTable[12][1][1][0] = 256;
- bitRateAndFrameSizeTable[12][0][1][1] = 557;
- bitRateAndFrameSizeTable[12][1][1][1] = 558;
- bitRateAndFrameSizeTable[13][0][1][0] = 320;
- bitRateAndFrameSizeTable[13][1][1][0] = 320;
- bitRateAndFrameSizeTable[13][0][1][1] = 696;
- bitRateAndFrameSizeTable[13][1][1][1] = 697;
- bitRateAndFrameSizeTable[14][0][1][0] = 384;
- bitRateAndFrameSizeTable[14][1][1][0] = 384;
- bitRateAndFrameSizeTable[14][0][1][1] = 835;
- bitRateAndFrameSizeTable[14][1][1][1] = 836;
- bitRateAndFrameSizeTable[15][0][1][0] = 448;
- bitRateAndFrameSizeTable[15][1][1][0] = 448;
- bitRateAndFrameSizeTable[15][0][1][1] = 975;
- bitRateAndFrameSizeTable[15][1][1][1] = 975;
- bitRateAndFrameSizeTable[16][0][1][0] = 512;
- bitRateAndFrameSizeTable[16][1][1][0] = 512;
- bitRateAndFrameSizeTable[16][0][1][1] = 1114;
- bitRateAndFrameSizeTable[16][1][1][1] = 1115;
- bitRateAndFrameSizeTable[17][0][1][0] = 576;
- bitRateAndFrameSizeTable[17][1][1][0] = 576;
- bitRateAndFrameSizeTable[17][0][1][1] = 1253;
- bitRateAndFrameSizeTable[17][1][1][1] = 1254;
- bitRateAndFrameSizeTable[18][0][1][0] = 640;
- bitRateAndFrameSizeTable[18][1][1][0] = 640;
- bitRateAndFrameSizeTable[18][0][1][1] = 1393;
- bitRateAndFrameSizeTable[18][1][1][1] = 1394;
-
- // 32kHz
- bitRateAndFrameSizeTable[0][0][2][0] = 32;
- bitRateAndFrameSizeTable[0][1][2][0] = 32;
- bitRateAndFrameSizeTable[0][0][2][1] = 96;
- bitRateAndFrameSizeTable[0][1][2][1] = 96;
- bitRateAndFrameSizeTable[1][0][2][0] = 40;
- bitRateAndFrameSizeTable[1][1][2][0] = 40;
- bitRateAndFrameSizeTable[1][0][2][1] = 120;
- bitRateAndFrameSizeTable[1][1][2][1] = 120;
- bitRateAndFrameSizeTable[2][0][2][0] = 48;
- bitRateAndFrameSizeTable[2][1][2][0] = 48;
- bitRateAndFrameSizeTable[2][0][2][1] = 144;
- bitRateAndFrameSizeTable[2][1][2][1] = 144;
- bitRateAndFrameSizeTable[3][0][2][0] = 56;
- bitRateAndFrameSizeTable[3][1][2][0] = 56;
- bitRateAndFrameSizeTable[3][0][2][1] = 168;
- bitRateAndFrameSizeTable[3][1][2][1] = 168;
- bitRateAndFrameSizeTable[4][0][2][0] = 64;
- bitRateAndFrameSizeTable[4][1][2][0] = 64;
- bitRateAndFrameSizeTable[4][0][2][1] = 192;
- bitRateAndFrameSizeTable[4][1][2][1] = 192;
- bitRateAndFrameSizeTable[5][0][2][0] = 80;
- bitRateAndFrameSizeTable[5][1][2][0] = 80;
- bitRateAndFrameSizeTable[5][0][2][1] = 240;
- bitRateAndFrameSizeTable[5][1][2][1] = 240;
- bitRateAndFrameSizeTable[6][0][2][0] = 96;
- bitRateAndFrameSizeTable[6][1][2][0] = 96;
- bitRateAndFrameSizeTable[6][0][2][1] = 288;
- bitRateAndFrameSizeTable[6][1][2][1] = 288;
- bitRateAndFrameSizeTable[7][0][2][0] = 112;
- bitRateAndFrameSizeTable[7][1][2][0] = 112;
- bitRateAndFrameSizeTable[7][0][2][1] = 336;
- bitRateAndFrameSizeTable[7][1][2][1] = 336;
- bitRateAndFrameSizeTable[8][0][2][0] = 128;
- bitRateAndFrameSizeTable[8][1][2][0] = 128;
- bitRateAndFrameSizeTable[8][0][2][1] = 384;
- bitRateAndFrameSizeTable[8][1][2][1] = 384;
- bitRateAndFrameSizeTable[9][0][2][0] = 160;
- bitRateAndFrameSizeTable[9][1][2][0] = 160;
- bitRateAndFrameSizeTable[9][0][2][1] = 480;
- bitRateAndFrameSizeTable[9][1][2][1] = 480;
- bitRateAndFrameSizeTable[10][0][2][0] = 192;
- bitRateAndFrameSizeTable[10][1][2][0] = 192;
- bitRateAndFrameSizeTable[10][0][2][1] = 576;
- bitRateAndFrameSizeTable[10][1][2][1] = 576;
- bitRateAndFrameSizeTable[11][0][2][0] = 224;
- bitRateAndFrameSizeTable[11][1][2][0] = 224;
- bitRateAndFrameSizeTable[11][0][2][1] = 672;
- bitRateAndFrameSizeTable[11][1][2][1] = 672;
- bitRateAndFrameSizeTable[12][0][2][0] = 256;
- bitRateAndFrameSizeTable[12][1][2][0] = 256;
- bitRateAndFrameSizeTable[12][0][2][1] = 768;
- bitRateAndFrameSizeTable[12][1][2][1] = 768;
- bitRateAndFrameSizeTable[13][0][2][0] = 320;
- bitRateAndFrameSizeTable[13][1][2][0] = 320;
- bitRateAndFrameSizeTable[13][0][2][1] = 960;
- bitRateAndFrameSizeTable[13][1][2][1] = 960;
- bitRateAndFrameSizeTable[14][0][2][0] = 384;
- bitRateAndFrameSizeTable[14][1][2][0] = 384;
- bitRateAndFrameSizeTable[14][0][2][1] = 1152;
- bitRateAndFrameSizeTable[14][1][2][1] = 1152;
- bitRateAndFrameSizeTable[15][0][2][0] = 448;
- bitRateAndFrameSizeTable[15][1][2][0] = 448;
- bitRateAndFrameSizeTable[15][0][2][1] = 1344;
- bitRateAndFrameSizeTable[15][1][2][1] = 1344;
- bitRateAndFrameSizeTable[16][0][2][0] = 512;
- bitRateAndFrameSizeTable[16][1][2][0] = 512;
- bitRateAndFrameSizeTable[16][0][2][1] = 1536;
- bitRateAndFrameSizeTable[16][1][2][1] = 1536;
- bitRateAndFrameSizeTable[17][0][2][0] = 576;
- bitRateAndFrameSizeTable[17][1][2][0] = 576;
- bitRateAndFrameSizeTable[17][0][2][1] = 1728;
- bitRateAndFrameSizeTable[17][1][2][1] = 1728;
- bitRateAndFrameSizeTable[18][0][2][0] = 640;
- bitRateAndFrameSizeTable[18][1][2][0] = 640;
- bitRateAndFrameSizeTable[18][0][2][1] = 1920;
- bitRateAndFrameSizeTable[18][1][2][1] = 1920;
- }
-} \ No newline at end of file
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/Amf0Track.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/Amf0Track.java.svn-base
deleted file mode 100644
index 0917767..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/Amf0Track.java.svn-base
+++ /dev/null
@@ -1,116 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.googlecode.mp4parser.authoring.AbstractTrack;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-import com.googlecode.mp4parser.boxes.adobe.ActionMessageFormat0SampleEntryBox;
-
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-public class Amf0Track extends AbstractTrack {
- SortedMap<Long, byte[]> rawSamples = new TreeMap<Long, byte[]>() {
- };
- private TrackMetaData trackMetaData = new TrackMetaData();
-
-
- /**
- * Creates a new AMF0 track from
- *
- * @param rawSamples
- */
- public Amf0Track(Map<Long, byte[]> rawSamples) {
- this.rawSamples = new TreeMap<Long, byte[]>(rawSamples);
- trackMetaData.setCreationTime(new Date());
- trackMetaData.setModificationTime(new Date());
- trackMetaData.setTimescale(1000); // Text tracks use millieseconds
- trackMetaData.setLanguage("eng");
- }
-
- public List<ByteBuffer> getSamples() {
- LinkedList<ByteBuffer> samples = new LinkedList<ByteBuffer>();
- for (byte[] bytes : rawSamples.values()) {
- samples.add(ByteBuffer.wrap(bytes));
- }
- return samples;
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- SampleDescriptionBox stsd = new SampleDescriptionBox();
- ActionMessageFormat0SampleEntryBox amf0 = new ActionMessageFormat0SampleEntryBox();
- amf0.setDataReferenceIndex(1);
- stsd.addBox(amf0);
- return stsd;
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- LinkedList<TimeToSampleBox.Entry> timesToSample = new LinkedList<TimeToSampleBox.Entry>();
- LinkedList<Long> keys = new LinkedList<Long>(rawSamples.keySet());
- Collections.sort(keys);
- long lastTimeStamp = 0;
- for (Long key : keys) {
- long delta = key - lastTimeStamp;
- if (timesToSample.size() > 0 && timesToSample.peek().getDelta() == delta) {
- timesToSample.peek().setCount(timesToSample.peek().getCount() + 1);
- } else {
- timesToSample.add(new TimeToSampleBox.Entry(1, delta));
- }
- lastTimeStamp = key;
- }
- return timesToSample;
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- // AMF0 tracks do not have Composition Time
- return null;
- }
-
- public long[] getSyncSamples() {
- // AMF0 tracks do not have Sync Samples
- return null;
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- // AMF0 tracks do not have Sample Dependencies
- return null;
- }
-
- public TrackMetaData getTrackMetaData() {
- return trackMetaData; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public String getHandler() {
- return "data";
- }
-
- public Box getMediaHeaderBox() {
- return new NullMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return null;
- }
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AppendTrack.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AppendTrack.java.svn-base
deleted file mode 100644
index 93ee0cd..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/AppendTrack.java.svn-base
+++ /dev/null
@@ -1,348 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.coremedia.iso.boxes.sampleentry.AudioSampleEntry;
-import com.googlecode.mp4parser.authoring.AbstractTrack;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-import com.googlecode.mp4parser.boxes.mp4.ESDescriptorBox;
-import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.DecoderConfigDescriptor;
-import com.googlecode.mp4parser.boxes.mp4.objectdescriptors.ESDescriptor;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.util.*;
-
-/**
- * Appends two or more <code>Tracks</code> of the same type. No only that the type must be equal
- * also the decoder settings must be the same.
- */
-public class AppendTrack extends AbstractTrack {
- Track[] tracks;
- SampleDescriptionBox stsd;
-
- public AppendTrack(Track... tracks) throws IOException {
- this.tracks = tracks;
-
- for (Track track : tracks) {
-
- if (stsd == null) {
- stsd = track.getSampleDescriptionBox();
- } else {
- ByteArrayOutputStream curBaos = new ByteArrayOutputStream();
- ByteArrayOutputStream refBaos = new ByteArrayOutputStream();
- track.getSampleDescriptionBox().getBox(Channels.newChannel(curBaos));
- stsd.getBox(Channels.newChannel(refBaos));
- byte[] cur = curBaos.toByteArray();
- byte[] ref = refBaos.toByteArray();
-
- if (!Arrays.equals(ref, cur)) {
- SampleDescriptionBox curStsd = track.getSampleDescriptionBox();
- if (stsd.getBoxes().size() == 1 && curStsd.getBoxes().size() == 1) {
- if (stsd.getBoxes().get(0) instanceof AudioSampleEntry && curStsd.getBoxes().get(0) instanceof AudioSampleEntry) {
- AudioSampleEntry aseResult = mergeAudioSampleEntries((AudioSampleEntry) stsd.getBoxes().get(0), (AudioSampleEntry) curStsd.getBoxes().get(0));
- if (aseResult != null) {
- stsd.setBoxes(Collections.<Box>singletonList(aseResult));
- return;
- }
- }
- }
- throw new IOException("Cannot append " + track + " to " + tracks[0] + " since their Sample Description Boxes differ: \n" + track.getSampleDescriptionBox() + "\n vs. \n" + tracks[0].getSampleDescriptionBox());
- }
- }
- }
- }
-
- private AudioSampleEntry mergeAudioSampleEntries(AudioSampleEntry ase1, AudioSampleEntry ase2) throws IOException {
- if (ase1.getType().equals(ase2.getType())) {
- AudioSampleEntry ase = new AudioSampleEntry(ase2.getType());
- if (ase1.getBytesPerFrame() == ase2.getBytesPerFrame()) {
- ase.setBytesPerFrame(ase1.getBytesPerFrame());
- } else {
- return null;
- }
- if (ase1.getBytesPerPacket() == ase2.getBytesPerPacket()) {
- ase.setBytesPerPacket(ase1.getBytesPerPacket());
- } else {
- return null;
- }
- if (ase1.getBytesPerSample() == ase2.getBytesPerSample()) {
- ase.setBytesPerSample(ase1.getBytesPerSample());
- } else {
- return null;
- }
- if (ase1.getChannelCount() == ase2.getChannelCount()) {
- ase.setChannelCount(ase1.getChannelCount());
- } else {
- return null;
- }
- if (ase1.getPacketSize() == ase2.getPacketSize()) {
- ase.setPacketSize(ase1.getPacketSize());
- } else {
- return null;
- }
- if (ase1.getCompressionId() == ase2.getCompressionId()) {
- ase.setCompressionId(ase1.getCompressionId());
- } else {
- return null;
- }
- if (ase1.getSampleRate() == ase2.getSampleRate()) {
- ase.setSampleRate(ase1.getSampleRate());
- } else {
- return null;
- }
- if (ase1.getSampleSize() == ase2.getSampleSize()) {
- ase.setSampleSize(ase1.getSampleSize());
- } else {
- return null;
- }
- if (ase1.getSamplesPerPacket() == ase2.getSamplesPerPacket()) {
- ase.setSamplesPerPacket(ase1.getSamplesPerPacket());
- } else {
- return null;
- }
- if (ase1.getSoundVersion() == ase2.getSoundVersion()) {
- ase.setSoundVersion(ase1.getSoundVersion());
- } else {
- return null;
- }
- if (Arrays.equals(ase1.getSoundVersion2Data(), ase2.getSoundVersion2Data())) {
- ase.setSoundVersion2Data(ase1.getSoundVersion2Data());
- } else {
- return null;
- }
- if (ase1.getBoxes().size() == ase2.getBoxes().size()) {
- Iterator<Box> bxs1 = ase1.getBoxes().iterator();
- Iterator<Box> bxs2 = ase2.getBoxes().iterator();
- while (bxs1.hasNext()) {
- Box cur1 = bxs1.next();
- Box cur2 = bxs2.next();
- ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
- ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
- cur1.getBox(Channels.newChannel(baos1));
- cur2.getBox(Channels.newChannel(baos2));
- if (Arrays.equals(baos1.toByteArray(), baos2.toByteArray())) {
- ase.addBox(cur1);
- } else {
- if (ESDescriptorBox.TYPE.equals(cur1.getType()) && ESDescriptorBox.TYPE.equals(cur2.getType())) {
- ESDescriptorBox esdsBox1 = (ESDescriptorBox) cur1;
- ESDescriptorBox esdsBox2 = (ESDescriptorBox) cur2;
- ESDescriptor esds1 = esdsBox1.getEsDescriptor();
- ESDescriptor esds2 = esdsBox2.getEsDescriptor();
- if (esds1.getURLFlag() != esds2.getURLFlag()) {
- return null;
- }
- if (esds1.getURLLength() != esds2.getURLLength()) {
- return null;
- }
- if (esds1.getDependsOnEsId() != esds2.getDependsOnEsId()) {
- return null;
- }
- if (esds1.getEsId() != esds2.getEsId()) {
- return null;
- }
- if (esds1.getoCREsId() != esds2.getoCREsId()) {
- return null;
- }
- if (esds1.getoCRstreamFlag() != esds2.getoCRstreamFlag()) {
- return null;
- }
- if (esds1.getRemoteODFlag() != esds2.getRemoteODFlag()) {
- return null;
- }
- if (esds1.getStreamDependenceFlag() != esds2.getStreamDependenceFlag()) {
- return null;
- }
- if (esds1.getStreamPriority() != esds2.getStreamPriority()) {
- return null;
- }
- if (esds1.getURLString() != null ? !esds1.getURLString().equals(esds2.getURLString()) : esds2.getURLString() != null) {
- return null;
- }
- if (esds1.getDecoderConfigDescriptor() != null ? !esds1.getDecoderConfigDescriptor().equals(esds2.getDecoderConfigDescriptor()) : esds2.getDecoderConfigDescriptor() != null) {
- DecoderConfigDescriptor dcd1 = esds1.getDecoderConfigDescriptor();
- DecoderConfigDescriptor dcd2 = esds2.getDecoderConfigDescriptor();
- if (!dcd1.getAudioSpecificInfo().equals(dcd2.getAudioSpecificInfo())) {
- return null;
- }
- if (dcd1.getAvgBitRate() != dcd2.getAvgBitRate()) {
- // I don't care
- }
- if (dcd1.getBufferSizeDB() != dcd2.getBufferSizeDB()) {
- // I don't care
- }
-
- if (dcd1.getDecoderSpecificInfo() != null ? !dcd1.getDecoderSpecificInfo().equals(dcd2.getDecoderSpecificInfo()) : dcd2.getDecoderSpecificInfo() != null) {
- return null;
- }
-
- if (dcd1.getMaxBitRate() != dcd2.getMaxBitRate()) {
- // I don't care
- }
- if (!dcd1.getProfileLevelIndicationDescriptors().equals(dcd2.getProfileLevelIndicationDescriptors())) {
- return null;
- }
-
- if (dcd1.getObjectTypeIndication() != dcd2.getObjectTypeIndication()) {
- return null;
- }
- if (dcd1.getStreamType() != dcd2.getStreamType()) {
- return null;
- }
- if (dcd1.getUpStream() != dcd2.getUpStream()) {
- return null;
- }
-
-
- }
- if (esds1.getOtherDescriptors() != null ? !esds1.getOtherDescriptors().equals(esds2.getOtherDescriptors()) : esds2.getOtherDescriptors() != null) {
- return null;
- }
- if (esds1.getSlConfigDescriptor() != null ? !esds1.getSlConfigDescriptor().equals(esds2.getSlConfigDescriptor()) : esds2.getSlConfigDescriptor() != null) {
- return null;
- }
- ase.addBox(cur1);
- }
- }
- }
- }
- return ase;
- } else {
- return null;
- }
-
-
- }
-
-
- public List<ByteBuffer> getSamples() {
- ArrayList<ByteBuffer> lists = new ArrayList<ByteBuffer>();
-
- for (Track track : tracks) {
- lists.addAll(track.getSamples());
- }
-
- return lists;
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return stsd;
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- if (tracks[0].getDecodingTimeEntries() != null && !tracks[0].getDecodingTimeEntries().isEmpty()) {
- List<long[]> lists = new LinkedList<long[]>();
- for (Track track : tracks) {
- lists.add(TimeToSampleBox.blowupTimeToSamples(track.getDecodingTimeEntries()));
- }
-
- LinkedList<TimeToSampleBox.Entry> returnDecodingEntries = new LinkedList<TimeToSampleBox.Entry>();
- for (long[] list : lists) {
- for (long nuDecodingTime : list) {
- if (returnDecodingEntries.isEmpty() || returnDecodingEntries.getLast().getDelta() != nuDecodingTime) {
- TimeToSampleBox.Entry e = new TimeToSampleBox.Entry(1, nuDecodingTime);
- returnDecodingEntries.add(e);
- } else {
- TimeToSampleBox.Entry e = returnDecodingEntries.getLast();
- e.setCount(e.getCount() + 1);
- }
- }
- }
- return returnDecodingEntries;
- } else {
- return null;
- }
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- if (tracks[0].getCompositionTimeEntries() != null && !tracks[0].getCompositionTimeEntries().isEmpty()) {
- List<int[]> lists = new LinkedList<int[]>();
- for (Track track : tracks) {
- lists.add(CompositionTimeToSample.blowupCompositionTimes(track.getCompositionTimeEntries()));
- }
- LinkedList<CompositionTimeToSample.Entry> compositionTimeEntries = new LinkedList<CompositionTimeToSample.Entry>();
- for (int[] list : lists) {
- for (int compositionTime : list) {
- if (compositionTimeEntries.isEmpty() || compositionTimeEntries.getLast().getOffset() != compositionTime) {
- CompositionTimeToSample.Entry e = new CompositionTimeToSample.Entry(1, compositionTime);
- compositionTimeEntries.add(e);
- } else {
- CompositionTimeToSample.Entry e = compositionTimeEntries.getLast();
- e.setCount(e.getCount() + 1);
- }
- }
- }
- return compositionTimeEntries;
- } else {
- return null;
- }
- }
-
- public long[] getSyncSamples() {
- if (tracks[0].getSyncSamples() != null && tracks[0].getSyncSamples().length > 0) {
- int numSyncSamples = 0;
- for (Track track : tracks) {
- numSyncSamples += track.getSyncSamples().length;
- }
- long[] returnSyncSamples = new long[numSyncSamples];
-
- int pos = 0;
- long samplesBefore = 0;
- for (Track track : tracks) {
- for (long l : track.getSyncSamples()) {
- returnSyncSamples[pos++] = samplesBefore + l;
- }
- samplesBefore += track.getSamples().size();
- }
- return returnSyncSamples;
- } else {
- return null;
- }
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- if (tracks[0].getSampleDependencies() != null && !tracks[0].getSampleDependencies().isEmpty()) {
- List<SampleDependencyTypeBox.Entry> list = new LinkedList<SampleDependencyTypeBox.Entry>();
- for (Track track : tracks) {
- list.addAll(track.getSampleDependencies());
- }
- return list;
- } else {
- return null;
- }
- }
-
- public TrackMetaData getTrackMetaData() {
- return tracks[0].getTrackMetaData();
- }
-
- public String getHandler() {
- return tracks[0].getHandler();
- }
-
- public Box getMediaHeaderBox() {
- return tracks[0].getMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return tracks[0].getSubsampleInformationBox();
- }
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/ChangeTimeScaleTrack.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/ChangeTimeScaleTrack.java.svn-base
deleted file mode 100644
index 50f76c2..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/ChangeTimeScaleTrack.java.svn-base
+++ /dev/null
@@ -1,203 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.logging.Logger;
-
-/**
- * Changes the timescale of a track by wrapping the track.
- */
-public class ChangeTimeScaleTrack implements Track {
- private static final Logger LOG = Logger.getLogger(ChangeTimeScaleTrack.class.getName());
-
- Track source;
- List<CompositionTimeToSample.Entry> ctts;
- List<TimeToSampleBox.Entry> tts;
- long timeScale;
-
- /**
- * Changes the time scale of the source track to the target time scale and makes sure
- * that any rounding errors that may have summed are corrected exactly before the syncSamples.
- *
- * @param source the source track
- * @param targetTimeScale the resulting time scale of this track.
- * @param syncSamples at these sync points where rounding error are corrected.
- */
- public ChangeTimeScaleTrack(Track source, long targetTimeScale, long[] syncSamples) {
- this.source = source;
- this.timeScale = targetTimeScale;
- double timeScaleFactor = (double) targetTimeScale / source.getTrackMetaData().getTimescale();
- ctts = adjustCtts(source.getCompositionTimeEntries(), timeScaleFactor);
- tts = adjustTts(source.getDecodingTimeEntries(), timeScaleFactor, syncSamples, getTimes(source, syncSamples, targetTimeScale));
- }
-
- private static long[] getTimes(Track track, long[] syncSamples, long targetTimeScale) {
- long[] syncSampleTimes = new long[syncSamples.length];
- Queue<TimeToSampleBox.Entry> timeQueue = new LinkedList<TimeToSampleBox.Entry>(track.getDecodingTimeEntries());
-
- int currentSample = 1; // first syncsample is 1
- long currentDuration = 0;
- long currentDelta = 0;
- int currentSyncSampleIndex = 0;
- long left = 0;
-
-
- while (currentSample <= syncSamples[syncSamples.length - 1]) {
- if (currentSample++ == syncSamples[currentSyncSampleIndex]) {
- syncSampleTimes[currentSyncSampleIndex++] = (currentDuration * targetTimeScale) / track.getTrackMetaData().getTimescale();
- }
- if (left-- == 0) {
- TimeToSampleBox.Entry entry = timeQueue.poll();
- left = entry.getCount() - 1;
- currentDelta = entry.getDelta();
- }
- currentDuration += currentDelta;
- }
- return syncSampleTimes;
-
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return source.getSampleDescriptionBox();
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- return tts;
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- return ctts;
- }
-
- public long[] getSyncSamples() {
- return source.getSyncSamples();
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- return source.getSampleDependencies();
- }
-
- public TrackMetaData getTrackMetaData() {
- TrackMetaData trackMetaData = (TrackMetaData) source.getTrackMetaData().clone();
- trackMetaData.setTimescale(timeScale);
- return trackMetaData;
- }
-
- public String getHandler() {
- return source.getHandler();
- }
-
- public boolean isEnabled() {
- return source.isEnabled();
- }
-
- public boolean isInMovie() {
- return source.isInMovie();
- }
-
- public boolean isInPreview() {
- return source.isInPreview();
- }
-
- public boolean isInPoster() {
- return source.isInPoster();
- }
-
- public List<ByteBuffer> getSamples() {
- return source.getSamples();
- }
-
-
- /**
- * Adjusting the composition times is easy. Just scale it by the factor - that's it. There is no rounding
- * error summing up.
- *
- * @param source
- * @param timeScaleFactor
- * @return
- */
- static List<CompositionTimeToSample.Entry> adjustCtts(List<CompositionTimeToSample.Entry> source, double timeScaleFactor) {
- if (source != null) {
- List<CompositionTimeToSample.Entry> entries2 = new ArrayList<CompositionTimeToSample.Entry>(source.size());
- for (CompositionTimeToSample.Entry entry : source) {
- entries2.add(new CompositionTimeToSample.Entry(entry.getCount(), (int) Math.round(timeScaleFactor * entry.getOffset())));
- }
- return entries2;
- } else {
- return null;
- }
- }
-
- static List<TimeToSampleBox.Entry> adjustTts(List<TimeToSampleBox.Entry> source, double timeScaleFactor, long[] syncSample, long[] syncSampleTimes) {
-
- long[] sourceArray = TimeToSampleBox.blowupTimeToSamples(source);
- long summedDurations = 0;
-
- LinkedList<TimeToSampleBox.Entry> entries2 = new LinkedList<TimeToSampleBox.Entry>();
- for (int i = 1; i <= sourceArray.length; i++) {
- long duration = sourceArray[i - 1];
-
- long x = Math.round(timeScaleFactor * duration);
-
-
- TimeToSampleBox.Entry last = entries2.peekLast();
- int ssIndex;
- if ((ssIndex = Arrays.binarySearch(syncSample, i + 1)) >= 0) {
- // we are at the sample before sync point
- if (syncSampleTimes[ssIndex] != summedDurations) {
- long correction = syncSampleTimes[ssIndex] - (summedDurations + x);
- LOG.finest(String.format("Sample %d %d / %d - correct by %d", i, summedDurations, syncSampleTimes[ssIndex], correction));
- x += correction;
- }
- }
- summedDurations += x;
- if (last == null) {
- entries2.add(new TimeToSampleBox.Entry(1, x));
- } else if (last.getDelta() != x) {
- entries2.add(new TimeToSampleBox.Entry(1, x));
- } else {
- last.setCount(last.getCount() + 1);
- }
-
- }
- return entries2;
- }
-
- public Box getMediaHeaderBox() {
- return source.getMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return source.getSubsampleInformationBox();
- }
-
- @Override
- public String toString() {
- return "ChangeTimeScaleTrack{" +
- "source=" + source +
- '}';
- }
-} \ No newline at end of file
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/CroppedTrack.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/CroppedTrack.java.svn-base
deleted file mode 100644
index 2389961..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/CroppedTrack.java.svn-base
+++ /dev/null
@@ -1,151 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.googlecode.mp4parser.authoring.AbstractTrack;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Generates a Track that starts at fromSample and ends at toSample (exclusive). The user of this class
- * has to make sure that the fromSample is a random access sample.
- * <ul>
- * <li>In AAC this is every single sample</li>
- * <li>In H264 this is every sample that is marked in the SyncSampleBox</li>
- * </ul>
- */
-public class CroppedTrack extends AbstractTrack {
- Track origTrack;
- private int fromSample;
- private int toSample;
- private long[] syncSampleArray;
-
- public CroppedTrack(Track origTrack, long fromSample, long toSample) {
- this.origTrack = origTrack;
- assert fromSample <= Integer.MAX_VALUE;
- assert toSample <= Integer.MAX_VALUE;
- this.fromSample = (int) fromSample;
- this.toSample = (int) toSample;
- }
-
- public List<ByteBuffer> getSamples() {
- return origTrack.getSamples().subList(fromSample, toSample);
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return origTrack.getSampleDescriptionBox();
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- if (origTrack.getDecodingTimeEntries() != null && !origTrack.getDecodingTimeEntries().isEmpty()) {
- // todo optimize! too much long is allocated but then not used
- long[] decodingTimes = TimeToSampleBox.blowupTimeToSamples(origTrack.getDecodingTimeEntries());
- long[] nuDecodingTimes = new long[toSample - fromSample];
- System.arraycopy(decodingTimes, fromSample, nuDecodingTimes, 0, toSample - fromSample);
-
- LinkedList<TimeToSampleBox.Entry> returnDecodingEntries = new LinkedList<TimeToSampleBox.Entry>();
-
- for (long nuDecodingTime : nuDecodingTimes) {
- if (returnDecodingEntries.isEmpty() || returnDecodingEntries.getLast().getDelta() != nuDecodingTime) {
- TimeToSampleBox.Entry e = new TimeToSampleBox.Entry(1, nuDecodingTime);
- returnDecodingEntries.add(e);
- } else {
- TimeToSampleBox.Entry e = returnDecodingEntries.getLast();
- e.setCount(e.getCount() + 1);
- }
- }
- return returnDecodingEntries;
- } else {
- return null;
- }
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- if (origTrack.getCompositionTimeEntries() != null && !origTrack.getCompositionTimeEntries().isEmpty()) {
- int[] compositionTime = CompositionTimeToSample.blowupCompositionTimes(origTrack.getCompositionTimeEntries());
- int[] nuCompositionTimes = new int[toSample - fromSample];
- System.arraycopy(compositionTime, fromSample, nuCompositionTimes, 0, toSample - fromSample);
-
- LinkedList<CompositionTimeToSample.Entry> returnDecodingEntries = new LinkedList<CompositionTimeToSample.Entry>();
-
- for (int nuDecodingTime : nuCompositionTimes) {
- if (returnDecodingEntries.isEmpty() || returnDecodingEntries.getLast().getOffset() != nuDecodingTime) {
- CompositionTimeToSample.Entry e = new CompositionTimeToSample.Entry(1, nuDecodingTime);
- returnDecodingEntries.add(e);
- } else {
- CompositionTimeToSample.Entry e = returnDecodingEntries.getLast();
- e.setCount(e.getCount() + 1);
- }
- }
- return returnDecodingEntries;
- } else {
- return null;
- }
- }
-
- synchronized public long[] getSyncSamples() {
- if (this.syncSampleArray == null) {
- if (origTrack.getSyncSamples() != null && origTrack.getSyncSamples().length > 0) {
- List<Long> syncSamples = new LinkedList<Long>();
- for (long l : origTrack.getSyncSamples()) {
- if (l >= fromSample && l < toSample) {
- syncSamples.add(l - fromSample);
- }
- }
- syncSampleArray = new long[syncSamples.size()];
- for (int i = 0; i < syncSampleArray.length; i++) {
- syncSampleArray[i] = syncSamples.get(i);
-
- }
- return syncSampleArray;
- } else {
- return null;
- }
- } else {
- return this.syncSampleArray;
- }
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- if (origTrack.getSampleDependencies() != null && !origTrack.getSampleDependencies().isEmpty()) {
- return origTrack.getSampleDependencies().subList(fromSample, toSample);
- } else {
- return null;
- }
- }
-
- public TrackMetaData getTrackMetaData() {
- return origTrack.getTrackMetaData();
- }
-
- public String getHandler() {
- return origTrack.getHandler();
- }
-
- public Box getMediaHeaderBox() {
- return origTrack.getMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return origTrack.getSubsampleInformationBox();
- }
-
-} \ No newline at end of file
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/DivideTimeScaleTrack.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/DivideTimeScaleTrack.java.svn-base
deleted file mode 100644
index c51e8e0..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/DivideTimeScaleTrack.java.svn-base
+++ /dev/null
@@ -1,126 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Changes the timescale of a track by wrapping the track.
- */
-public class DivideTimeScaleTrack implements Track {
- Track source;
- private int timeScaleDivisor;
-
- public DivideTimeScaleTrack(Track source, int timeScaleDivisor) {
- this.source = source;
- this.timeScaleDivisor = timeScaleDivisor;
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return source.getSampleDescriptionBox();
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- return adjustTts();
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- return adjustCtts();
- }
-
- public long[] getSyncSamples() {
- return source.getSyncSamples();
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- return source.getSampleDependencies();
- }
-
- public TrackMetaData getTrackMetaData() {
- TrackMetaData trackMetaData = (TrackMetaData) source.getTrackMetaData().clone();
- trackMetaData.setTimescale(source.getTrackMetaData().getTimescale() / this.timeScaleDivisor);
- return trackMetaData;
- }
-
- public String getHandler() {
- return source.getHandler();
- }
-
- public boolean isEnabled() {
- return source.isEnabled();
- }
-
- public boolean isInMovie() {
- return source.isInMovie();
- }
-
- public boolean isInPreview() {
- return source.isInPreview();
- }
-
- public boolean isInPoster() {
- return source.isInPoster();
- }
-
- public List<ByteBuffer> getSamples() {
- return source.getSamples();
- }
-
-
- List<CompositionTimeToSample.Entry> adjustCtts() {
- List<CompositionTimeToSample.Entry> origCtts = this.source.getCompositionTimeEntries();
- if (origCtts != null) {
- List<CompositionTimeToSample.Entry> entries2 = new ArrayList<CompositionTimeToSample.Entry>(origCtts.size());
- for (CompositionTimeToSample.Entry entry : origCtts) {
- entries2.add(new CompositionTimeToSample.Entry(entry.getCount(), entry.getOffset() / timeScaleDivisor));
- }
- return entries2;
- } else {
- return null;
- }
- }
-
- List<TimeToSampleBox.Entry> adjustTts() {
- List<TimeToSampleBox.Entry> origTts = source.getDecodingTimeEntries();
- LinkedList<TimeToSampleBox.Entry> entries2 = new LinkedList<TimeToSampleBox.Entry>();
- for (TimeToSampleBox.Entry e : origTts) {
- entries2.add(new TimeToSampleBox.Entry(e.getCount(), e.getDelta() / timeScaleDivisor));
- }
- return entries2;
- }
-
- public Box getMediaHeaderBox() {
- return source.getMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return source.getSubsampleInformationBox();
- }
-
- @Override
- public String toString() {
- return "MultiplyTimeScaleTrack{" +
- "source=" + source +
- '}';
- }
-}
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
deleted file mode 100644
index d0b2d76..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/EC3TrackImpl.java.svn-base
+++ /dev/null
@@ -1,436 +0,0 @@
-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 +
- '}';
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/H264TrackImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/H264TrackImpl.java.svn-base
deleted file mode 100644
index b3c1866..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/H264TrackImpl.java.svn-base
+++ /dev/null
@@ -1,740 +0,0 @@
-package com.googlecode.mp4parser.authoring.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.coremedia.iso.boxes.h264.AvcConfigurationBox;
-import com.coremedia.iso.boxes.sampleentry.VisualSampleEntry;
-import com.googlecode.mp4parser.authoring.AbstractTrack;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-import com.googlecode.mp4parser.h264.model.PictureParameterSet;
-import com.googlecode.mp4parser.h264.model.SeqParameterSet;
-import com.googlecode.mp4parser.h264.read.CAVLCReader;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Logger;
-
-/**
- * The <code>H264TrackImpl</code> creates a <code>Track</code> from an H.264
- * Annex B file.
- */
-public class H264TrackImpl extends AbstractTrack {
- private static final Logger LOG = Logger.getLogger(H264TrackImpl.class.getName());
-
- TrackMetaData trackMetaData = new TrackMetaData();
- SampleDescriptionBox sampleDescriptionBox;
-
- private ReaderWrapper reader;
- private List<ByteBuffer> samples;
- boolean readSamples = false;
-
- List<TimeToSampleBox.Entry> stts;
- List<CompositionTimeToSample.Entry> ctts;
- List<SampleDependencyTypeBox.Entry> sdtp;
- List<Integer> stss;
-
- SeqParameterSet seqParameterSet = null;
- PictureParameterSet pictureParameterSet = null;
- LinkedList<byte[]> seqParameterSetList = new LinkedList<byte[]>();
- LinkedList<byte[]> pictureParameterSetList = new LinkedList<byte[]>();
-
- private int width;
- private int height;
- private int timescale;
- private int frametick;
- private int currentScSize;
- private int prevScSize;
-
- private SEIMessage seiMessage;
- int frameNrInGop = 0;
- private boolean determineFrameRate = true;
- private String lang = "und";
-
- public H264TrackImpl(InputStream inputStream, String lang, long timescale) throws IOException {
- this.lang = lang;
- if (timescale > 1000) {
- timescale = timescale; //e.g. 23976
- frametick = 1000;
- determineFrameRate = false;
- } else {
- throw new IllegalArgumentException("Timescale must be specified in milliseconds!");
- }
- parse(inputStream);
- }
-
- public H264TrackImpl(InputStream inputStream, String lang) throws IOException {
- this.lang = lang;
- parse(inputStream);
- }
-
- public H264TrackImpl(InputStream inputStream) throws IOException {
- parse(inputStream);
- }
-
- private void parse(InputStream inputStream) throws IOException {
- this.reader = new ReaderWrapper(inputStream);
- stts = new LinkedList<TimeToSampleBox.Entry>();
- ctts = new LinkedList<CompositionTimeToSample.Entry>();
- sdtp = new LinkedList<SampleDependencyTypeBox.Entry>();
- stss = new LinkedList<Integer>();
-
- samples = new LinkedList<ByteBuffer>();
- if (!readSamples()) {
- throw new IOException();
- }
-
- if (!readVariables()) {
- throw new IOException();
- }
-
- sampleDescriptionBox = new SampleDescriptionBox();
- VisualSampleEntry visualSampleEntry = new VisualSampleEntry("avc1");
- visualSampleEntry.setDataReferenceIndex(1);
- visualSampleEntry.setDepth(24);
- visualSampleEntry.setFrameCount(1);
- visualSampleEntry.setHorizresolution(72);
- visualSampleEntry.setVertresolution(72);
- visualSampleEntry.setWidth(width);
- visualSampleEntry.setHeight(height);
- visualSampleEntry.setCompressorname("AVC Coding");
-
- AvcConfigurationBox avcConfigurationBox = new AvcConfigurationBox();
-
- avcConfigurationBox.setSequenceParameterSets(seqParameterSetList);
- avcConfigurationBox.setPictureParameterSets(pictureParameterSetList);
- avcConfigurationBox.setAvcLevelIndication(seqParameterSet.level_idc);
- avcConfigurationBox.setAvcProfileIndication(seqParameterSet.profile_idc);
- avcConfigurationBox.setBitDepthLumaMinus8(seqParameterSet.bit_depth_luma_minus8);
- avcConfigurationBox.setBitDepthChromaMinus8(seqParameterSet.bit_depth_chroma_minus8);
- avcConfigurationBox.setChromaFormat(seqParameterSet.chroma_format_idc.getId());
- avcConfigurationBox.setConfigurationVersion(1);
- avcConfigurationBox.setLengthSizeMinusOne(3);
- avcConfigurationBox.setProfileCompatibility(seqParameterSetList.get(0)[1]);
-
- visualSampleEntry.addBox(avcConfigurationBox);
- sampleDescriptionBox.addBox(visualSampleEntry);
-
- trackMetaData.setCreationTime(new Date());
- trackMetaData.setModificationTime(new Date());
- trackMetaData.setLanguage(lang);
- trackMetaData.setTimescale(timescale);
- trackMetaData.setWidth(width);
- trackMetaData.setHeight(height);
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return sampleDescriptionBox;
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- return stts;
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- return ctts;
- }
-
- public long[] getSyncSamples() {
- long[] returns = new long[stss.size()];
- for (int i = 0; i < stss.size(); i++) {
- returns[i] = stss.get(i);
- }
- return returns;
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- return sdtp;
- }
-
- public TrackMetaData getTrackMetaData() {
- return trackMetaData;
- }
-
- public String getHandler() {
- return "vide";
- }
-
- public List<ByteBuffer> getSamples() {
- return samples;
- }
-
- public AbstractMediaHeaderBox getMediaHeaderBox() {
- return new VideoMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return null;
- }
-
- private boolean readVariables() {
- width = (seqParameterSet.pic_width_in_mbs_minus1 + 1) * 16;
- int mult = 2;
- if (seqParameterSet.frame_mbs_only_flag) {
- mult = 1;
- }
- height = 16 * (seqParameterSet.pic_height_in_map_units_minus1 + 1) * mult;
- if (seqParameterSet.frame_cropping_flag) {
- int chromaArrayType = 0;
- if (seqParameterSet.residual_color_transform_flag == false) {
- chromaArrayType = seqParameterSet.chroma_format_idc.getId();
- }
- int cropUnitX = 1;
- int cropUnitY = mult;
- if (chromaArrayType != 0) {
- cropUnitX = seqParameterSet.chroma_format_idc.getSubWidth();
- cropUnitY = seqParameterSet.chroma_format_idc.getSubHeight() * mult;
- }
-
- width -= cropUnitX * (seqParameterSet.frame_crop_left_offset + seqParameterSet.frame_crop_right_offset);
- height -= cropUnitY * (seqParameterSet.frame_crop_top_offset + seqParameterSet.frame_crop_bottom_offset);
- }
- return true;
- }
-
- private boolean findNextStartcode() throws IOException {
- byte[] test = new byte[]{-1, -1, -1, -1};
-
- int c;
- while ((c = reader.read()) != -1) {
- test[0] = test[1];
- test[1] = test[2];
- test[2] = test[3];
- test[3] = (byte) c;
- if (test[0] == 0 && test[1] == 0 && test[2] == 0 && test[3] == 1) {
- prevScSize = currentScSize;
- currentScSize = 4;
- return true;
- }
- if (test[0] == 0 && test[1] == 0 && test[2] == 1) {
- prevScSize = currentScSize;
- currentScSize = 3;
- return true;
- }
- }
- return false;
- }
-
- private enum NALActions {
- IGNORE, BUFFER, STORE, END
- }
-
- private boolean readSamples() throws IOException {
- if (readSamples) {
- return true;
- }
-
- readSamples = true;
-
-
- findNextStartcode();
- reader.mark();
- long pos = reader.getPos();
-
- ArrayList<byte[]> buffered = new ArrayList<byte[]>();
-
- int frameNr = 0;
-
- while (findNextStartcode()) {
- long newpos = reader.getPos();
- int size = (int) (newpos - pos - prevScSize);
- reader.reset();
- byte[] data = new byte[size ];
- reader.read(data);
- int type = data[0];
- int nal_ref_idc = (type >> 5) & 3;
- int nal_unit_type = type & 0x1f;
- LOG.fine("Found startcode at " + (pos -4) + " Type: " + nal_unit_type + " ref idc: " + nal_ref_idc + " (size " + size + ")");
- NALActions action = handleNALUnit(nal_ref_idc, nal_unit_type, data);
- switch (action) {
- case IGNORE:
- break;
-
- case BUFFER:
- buffered.add(data);
- break;
-
- case STORE:
- int stdpValue = 22;
- frameNr++;
- buffered.add(data);
- ByteBuffer bb = createSample(buffered);
- boolean IdrPicFlag = false;
- if (nal_unit_type == 5) {
- stdpValue += 16;
- IdrPicFlag = true;
- }
- ByteArrayInputStream bs = cleanBuffer(buffered.get(buffered.size() - 1));
- SliceHeader sh = new SliceHeader(bs, seqParameterSet, pictureParameterSet, IdrPicFlag);
- if (sh.slice_type == SliceHeader.SliceType.B) {
- stdpValue += 4;
- }
- LOG.fine("Adding sample with size " + bb.capacity() + " and header " + sh);
- buffered.clear();
- samples.add(bb);
- stts.add(new TimeToSampleBox.Entry(1, frametick));
- if (nal_unit_type == 5) { // IDR Picture
- stss.add(frameNr);
- }
- if (seiMessage.n_frames == 0) {
- frameNrInGop = 0;
- }
- int offset = 0;
- if (seiMessage.clock_timestamp_flag) {
- offset = seiMessage.n_frames - frameNrInGop;
- } else if (seiMessage.removal_delay_flag) {
- offset = seiMessage.dpb_removal_delay / 2;
- }
- ctts.add(new CompositionTimeToSample.Entry(1, offset * frametick));
- sdtp.add(new SampleDependencyTypeBox.Entry(stdpValue));
- frameNrInGop++;
- break;
-
- case END:
- return true;
-
-
- }
- pos = newpos;
- reader.seek(currentScSize);
- reader.mark();
- }
- return true;
- }
-
- private ByteBuffer createSample(List<byte[]> buffers) {
- int outsize = 0;
- for (int i = 0; i < buffers.size(); i++) {
- outsize += buffers.get(i).length + 4;
- }
- byte[] output = new byte[outsize];
-
- ByteBuffer bb = ByteBuffer.wrap(output);
- for (int i = 0; i < buffers.size(); i++) {
- bb.putInt(buffers.get(i).length);
- bb.put(buffers.get(i));
- }
- bb.rewind();
- return bb;
- }
-
- private ByteArrayInputStream cleanBuffer(byte[] data) {
- byte[] output = new byte[data.length];
- int inPos = 0;
- int outPos = 0;
- while (inPos < data.length) {
- if (data[inPos] == 0 && data[inPos + 1] == 0 && data[inPos + 2] == 3) {
- output[outPos] = 0;
- output[outPos + 1] = 0;
- inPos += 3;
- outPos += 2;
- } else {
- output[outPos] = data[inPos];
- inPos++;
- outPos++;
- }
- }
- return new ByteArrayInputStream(output, 0, outPos);
- }
-
- private NALActions handleNALUnit(int nal_ref_idc, int nal_unit_type, byte[] data) throws IOException {
- NALActions action;
- switch (nal_unit_type) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- action = NALActions.STORE; // Will only work in single slice per frame mode!
- break;
-
- case 6:
- seiMessage = new SEIMessage(cleanBuffer(data), seqParameterSet);
- action = NALActions.BUFFER;
- break;
-
- case 9:
-// printAccessUnitDelimiter(data);
- int type = data[1] >> 5;
- LOG.fine("Access unit delimiter type: " + type);
- action = NALActions.BUFFER;
- break;
-
-
- case 7:
- if (seqParameterSet == null) {
- ByteArrayInputStream is = cleanBuffer(data);
- is.read();
- seqParameterSet = SeqParameterSet.read(is);
- seqParameterSetList.add(data);
- configureFramerate();
- }
- action = NALActions.IGNORE;
- break;
-
- case 8:
- if (pictureParameterSet == null) {
- ByteArrayInputStream is = new ByteArrayInputStream(data);
- is.read();
- pictureParameterSet = PictureParameterSet.read(is);
- pictureParameterSetList.add(data);
- }
- action = NALActions.IGNORE;
- break;
-
- case 10:
- case 11:
- action = NALActions.END;
- break;
-
- default:
- System.err.println("Unknown NAL unit type: " + nal_unit_type);
- action = NALActions.IGNORE;
-
- }
-
- return action;
- }
-
- private void configureFramerate() {
- if (determineFrameRate) {
- if (seqParameterSet.vuiParams != null) {
- timescale = seqParameterSet.vuiParams.time_scale >> 1; // Not sure why, but I found this in several places, and it works...
- frametick = seqParameterSet.vuiParams.num_units_in_tick;
- if (timescale == 0 || frametick == 0) {
- System.err.println("Warning: vuiParams contain invalid values: time_scale: " + timescale + " and frame_tick: " + frametick + ". Setting frame rate to 25fps");
- timescale = 90000;
- frametick = 3600;
- }
- } else {
- System.err.println("Warning: Can't determine frame rate. Guessing 25 fps");
- timescale = 90000;
- frametick = 3600;
- }
- }
- }
-
- public void printAccessUnitDelimiter(byte[] data) {
- LOG.fine("Access unit delimiter: " + (data[1] >> 5));
- }
-
- public static class SliceHeader {
-
- public enum SliceType {
- P, B, I, SP, SI
- }
-
- public int first_mb_in_slice;
- public SliceType slice_type;
- public int pic_parameter_set_id;
- public int colour_plane_id;
- public int frame_num;
- public boolean field_pic_flag = false;
- public boolean bottom_field_flag = false;
- public int idr_pic_id;
- public int pic_order_cnt_lsb;
- public int delta_pic_order_cnt_bottom;
-
- public SliceHeader(InputStream is, SeqParameterSet sps, PictureParameterSet pps, boolean IdrPicFlag) throws IOException {
- is.read();
- CAVLCReader reader = new CAVLCReader(is);
- first_mb_in_slice = reader.readUE("SliceHeader: first_mb_in_slice");
- switch (reader.readUE("SliceHeader: slice_type")) {
- case 0:
- case 5:
- slice_type = SliceType.P;
- break;
-
- case 1:
- case 6:
- slice_type = SliceType.B;
- break;
-
- case 2:
- case 7:
- slice_type = SliceType.I;
- break;
-
- case 3:
- case 8:
- slice_type = SliceType.SP;
- break;
-
- case 4:
- case 9:
- slice_type = SliceType.SI;
- break;
-
- }
- pic_parameter_set_id = reader.readUE("SliceHeader: pic_parameter_set_id");
- if (sps.residual_color_transform_flag) {
- colour_plane_id = reader.readU(2, "SliceHeader: colour_plane_id");
- }
- frame_num = reader.readU(sps.log2_max_frame_num_minus4 + 4, "SliceHeader: frame_num");
-
- if (!sps.frame_mbs_only_flag) {
- field_pic_flag = reader.readBool("SliceHeader: field_pic_flag");
- if (field_pic_flag) {
- bottom_field_flag = reader.readBool("SliceHeader: bottom_field_flag");
- }
- }
- if (IdrPicFlag) {
- idr_pic_id = reader.readUE("SliceHeader: idr_pic_id");
- if (sps.pic_order_cnt_type == 0) {
- pic_order_cnt_lsb = reader.readU(sps.log2_max_pic_order_cnt_lsb_minus4 + 4, "SliceHeader: pic_order_cnt_lsb");
- if (pps.pic_order_present_flag && !field_pic_flag) {
- delta_pic_order_cnt_bottom = reader.readSE("SliceHeader: delta_pic_order_cnt_bottom");
- }
- }
- }
- }
-
- @Override
- public String toString() {
- return "SliceHeader{" +
- "first_mb_in_slice=" + first_mb_in_slice +
- ", slice_type=" + slice_type +
- ", pic_parameter_set_id=" + pic_parameter_set_id +
- ", colour_plane_id=" + colour_plane_id +
- ", frame_num=" + frame_num +
- ", field_pic_flag=" + field_pic_flag +
- ", bottom_field_flag=" + bottom_field_flag +
- ", idr_pic_id=" + idr_pic_id +
- ", pic_order_cnt_lsb=" + pic_order_cnt_lsb +
- ", delta_pic_order_cnt_bottom=" + delta_pic_order_cnt_bottom +
- '}';
- }
- }
-
- private class ReaderWrapper {
- private InputStream inputStream;
- private long pos = 0;
-
- private long markPos = 0;
-
-
- private ReaderWrapper(InputStream inputStream) {
- this.inputStream = inputStream;
- }
-
- int read() throws IOException {
- pos++;
- return inputStream.read();
- }
-
- long read(byte[] data) throws IOException {
- long read = inputStream.read(data);
- pos += read;
- return read;
- }
-
- long seek(int dist) throws IOException {
- long seeked = inputStream.skip(dist);
- pos += seeked;
- return seeked;
- }
-
- public long getPos() {
- return pos;
- }
-
- public void mark() {
- int i = 1048576;
- LOG.fine("Marking with " + i + " at " + pos);
- inputStream.mark(i);
- markPos = pos;
- }
-
-
- public void reset() throws IOException {
- long diff = pos - markPos;
- LOG.fine("Resetting to " + markPos + " (pos is " + pos + ") which makes the buffersize " + diff);
- inputStream.reset();
- pos = markPos;
- }
- }
-
- public class SEIMessage {
-
- int payloadType = 0;
- int payloadSize = 0;
-
- boolean removal_delay_flag;
- int cpb_removal_delay;
- int dpb_removal_delay;
-
- boolean clock_timestamp_flag;
- int pic_struct;
- int ct_type;
- int nuit_field_based_flag;
- int counting_type;
- int full_timestamp_flag;
- int discontinuity_flag;
- int cnt_dropped_flag;
- int n_frames;
- int seconds_value;
- int minutes_value;
- int hours_value;
- int time_offset_length;
- int time_offset;
-
- SeqParameterSet sps;
-
- public SEIMessage(InputStream is, SeqParameterSet sps) throws IOException {
- this.sps = sps;
- is.read();
- int datasize = is.available();
- int read = 0;
- while (read < datasize) {
- payloadType = 0;
- payloadSize = 0;
- int last_payload_type_bytes = is.read();
- read++;
- while (last_payload_type_bytes == 0xff) {
- payloadType += last_payload_type_bytes;
- last_payload_type_bytes = is.read();
- read++;
- }
- payloadType += last_payload_type_bytes;
- int last_payload_size_bytes = is.read();
- read++;
-
- while (last_payload_size_bytes == 0xff) {
- payloadSize += last_payload_size_bytes;
- last_payload_size_bytes = is.read();
- read++;
- }
- payloadSize += last_payload_size_bytes;
- if (datasize - read >= payloadSize) {
- if (payloadType == 1) { // pic_timing is what we are interested in!
- if (sps.vuiParams != null && (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null || sps.vuiParams.pic_struct_present_flag)) {
- byte[] data = new byte[payloadSize];
- is.read(data);
- read += payloadSize;
- CAVLCReader reader = new CAVLCReader(new ByteArrayInputStream(data));
- if (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null) {
- removal_delay_flag = true;
- cpb_removal_delay = reader.readU(sps.vuiParams.nalHRDParams.cpb_removal_delay_length_minus1 + 1, "SEI: cpb_removal_delay");
- dpb_removal_delay = reader.readU(sps.vuiParams.nalHRDParams.dpb_output_delay_length_minus1 + 1, "SEI: dpb_removal_delay");
- } else {
- removal_delay_flag = false;
- }
- if (sps.vuiParams.pic_struct_present_flag) {
- pic_struct = reader.readU(4, "SEI: pic_struct");
- int numClockTS;
- switch (pic_struct) {
- case 0:
- case 1:
- case 2:
- default:
- numClockTS = 1;
- break;
-
- case 3:
- case 4:
- case 7:
- numClockTS = 2;
- break;
-
- case 5:
- case 6:
- case 8:
- numClockTS = 3;
- break;
- }
- for (int i = 0; i < numClockTS; i++) {
- clock_timestamp_flag = reader.readBool("pic_timing SEI: clock_timestamp_flag[" + i + "]");
- if (clock_timestamp_flag) {
- ct_type = reader.readU(2, "pic_timing SEI: ct_type");
- nuit_field_based_flag = reader.readU(1, "pic_timing SEI: nuit_field_based_flag");
- counting_type = reader.readU(5, "pic_timing SEI: counting_type");
- full_timestamp_flag = reader.readU(1, "pic_timing SEI: full_timestamp_flag");
- discontinuity_flag = reader.readU(1, "pic_timing SEI: discontinuity_flag");
- cnt_dropped_flag = reader.readU(1, "pic_timing SEI: cnt_dropped_flag");
- n_frames = reader.readU(8, "pic_timing SEI: n_frames");
- if (full_timestamp_flag == 1) {
- seconds_value = reader.readU(6, "pic_timing SEI: seconds_value");
- minutes_value = reader.readU(6, "pic_timing SEI: minutes_value");
- hours_value = reader.readU(5, "pic_timing SEI: hours_value");
- } else {
- if (reader.readBool("pic_timing SEI: seconds_flag")) {
- seconds_value = reader.readU(6, "pic_timing SEI: seconds_value");
- if (reader.readBool("pic_timing SEI: minutes_flag")) {
- minutes_value = reader.readU(6, "pic_timing SEI: minutes_value");
- if (reader.readBool("pic_timing SEI: hours_flag")) {
- hours_value = reader.readU(5, "pic_timing SEI: hours_value");
- }
- }
- }
- }
- if (true) {
- if (sps.vuiParams.nalHRDParams != null) {
- time_offset_length = sps.vuiParams.nalHRDParams.time_offset_length;
- } else if (sps.vuiParams.vclHRDParams != null) {
- time_offset_length = sps.vuiParams.vclHRDParams.time_offset_length;
- } else {
- time_offset_length = 24;
- }
- time_offset = reader.readU(24, "pic_timing SEI: time_offset");
- }
- }
- }
- }
-
- } else {
- for (int i = 0; i < payloadSize; i++) {
- is.read();
- read++;
- }
- }
- } else {
- for (int i = 0; i < payloadSize; i++) {
- is.read();
- read++;
- }
- }
- } else {
- read = datasize;
- }
- LOG.fine(this.toString());
- }
- }
-
- @Override
- public String toString() {
- String out = "SEIMessage{" +
- "payloadType=" + payloadType +
- ", payloadSize=" + payloadSize;
- if (payloadType == 1) {
- if (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null) {
-
- out += ", cpb_removal_delay=" + cpb_removal_delay +
- ", dpb_removal_delay=" + dpb_removal_delay;
- }
- if (sps.vuiParams.pic_struct_present_flag) {
- out += ", pic_struct=" + pic_struct;
- if (clock_timestamp_flag) {
- out += ", ct_type=" + ct_type +
- ", nuit_field_based_flag=" + nuit_field_based_flag +
- ", counting_type=" + counting_type +
- ", full_timestamp_flag=" + full_timestamp_flag +
- ", discontinuity_flag=" + discontinuity_flag +
- ", cnt_dropped_flag=" + cnt_dropped_flag +
- ", n_frames=" + n_frames +
- ", seconds_value=" + seconds_value +
- ", minutes_value=" + minutes_value +
- ", hours_value=" + hours_value +
- ", time_offset_length=" + time_offset_length +
- ", time_offset=" + time_offset;
- }
- }
- }
- out += '}';
- return out;
- }
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/MultiplyTimeScaleTrack.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/MultiplyTimeScaleTrack.java.svn-base
deleted file mode 100644
index e9a90e4..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/MultiplyTimeScaleTrack.java.svn-base
+++ /dev/null
@@ -1,130 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-import static com.googlecode.mp4parser.util.CastUtils.l2i;
-import static com.googlecode.mp4parser.util.Math.gcd;
-import static com.googlecode.mp4parser.util.Math.lcm;
-import static java.lang.Math.round;
-
-/**
- * Changes the timescale of a track by wrapping the track.
- */
-public class MultiplyTimeScaleTrack implements Track {
- Track source;
- private int timeScaleFactor;
-
- public MultiplyTimeScaleTrack(Track source, int timeScaleFactor) {
- this.source = source;
- this.timeScaleFactor = timeScaleFactor;
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return source.getSampleDescriptionBox();
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- return adjustTts(source.getDecodingTimeEntries(), timeScaleFactor);
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- return adjustCtts(source.getCompositionTimeEntries(), timeScaleFactor);
- }
-
- public long[] getSyncSamples() {
- return source.getSyncSamples();
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- return source.getSampleDependencies();
- }
-
- public TrackMetaData getTrackMetaData() {
- TrackMetaData trackMetaData = (TrackMetaData) source.getTrackMetaData().clone();
- trackMetaData.setTimescale(source.getTrackMetaData().getTimescale() * this.timeScaleFactor);
- return trackMetaData;
- }
-
- public String getHandler() {
- return source.getHandler();
- }
-
- public boolean isEnabled() {
- return source.isEnabled();
- }
-
- public boolean isInMovie() {
- return source.isInMovie();
- }
-
- public boolean isInPreview() {
- return source.isInPreview();
- }
-
- public boolean isInPoster() {
- return source.isInPoster();
- }
-
- public List<ByteBuffer> getSamples() {
- return source.getSamples();
- }
-
-
- static List<CompositionTimeToSample.Entry> adjustCtts(List<CompositionTimeToSample.Entry> source, int timeScaleFactor) {
- if (source != null) {
- List<CompositionTimeToSample.Entry> entries2 = new ArrayList<CompositionTimeToSample.Entry>(source.size());
- for (CompositionTimeToSample.Entry entry : source) {
- entries2.add(new CompositionTimeToSample.Entry(entry.getCount(), timeScaleFactor * entry.getOffset()));
- }
- return entries2;
- } else {
- return null;
- }
- }
-
- static List<TimeToSampleBox.Entry> adjustTts(List<TimeToSampleBox.Entry> source, int timeScaleFactor) {
- LinkedList<TimeToSampleBox.Entry> entries2 = new LinkedList<TimeToSampleBox.Entry>();
- for (TimeToSampleBox.Entry e : source) {
- entries2.add(new TimeToSampleBox.Entry(e.getCount(), timeScaleFactor * e.getDelta()));
- }
- return entries2;
- }
-
- public Box getMediaHeaderBox() {
- return source.getMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return source.getSubsampleInformationBox();
- }
-
- @Override
- public String toString() {
- return "MultiplyTimeScaleTrack{" +
- "source=" + source +
- '}';
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/QuicktimeTextTrackImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/QuicktimeTextTrackImpl.java.svn-base
deleted file mode 100644
index 8efa399..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/QuicktimeTextTrackImpl.java.svn-base
+++ /dev/null
@@ -1,165 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.coremedia.iso.boxes.sampleentry.TextSampleEntry;
-import com.googlecode.mp4parser.authoring.AbstractTrack;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-import com.googlecode.mp4parser.boxes.apple.BaseMediaInfoAtom;
-import com.googlecode.mp4parser.boxes.apple.GenericMediaHeaderAtom;
-import com.googlecode.mp4parser.boxes.apple.GenericMediaHeaderTextAtom;
-import com.googlecode.mp4parser.boxes.apple.QuicktimeTextSampleEntry;
-import com.googlecode.mp4parser.boxes.threegpp26245.FontTableBox;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * A Text track as Quicktime Pro would create.
- */
-public class QuicktimeTextTrackImpl extends AbstractTrack {
- TrackMetaData trackMetaData = new TrackMetaData();
- SampleDescriptionBox sampleDescriptionBox;
- List<Line> subs = new LinkedList<Line>();
-
- public List<Line> getSubs() {
- return subs;
- }
-
- public QuicktimeTextTrackImpl() {
- sampleDescriptionBox = new SampleDescriptionBox();
- QuicktimeTextSampleEntry textTrack = new QuicktimeTextSampleEntry();
- textTrack.setDataReferenceIndex(1);
- sampleDescriptionBox.addBox(textTrack);
-
-
- trackMetaData.setCreationTime(new Date());
- trackMetaData.setModificationTime(new Date());
- trackMetaData.setTimescale(1000);
-
-
- }
-
-
- public List<ByteBuffer> getSamples() {
- List<ByteBuffer> samples = new LinkedList<ByteBuffer>();
- long lastEnd = 0;
- for (Line sub : subs) {
- long silentTime = sub.from - lastEnd;
- if (silentTime > 0) {
- samples.add(ByteBuffer.wrap(new byte[]{0, 0}));
- } else if (silentTime < 0) {
- throw new Error("Subtitle display times may not intersect");
- }
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baos);
- try {
- dos.writeShort(sub.text.getBytes("UTF-8").length);
- dos.write(sub.text.getBytes("UTF-8"));
- dos.close();
- } catch (IOException e) {
- throw new Error("VM is broken. Does not support UTF-8");
- }
- samples.add(ByteBuffer.wrap(baos.toByteArray()));
- lastEnd = sub.to;
- }
- return samples;
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return sampleDescriptionBox;
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- List<TimeToSampleBox.Entry> stts = new LinkedList<TimeToSampleBox.Entry>();
- long lastEnd = 0;
- for (Line sub : subs) {
- long silentTime = sub.from - lastEnd;
- if (silentTime > 0) {
- stts.add(new TimeToSampleBox.Entry(1, silentTime));
- } else if (silentTime < 0) {
- throw new Error("Subtitle display times may not intersect");
- }
- stts.add(new TimeToSampleBox.Entry(1, sub.to - sub.from));
- lastEnd = sub.to;
- }
- 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 "text";
- }
-
-
- public static class Line {
- long from;
- long to;
- String text;
-
-
- public Line(long from, long to, String text) {
- this.from = from;
- this.to = to;
- this.text = text;
- }
-
- public long getFrom() {
- return from;
- }
-
- public String getText() {
- return text;
- }
-
- public long getTo() {
- return to;
- }
- }
-
- public Box getMediaHeaderBox() {
- GenericMediaHeaderAtom ghmd = new GenericMediaHeaderAtom();
- ghmd.addBox(new BaseMediaInfoAtom());
- ghmd.addBox(new GenericMediaHeaderTextAtom());
- return ghmd;
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return null;
- }
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/ReplaceSampleTrack.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/ReplaceSampleTrack.java.svn-base
deleted file mode 100644
index 81a129d..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/ReplaceSampleTrack.java.svn-base
+++ /dev/null
@@ -1,104 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.googlecode.mp4parser.authoring.AbstractTrack;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-
-import java.nio.ByteBuffer;
-import java.util.AbstractList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Generates a Track where a single sample has been replaced by a given <code>ByteBuffer</code>.
- */
-
-public class ReplaceSampleTrack extends AbstractTrack {
- Track origTrack;
- private long sampleNumber;
- private ByteBuffer sampleContent;
- private List<ByteBuffer> samples;
-
- public ReplaceSampleTrack(Track origTrack, long sampleNumber, ByteBuffer content) {
- this.origTrack = origTrack;
- this.sampleNumber = sampleNumber;
- this.sampleContent = content;
- this.samples = new ReplaceASingleEntryList();
-
- }
-
- public List<ByteBuffer> getSamples() {
- return samples;
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return origTrack.getSampleDescriptionBox();
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- return origTrack.getDecodingTimeEntries();
-
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- return origTrack.getCompositionTimeEntries();
-
- }
-
- synchronized public long[] getSyncSamples() {
- return origTrack.getSyncSamples();
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- return origTrack.getSampleDependencies();
- }
-
- public TrackMetaData getTrackMetaData() {
- return origTrack.getTrackMetaData();
- }
-
- public String getHandler() {
- return origTrack.getHandler();
- }
-
- public Box getMediaHeaderBox() {
- return origTrack.getMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return origTrack.getSubsampleInformationBox();
- }
-
- private class ReplaceASingleEntryList extends AbstractList<ByteBuffer> {
- @Override
- public ByteBuffer get(int index) {
- if (ReplaceSampleTrack.this.sampleNumber == index) {
- return ReplaceSampleTrack.this.sampleContent;
- } else {
- return ReplaceSampleTrack.this.origTrack.getSamples().get(index);
- }
- }
-
- @Override
- public int size() {
- return ReplaceSampleTrack.this.origTrack.getSamples().size();
- }
- }
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/SilenceTrackImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/SilenceTrackImpl.java.svn-base
deleted file mode 100644
index f74ab3c..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/SilenceTrackImpl.java.svn-base
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.googlecode.mp4parser.authoring.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.googlecode.mp4parser.authoring.Mp4TrackImpl;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * This is just a basic idea how things could work but they don't.
- */
-public class SilenceTrackImpl implements Track {
- Track source;
-
- List<ByteBuffer> samples = new LinkedList<ByteBuffer>();
- TimeToSampleBox.Entry entry;
-
- public SilenceTrackImpl(Track ofType, long ms) {
- source = ofType;
- if ("mp4a".equals(ofType.getSampleDescriptionBox().getSampleEntry().getType())) {
- long numFrames = getTrackMetaData().getTimescale() * ms / 1000 / 1024;
- long standZeit = getTrackMetaData().getTimescale() * ms / numFrames / 1000;
- entry = new TimeToSampleBox.Entry(numFrames, standZeit);
-
-
- while (numFrames-- > 0) {
- samples.add((ByteBuffer) ByteBuffer.wrap(new byte[]{
- 0x21, 0x10, 0x04, 0x60, (byte) 0x8c, 0x1c,
- }).rewind());
- }
-
- } else {
- throw new RuntimeException("Tracks of type " + ofType.getClass().getSimpleName() + " are not supported");
- }
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return source.getSampleDescriptionBox();
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- return Collections.singletonList(entry);
-
- }
-
- public TrackMetaData getTrackMetaData() {
- return source.getTrackMetaData();
- }
-
- public String getHandler() {
- return source.getHandler();
- }
-
- public boolean isEnabled() {
- return source.isEnabled();
- }
-
- public boolean isInMovie() {
- return source.isInMovie();
- }
-
- public boolean isInPreview() {
- return source.isInPreview();
- }
-
- public boolean isInPoster() {
- return source.isInPoster();
- }
-
- public List<ByteBuffer> getSamples() {
- return samples;
- }
-
- public Box getMediaHeaderBox() {
- return source.getMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return null;
- }
-
- public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() {
- return null;
- }
-
- public long[] getSyncSamples() {
- return null;
- }
-
- public List<SampleDependencyTypeBox.Entry> getSampleDependencies() {
- return null;
- }
-
-}
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/TextTrackImpl.java.svn-base b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/TextTrackImpl.java.svn-base
deleted file mode 100644
index 3bae143..0000000
--- a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/.svn/text-base/TextTrackImpl.java.svn-base
+++ /dev/null
@@ -1,165 +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.tracks;
-
-import com.coremedia.iso.boxes.*;
-import com.coremedia.iso.boxes.sampleentry.TextSampleEntry;
-import com.googlecode.mp4parser.authoring.AbstractTrack;
-import com.googlecode.mp4parser.authoring.TrackMetaData;
-import com.googlecode.mp4parser.boxes.threegpp26245.FontTableBox;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- *
- */
-public class TextTrackImpl extends AbstractTrack {
- TrackMetaData trackMetaData = new TrackMetaData();
- SampleDescriptionBox sampleDescriptionBox;
- List<Line> subs = new LinkedList<Line>();
-
- public List<Line> getSubs() {
- return subs;
- }
-
- public TextTrackImpl() {
- sampleDescriptionBox = new SampleDescriptionBox();
- TextSampleEntry tx3g = new TextSampleEntry("tx3g");
- tx3g.setDataReferenceIndex(1);
- tx3g.setStyleRecord(new TextSampleEntry.StyleRecord());
- tx3g.setBoxRecord(new TextSampleEntry.BoxRecord());
- sampleDescriptionBox.addBox(tx3g);
-
- FontTableBox ftab = new FontTableBox();
- ftab.setEntries(Collections.singletonList(new FontTableBox.FontRecord(1, "Serif")));
-
- tx3g.addBox(ftab);
-
-
- trackMetaData.setCreationTime(new Date());
- trackMetaData.setModificationTime(new Date());
- trackMetaData.setTimescale(1000); // Text tracks use millieseconds
-
-
- }
-
-
- public List<ByteBuffer> getSamples() {
- List<ByteBuffer> samples = new LinkedList<ByteBuffer>();
- long lastEnd = 0;
- for (Line sub : subs) {
- long silentTime = sub.from - lastEnd;
- if (silentTime > 0) {
- samples.add(ByteBuffer.wrap(new byte[]{0, 0}));
- } else if (silentTime < 0) {
- throw new Error("Subtitle display times may not intersect");
- }
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baos);
- try {
- dos.writeShort(sub.text.getBytes("UTF-8").length);
- dos.write(sub.text.getBytes("UTF-8"));
- dos.close();
- } catch (IOException e) {
- throw new Error("VM is broken. Does not support UTF-8");
- }
- samples.add(ByteBuffer.wrap(baos.toByteArray()));
- lastEnd = sub.to;
- }
- return samples;
- }
-
- public SampleDescriptionBox getSampleDescriptionBox() {
- return sampleDescriptionBox;
- }
-
- public List<TimeToSampleBox.Entry> getDecodingTimeEntries() {
- List<TimeToSampleBox.Entry> stts = new LinkedList<TimeToSampleBox.Entry>();
- long lastEnd = 0;
- for (Line sub : subs) {
- long silentTime = sub.from - lastEnd;
- if (silentTime > 0) {
- stts.add(new TimeToSampleBox.Entry(1, silentTime));
- } else if (silentTime < 0) {
- throw new Error("Subtitle display times may not intersect");
- }
- stts.add(new TimeToSampleBox.Entry(1, sub.to - sub.from));
- lastEnd = sub.to;
- }
- 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 "sbtl";
- }
-
-
- public static class Line {
- long from;
- long to;
- String text;
-
-
- public Line(long from, long to, String text) {
- this.from = from;
- this.to = to;
- this.text = text;
- }
-
- public long getFrom() {
- return from;
- }
-
- public String getText() {
- return text;
- }
-
- public long getTo() {
- return to;
- }
- }
-
- public AbstractMediaHeaderBox getMediaHeaderBox() {
- return new NullMediaHeaderBox();
- }
-
- public SubSampleInformationBox getSubsampleInformationBox() {
- return null;
- }
-}