1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.exoplayer2.extractor.mp4; 17 18 import com.google.android.exoplayer2.C; 19 import com.google.android.exoplayer2.util.Util; 20 21 /** 22 * Rechunks fixed sample size media in which every sample is a key frame (e.g. uncompressed audio). 23 */ 24 /* package */ final class FixedSampleSizeRechunker { 25 26 /** 27 * The result of a rechunking operation. 28 */ 29 public static final class Results { 30 31 public final long[] offsets; 32 public final int[] sizes; 33 public final int maximumSize; 34 public final long[] timestamps; 35 public final int[] flags; 36 public final long duration; 37 Results( long[] offsets, int[] sizes, int maximumSize, long[] timestamps, int[] flags, long duration)38 private Results( 39 long[] offsets, 40 int[] sizes, 41 int maximumSize, 42 long[] timestamps, 43 int[] flags, 44 long duration) { 45 this.offsets = offsets; 46 this.sizes = sizes; 47 this.maximumSize = maximumSize; 48 this.timestamps = timestamps; 49 this.flags = flags; 50 this.duration = duration; 51 } 52 53 } 54 55 /** 56 * Maximum number of bytes for each buffer in rechunked output. 57 */ 58 private static final int MAX_SAMPLE_SIZE = 8 * 1024; 59 60 /** 61 * Rechunk the given fixed sample size input to produce a new sequence of samples. 62 * 63 * @param fixedSampleSize Size in bytes of each sample. 64 * @param chunkOffsets Chunk offsets in the MP4 stream to rechunk. 65 * @param chunkSampleCounts Sample counts for each of the MP4 stream's chunks. 66 * @param timestampDeltaInTimeUnits Timestamp delta between each sample in time units. 67 */ rechunk(int fixedSampleSize, long[] chunkOffsets, int[] chunkSampleCounts, long timestampDeltaInTimeUnits)68 public static Results rechunk(int fixedSampleSize, long[] chunkOffsets, int[] chunkSampleCounts, 69 long timestampDeltaInTimeUnits) { 70 int maxSampleCount = MAX_SAMPLE_SIZE / fixedSampleSize; 71 72 // Count the number of new, rechunked buffers. 73 int rechunkedSampleCount = 0; 74 for (int chunkSampleCount : chunkSampleCounts) { 75 rechunkedSampleCount += Util.ceilDivide(chunkSampleCount, maxSampleCount); 76 } 77 78 long[] offsets = new long[rechunkedSampleCount]; 79 int[] sizes = new int[rechunkedSampleCount]; 80 int maximumSize = 0; 81 long[] timestamps = new long[rechunkedSampleCount]; 82 int[] flags = new int[rechunkedSampleCount]; 83 84 int originalSampleIndex = 0; 85 int newSampleIndex = 0; 86 for (int chunkIndex = 0; chunkIndex < chunkSampleCounts.length; chunkIndex++) { 87 int chunkSamplesRemaining = chunkSampleCounts[chunkIndex]; 88 long sampleOffset = chunkOffsets[chunkIndex]; 89 90 while (chunkSamplesRemaining > 0) { 91 int bufferSampleCount = Math.min(maxSampleCount, chunkSamplesRemaining); 92 93 offsets[newSampleIndex] = sampleOffset; 94 sizes[newSampleIndex] = fixedSampleSize * bufferSampleCount; 95 maximumSize = Math.max(maximumSize, sizes[newSampleIndex]); 96 timestamps[newSampleIndex] = (timestampDeltaInTimeUnits * originalSampleIndex); 97 flags[newSampleIndex] = C.BUFFER_FLAG_KEY_FRAME; 98 99 sampleOffset += sizes[newSampleIndex]; 100 originalSampleIndex += bufferSampleCount; 101 102 chunkSamplesRemaining -= bufferSampleCount; 103 newSampleIndex++; 104 } 105 } 106 long duration = timestampDeltaInTimeUnits * originalSampleIndex; 107 108 return new Results(offsets, sizes, maximumSize, timestamps, flags, duration); 109 } 110 FixedSampleSizeRechunker()111 private FixedSampleSizeRechunker() { 112 // Prevent instantiation. 113 } 114 } 115