diff options
Diffstat (limited to 'isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/CroppedTrack.java')
-rw-r--r-- | isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/CroppedTrack.java | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/CroppedTrack.java b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/CroppedTrack.java new file mode 100644 index 0000000..2389961 --- /dev/null +++ b/isoparser/src/main/java/com/googlecode/mp4parser/authoring/tracks/CroppedTrack.java @@ -0,0 +1,151 @@ +/* + * 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 |