Пример #1
0
    private InterleaveChunkMdat(Movie movie, Map<Track, int[]> chunks, long contentSize) {
      this.contentSize = contentSize;
      this.tracks = movie.getTracks();
      List<Track> tracks = new ArrayList<Track>(chunks.keySet());
      Collections.sort(
          tracks,
          new Comparator<Track>() {
            public int compare(Track o1, Track o2) {
              return l2i(o1.getTrackMetaData().getTrackId() - o2.getTrackMetaData().getTrackId());
            }
          });
      Map<Track, Integer> trackToChunk = new HashMap<Track, Integer>();
      Map<Track, Integer> trackToSample = new HashMap<Track, Integer>();
      Map<Track, Double> trackToTime = new HashMap<Track, Double>();
      for (Track track : tracks) {
        trackToChunk.put(track, 0);
        trackToSample.put(track, 0);
        trackToTime.put(track, 0.0);
      }

      while (true) {
        Track nextChunksTrack = null;
        for (Track track : tracks) {
          if ((nextChunksTrack == null || trackToTime.get(track) < trackToTime.get(nextChunksTrack))
              &&
              // either first OR track's next chunk's starttime is smaller than nextTrack's next
              // chunks starttime
              // AND their need to be chunks left!
              (trackToChunk.get(track) < chunks.get(track).length)) {
            nextChunksTrack = track;
          }
        }
        if (nextChunksTrack == null) {
          break;
        }
        // found the next one

        int nextChunksIndex = trackToChunk.get(nextChunksTrack);
        int numberOfSampleInNextChunk = chunks.get(nextChunksTrack)[nextChunksIndex];
        int startSample = trackToSample.get(nextChunksTrack);
        double time = trackToTime.get(nextChunksTrack);
        for (int j = startSample; j < startSample + numberOfSampleInNextChunk; j++) {
          time +=
              (double) nextChunksTrack.getSampleDurations()[j]
                  / nextChunksTrack.getTrackMetaData().getTimescale();
        }
        chunkList.add(
            nextChunksTrack
                .getSamples()
                .subList(startSample, startSample + numberOfSampleInNextChunk));

        trackToChunk.put(nextChunksTrack, nextChunksIndex + 1);
        trackToSample.put(nextChunksTrack, startSample + numberOfSampleInNextChunk);
        trackToTime.put(nextChunksTrack, time);
      }
    }
Пример #2
0
  protected void createStco(
      Track targetTrack, Movie movie, Map<Track, int[]> chunks, SampleTableBox stbl) {
    if (chunkOffsetBoxes.get(targetTrack) == null) {
      // The ChunkOffsetBox we create here is just a stub
      // since we haven't created the whole structure we can't tell where the
      // first chunk starts (mdat box). So I just let the chunk offset
      // start at zero and I will add the mdat offset later.

      long offset = 0;
      // all tracks have the same number of chunks
      if (LOG.isLoggable(Level.FINE)) {
        LOG.fine(
            "Calculating chunk offsets for track_" + targetTrack.getTrackMetaData().getTrackId());
      }

      List<Track> tracks = new ArrayList<Track>(chunks.keySet());
      Collections.sort(
          tracks,
          new Comparator<Track>() {
            public int compare(Track o1, Track o2) {
              return l2i(o1.getTrackMetaData().getTrackId() - o2.getTrackMetaData().getTrackId());
            }
          });
      Map<Track, Integer> trackToChunk = new HashMap<Track, Integer>();
      Map<Track, Integer> trackToSample = new HashMap<Track, Integer>();
      Map<Track, Double> trackToTime = new HashMap<Track, Double>();
      for (Track track : tracks) {
        trackToChunk.put(track, 0);
        trackToSample.put(track, 0);
        trackToTime.put(track, 0.0);
        chunkOffsetBoxes.put(track, new StaticChunkOffsetBox());
      }

      while (true) {
        Track nextChunksTrack = null;
        for (Track track : tracks) {
          // This always chooses the least progressed track
          if ((nextChunksTrack == null || trackToTime.get(track) < trackToTime.get(nextChunksTrack))
              &&
              // either first OR track's next chunk's starttime is smaller than nextTrack's next
              // chunks starttime
              // AND their need to be chunks left!
              (trackToChunk.get(track) < chunks.get(track).length)) {
            nextChunksTrack = track;
          }
        }
        if (nextChunksTrack == null) {
          break; // no next
        }
        // found the next one
        ChunkOffsetBox chunkOffsetBox = chunkOffsetBoxes.get(nextChunksTrack);
        chunkOffsetBox.setChunkOffsets(
            Mp4Arrays.copyOfAndAppend(chunkOffsetBox.getChunkOffsets(), offset));

        int nextChunksIndex = trackToChunk.get(nextChunksTrack);

        int numberOfSampleInNextChunk = chunks.get(nextChunksTrack)[nextChunksIndex];
        int startSample = trackToSample.get(nextChunksTrack);
        double time = trackToTime.get(nextChunksTrack);

        for (int j = startSample; j < startSample + numberOfSampleInNextChunk; j++) {
          offset += track2SampleSizes.get(nextChunksTrack)[j];
          time +=
              (double) nextChunksTrack.getSampleDurations()[j]
                  / nextChunksTrack.getTrackMetaData().getTimescale();
        }
        trackToChunk.put(nextChunksTrack, nextChunksIndex + 1);
        trackToSample.put(nextChunksTrack, startSample + numberOfSampleInNextChunk);
        trackToTime.put(nextChunksTrack, time);
      }
    }

    stbl.addBox(chunkOffsetBoxes.get(targetTrack));
  }