diff options
Diffstat (limited to 'isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base')
6 files changed, 604 insertions, 0 deletions
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 new file mode 100644 index 0000000..fb0e224 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/AbstractTrack.java.svn-base @@ -0,0 +1,60 @@ +/* + * 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 new file mode 100644 index 0000000..0252859 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/DateHelper.java.svn-base @@ -0,0 +1,44 @@ +/* + * 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 new file mode 100644 index 0000000..0658682 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Movie.java.svn-base @@ -0,0 +1,91 @@ +/* + * 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 new file mode 100644 index 0000000..3bff1a5 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Mp4TrackImpl.java.svn-base @@ -0,0 +1,219 @@ +/* + * 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 new file mode 100644 index 0000000..1f4b363 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/Track.java.svn-base @@ -0,0 +1,60 @@ +/* + * 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 new file mode 100644 index 0000000..c262309 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/.svn/text-base/TrackMetaData.java.svn-base @@ -0,0 +1,130 @@ +/* + * 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; + } + } + +} |