/*
* 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.MovieExtendsBox;
import com.coremedia.iso.boxes.fragment.MovieFragmentBox;
import com.coremedia.iso.boxes.fragment.TrackFragmentBox;
import com.coremedia.iso.boxes.fragment.TrackRunBox;
import com.coremedia.iso.boxes.mdat.SampleList;
import java.nio.ByteBuffer;
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;
private List<SampleDependencyTypeBox.Entry> sampleDependencies;
private TrackMetaData trackMetaData = new TrackMetaData();
private String handler;
private AbstractMediaHeaderBox mihd;
public Mp4TrackImpl(TrackBox trackBox) {
samples = new SampleList(trackBox);
SampleTableBox stbl = trackBox.getMediaBox().getMediaInformationBox().getSampleTableBox();
handler = trackBox.getMediaBox().getHandlerBox().getHandlerType();
mihd = trackBox.getMediaBox().getMediaInformationBox().getMediaHeaderBox();
sampleDescriptionBox = stbl.getSampleDescriptionBox();
if (trackBox.getParent().getBoxes(MovieExtendsBox.class).size() > 0) {
decodingTimeEntries = new LinkedList<TimeToSampleBox.Entry>();
compositionTimeEntries = new LinkedList<CompositionTimeToSample.Entry>();
sampleDependencies = new LinkedList<SampleDependencyTypeBox.Entry>();
for (MovieFragmentBox movieFragmentBox : trackBox.getIsoFile().getBoxes(MovieFragmentBox.class)) {
List<TrackFragmentBox> trafs = movieFragmentBox.getBoxes(TrackFragmentBox.class);
for (TrackFragmentBox traf : trafs) {
if (traf.getTrackFragmentHeaderBox().getTrackId() == trackBox.getTrackHeaderBox().getTrackId()) {
List<TrackRunBox> truns = traf.getBoxes(TrackRunBox.class);
for (TrackRunBox trun : truns) {
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);
}
}
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);
}
}
}
}
}
}
}
} else {
decodingTimeEntries = stbl.getTimeToSampleBox().getEntries();
if (stbl.getCompositionTimeToSample() != null) {
compositionTimeEntries = stbl.getCompositionTimeToSample().getEntries();
}
if (stbl.getSyncSampleBox() != null) {
syncSamples = stbl.getSyncSampleBox().getSampleNumber();
}
if (stbl.getSampleDependencyTypeBox() != null) {
sampleDependencies = stbl.getSampleDependencyTypeBox().getEntries();
}
}
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 + '\'' +
'}';
}
}