@@ -0,0 +1,3143 @@
+package org.jcodec.movtool;%0A%0Aimport java.io.IOException;%0Aimport java.nio.ByteBuffer;%0Aimport java.util.ArrayList;%0A%0Aimport org.jcodec.common.IntArrayList;%0Aimport org.jcodec.common.io.NIOUtils;%0Aimport org.jcodec.common.io.SeekableByteChannel;%0Aimport org.jcodec.containers.mp4.Chunk;%0Aimport org.jcodec.containers.mp4.ChunkReader;%0Aimport org.jcodec.containers.mp4.boxes.Box;%0Aimport org.jcodec.containers.mp4.boxes.Edit;%0Aimport org.jcodec.containers.mp4.boxes.TimeToSampleBox;%0Aimport org.jcodec.containers.mp4.boxes.TimeToSampleBox.TimeToSampleEntry;%0Aimport org.jcodec.containers.mp4.boxes.TrakBox;%0A%0A/**%0A * This class is part of JCodec ( www.jcodec.org ) This software is distributed%0A * under FreeBSD License%0A * %0A * A hacky way to fix timestamps without rewriting the file%0A * %0A * @author The JCodec project%0A * %0A */%0Apublic abstract class FixTimestamp %7B%0A    public void fixTimestamp(TrakBox trakBox, SeekableByteChannel ch) throws IOException %7B%0A        SeekableByteChannel%5B%5D inputs = new SeekableByteChannel%5B%5D %7B ch %7D;%0A        ChunkReader chr = new ChunkReader(trakBox, inputs);%0A        long prevPts = -1;%0A        long oldPts = 0;%0A        int oldDur = -1;%0A        long editStart = 0;%0A        long totalDur = 0;%0A        IntArrayList durations = IntArrayList.createIntArrayList();%0A        while (chr.hasNext()) %7B%0A            Chunk next = chr.next();%0A            ByteBuffer data = next.getData().duplicate();%0A            int%5B%5D sampleSizes = next.getSampleSizes();%0A            int%5B%5D sampleDurs = next.getSampleDurs();%0A            for (int i = 0; i %3C sampleSizes.length; i++) %7B%0A                int sz = sampleSizes%5Bi%5D;%0A                oldDur = sampleDurs != null ? sampleDurs%5Bi%5D : next.getSampleDur();%0A                ByteBuffer sampleData = NIOUtils.read(data, sz);%0A                long pts = (long) (getPts(sampleData, oldPts, trakBox) * trakBox.getTimescale());%0A                totalDur = pts;%0A                System.out.println(%22old: %22 + oldPts + %22, new: %22 + pts);%0A                oldPts += oldDur;%0A                if (prevPts != -1 && pts %3E= prevPts) %7B%0A                    long dur = pts - prevPts;%0A                    durations.add((int) dur);%0A                    prevPts = pts;%0A                %7D else if (prevPts == -1) %7B%0A                    prevPts = pts;%0A                    editStart = pts;%0A                %7D%0A            %7D%0A        %7D%0A        if (oldDur != -1) %7B%0A            durations.add(oldDur);%0A            totalDur += oldDur;%0A        %7D%0A        trakBox.getStbl().replaceBox(createStts(durations));%0A        if (editStart != 0) %7B%0A            ArrayList%3CEdit%3E edits = new ArrayList%3CEdit%3E();%0A            edits.add(new Edit(-editStart, totalDur - editStart, 1f));%0A            trakBox.setEdits(edits);%0A        %7D%0A    %7D%0A%0A    private Box createStts(IntArrayList durations) %7B%0A        TimeToSampleEntry%5B%5D entries = new TimeToSampleEntry%5Bdurations.size()%5D;%0A        for (int i = 0; i %3C durations.size(); i++)%0A            entries%5Bi%5D = new TimeToSampleEntry(1, durations.get(i));%0A        return TimeToSampleBox.createTimeToSampleBox(entries);%0A    %7D%0A%0A    protected abstract double getPts(ByteBuffer sampleData, double orig, TrakBox trakBox) throws IOException;%0A%7D%0A

Fix timestamp utility