Skip AnnexB to Avcc conversion for AV1 video format

The AV1 video stream does not contain NAL unit which is a concept
specific to H.264/H.265.
This was not caught before muxer does an in place replacement of
`NAL start code` with `NAL length`. In the absence of `NAL start code`
it was automatically a no-op.

PiperOrigin-RevId: 617193317
This commit is contained in:
sheenachhabra 2024-03-19 09:15:44 -07:00 committed by Copybara-Service
parent e14156aa3b
commit 3272ad50f3
3 changed files with 14 additions and 3 deletions

View File

@ -15,6 +15,7 @@
*/ */
package androidx.media3.muxer; package androidx.media3.muxer;
import androidx.media3.common.MimeTypes;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -87,6 +88,15 @@ import java.nio.ByteBuffer;
return output; return output;
} }
/**
* Returns whether the sample of the given MIME type will contain NAL units in Annex-B format
* (ISO/IEC 14496-10 Annex B, which uses start codes to delineate NAL units).
*/
public static boolean doesSampleContainAnnexBNalUnits(String sampleMimeType) {
return sampleMimeType.equals(MimeTypes.VIDEO_H264)
|| sampleMimeType.equals(MimeTypes.VIDEO_H265);
}
private static ByteBuffer getBytes(ByteBuffer buf, int offset, int length) { private static ByteBuffer getBytes(ByteBuffer buf, int offset, int length) {
ByteBuffer result = buf.duplicate(); ByteBuffer result = buf.duplicate();
result.position(offset); result.position(offset);

View File

@ -18,12 +18,12 @@ package androidx.media3.muxer;
import static androidx.media3.common.util.Assertions.checkArgument; import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.muxer.AnnexBUtils.doesSampleContainAnnexBNalUnits;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.lang.Math.min; import static java.lang.Math.min;
import android.media.MediaCodec.BufferInfo; import android.media.MediaCodec.BufferInfo;
import androidx.media3.common.Format; import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.muxer.Mp4Muxer.TrackToken; import androidx.media3.muxer.Mp4Muxer.TrackToken;
import com.google.common.collect.Range; import com.google.common.collect.Range;
@ -297,7 +297,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
// Convert the H.264/H.265 samples from Annex-B format (output by MediaCodec) to // Convert the H.264/H.265 samples from Annex-B format (output by MediaCodec) to
// Avcc format (required by MP4 container). // Avcc format (required by MP4 container).
if (MimeTypes.isVideo(track.format.sampleMimeType)) { if (doesSampleContainAnnexBNalUnits(checkNotNull(track.format.sampleMimeType))) {
annexBToAvccConverter.process(currentSampleByteBuffer); annexBToAvccConverter.process(currentSampleByteBuffer);
} }

View File

@ -17,6 +17,7 @@ package androidx.media3.muxer;
import static androidx.media3.common.util.Assertions.checkArgument; import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.muxer.AnnexBUtils.doesSampleContainAnnexBNalUnits;
import static androidx.media3.muxer.Boxes.BOX_HEADER_SIZE; import static androidx.media3.muxer.Boxes.BOX_HEADER_SIZE;
import static androidx.media3.muxer.Boxes.MFHD_BOX_CONTENT_SIZE; import static androidx.media3.muxer.Boxes.MFHD_BOX_CONTENT_SIZE;
import static androidx.media3.muxer.Boxes.TFHD_BOX_CONTENT_SIZE; import static androidx.media3.muxer.Boxes.TFHD_BOX_CONTENT_SIZE;
@ -247,7 +248,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// Convert the H.264/H.265 samples from Annex-B format (output by MediaCodec) to // Convert the H.264/H.265 samples from Annex-B format (output by MediaCodec) to
// Avcc format (required by MP4 container). // Avcc format (required by MP4 container).
if (MimeTypes.isVideo(currentTrack.format.sampleMimeType)) { if (doesSampleContainAnnexBNalUnits(checkNotNull(currentTrack.format.sampleMimeType))) {
annexBToAvccConverter.process(currentSampleByteBuffer); annexBToAvccConverter.process(currentSampleByteBuffer);
} }
bytesWritten += output.write(currentSampleByteBuffer); bytesWritten += output.write(currentSampleByteBuffer);