FileDocCategorySizeDatePackage
AppendTrack.javaAPI Docmp4parser 1.0-RC-1715783Wed Dec 19 20:10:37 GMT 2012com.googlecode.mp4parser.authoring.tracks

AppendTrack

public class AppendTrack extends com.googlecode.mp4parser.authoring.AbstractTrack
Appends two or more Tracks of the same type. No only that the type must be equal also the decoder settings must be the same.

Fields Summary
com.googlecode.mp4parser.authoring.Track[]
tracks
SampleDescriptionBox
stsd
Constructors Summary
public AppendTrack(com.googlecode.mp4parser.authoring.Track tracks)

        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());
                }
            }
        }
    
Methods Summary
public java.util.ListgetCompositionTimeEntries()

        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 java.util.ListgetDecodingTimeEntries()

        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 java.lang.StringgetHandler()

        return tracks[0].getHandler();
    
public BoxgetMediaHeaderBox()

        return tracks[0].getMediaHeaderBox();
    
public java.util.ListgetSampleDependencies()

        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 SampleDescriptionBoxgetSampleDescriptionBox()

        return stsd;
    
public java.util.ListgetSamples()

        ArrayList<ByteBuffer> lists = new ArrayList<ByteBuffer>();

        for (Track track : tracks) {
            lists.addAll(track.getSamples());
        }

        return lists;
    
public SubSampleInformationBoxgetSubsampleInformationBox()

        return tracks[0].getSubsampleInformationBox();
    
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 com.googlecode.mp4parser.authoring.TrackMetaDatagetTrackMetaData()

        return tracks[0].getTrackMetaData();
    
private com.coremedia.iso.boxes.sampleentry.AudioSampleEntrymergeAudioSampleEntries(com.coremedia.iso.boxes.sampleentry.AudioSampleEntry ase1, com.coremedia.iso.boxes.sampleentry.AudioSampleEntry ase2)

        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;
        }