mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Move shouldTrancodeAudio/Video to static helper methods
PiperOrigin-RevId: 578617730
This commit is contained in:
parent
a671f4aede
commit
de82aa93f0
2 changed files with 147 additions and 113 deletions
|
|
@ -23,14 +23,13 @@ import static androidx.media3.common.util.Assertions.checkState;
|
||||||
import static androidx.media3.common.util.Util.contains;
|
import static androidx.media3.common.util.Util.contains;
|
||||||
import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_DECODED;
|
import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_DECODED;
|
||||||
import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_ENCODED;
|
import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_ENCODED;
|
||||||
import static androidx.media3.transformer.Composition.HDR_MODE_KEEP_HDR;
|
|
||||||
import static androidx.media3.transformer.ExportException.ERROR_CODE_FAILED_RUNTIME_CHECK;
|
import static androidx.media3.transformer.ExportException.ERROR_CODE_FAILED_RUNTIME_CHECK;
|
||||||
import static androidx.media3.transformer.ExportException.ERROR_CODE_MUXING_FAILED;
|
import static androidx.media3.transformer.ExportException.ERROR_CODE_MUXING_FAILED;
|
||||||
import static androidx.media3.transformer.Transformer.PROGRESS_STATE_AVAILABLE;
|
import static androidx.media3.transformer.Transformer.PROGRESS_STATE_AVAILABLE;
|
||||||
import static androidx.media3.transformer.Transformer.PROGRESS_STATE_NOT_STARTED;
|
import static androidx.media3.transformer.Transformer.PROGRESS_STATE_NOT_STARTED;
|
||||||
import static androidx.media3.transformer.TransformerUtil.areVideoEffectsAllNoOp;
|
|
||||||
import static androidx.media3.transformer.TransformerUtil.containsSlowMotionData;
|
|
||||||
import static androidx.media3.transformer.TransformerUtil.getProcessedTrackType;
|
import static androidx.media3.transformer.TransformerUtil.getProcessedTrackType;
|
||||||
|
import static androidx.media3.transformer.TransformerUtil.shouldTranscodeAudio;
|
||||||
|
import static androidx.media3.transformer.TransformerUtil.shouldTranscodeVideo;
|
||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
|
|
@ -45,14 +44,12 @@ import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.DebugViewProvider;
|
import androidx.media3.common.DebugViewProvider;
|
||||||
import androidx.media3.common.Effect;
|
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.VideoFrameProcessor;
|
import androidx.media3.common.VideoFrameProcessor;
|
||||||
import androidx.media3.common.util.Clock;
|
import androidx.media3.common.util.Clock;
|
||||||
import androidx.media3.common.util.ConditionVariable;
|
import androidx.media3.common.util.ConditionVariable;
|
||||||
import androidx.media3.common.util.HandlerWrapper;
|
import androidx.media3.common.util.HandlerWrapper;
|
||||||
import androidx.media3.effect.ScaleAndRotateTransformation;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
|
@ -445,7 +442,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
private final class SequenceAssetLoaderListener implements AssetLoader.Listener {
|
private final class SequenceAssetLoaderListener implements AssetLoader.Listener {
|
||||||
|
|
||||||
private final int sequenceIndex;
|
private final int sequenceIndex;
|
||||||
private final ImmutableList<EditedMediaItem> editedMediaItems;
|
private final EditedMediaItem firstEditedMediaItem;
|
||||||
private final Composition composition;
|
private final Composition composition;
|
||||||
private final TransformationRequest transformationRequest;
|
private final TransformationRequest transformationRequest;
|
||||||
private final AudioMixer.Factory audioMixerFactory;
|
private final AudioMixer.Factory audioMixerFactory;
|
||||||
|
|
@ -463,7 +460,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
FallbackListener fallbackListener,
|
FallbackListener fallbackListener,
|
||||||
DebugViewProvider debugViewProvider) {
|
DebugViewProvider debugViewProvider) {
|
||||||
this.sequenceIndex = sequenceIndex;
|
this.sequenceIndex = sequenceIndex;
|
||||||
this.editedMediaItems = composition.sequences.get(sequenceIndex).editedMediaItems;
|
this.firstEditedMediaItem = composition.sequences.get(sequenceIndex).editedMediaItems.get(0);
|
||||||
this.composition = composition;
|
this.composition = composition;
|
||||||
this.transformationRequest = transformationRequest;
|
this.transformationRequest = transformationRequest;
|
||||||
this.audioMixerFactory = audioMixerFactory;
|
this.audioMixerFactory = audioMixerFactory;
|
||||||
|
|
@ -535,7 +532,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphInput sampleExporterInput =
|
GraphInput sampleExporterInput =
|
||||||
sampleExporter.getInput(editedMediaItems.get(0), assetLoaderOutputFormat);
|
sampleExporter.getInput(firstEditedMediaItem, assetLoaderOutputFormat);
|
||||||
OnMediaItemChangedListener onMediaItemChangedListener =
|
OnMediaItemChangedListener onMediaItemChangedListener =
|
||||||
(editedMediaItem, durationUs, trackFormat, isLast) -> {
|
(editedMediaItem, durationUs, trackFormat, isLast) -> {
|
||||||
onMediaItemChanged(trackType, durationUs, isLast);
|
onMediaItemChanged(trackType, durationUs, isLast);
|
||||||
|
|
@ -581,7 +578,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
firstAssetLoaderInputFormat,
|
firstAssetLoaderInputFormat,
|
||||||
/* firstInputFormat= */ assetLoaderOutputFormat,
|
/* firstInputFormat= */ assetLoaderOutputFormat,
|
||||||
transformationRequest,
|
transformationRequest,
|
||||||
editedMediaItems.get(0),
|
firstEditedMediaItem,
|
||||||
audioMixerFactory,
|
audioMixerFactory,
|
||||||
encoderFactory,
|
encoderFactory,
|
||||||
muxerWrapper,
|
muxerWrapper,
|
||||||
|
|
@ -680,95 +677,29 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
if (!assetLoaderCanOutputEncoded) {
|
if (!assetLoaderCanOutputEncoded) {
|
||||||
shouldTranscode = true;
|
shouldTranscode = true;
|
||||||
} else if (trackType == TRACK_TYPE_AUDIO) {
|
} else if (trackType == TRACK_TYPE_AUDIO) {
|
||||||
shouldTranscode = shouldTranscodeAudio(inputFormat);
|
shouldTranscode =
|
||||||
|
shouldTranscodeAudio(
|
||||||
|
inputFormat,
|
||||||
|
composition,
|
||||||
|
sequenceIndex,
|
||||||
|
transformationRequest,
|
||||||
|
encoderFactory,
|
||||||
|
muxerWrapper);
|
||||||
} else if (trackType == C.TRACK_TYPE_VIDEO) {
|
} else if (trackType == C.TRACK_TYPE_VIDEO) {
|
||||||
shouldTranscode = shouldTranscodeVideo(inputFormat);
|
shouldTranscode =
|
||||||
|
shouldTranscodeVideo(
|
||||||
|
inputFormat,
|
||||||
|
composition,
|
||||||
|
sequenceIndex,
|
||||||
|
transformationRequest,
|
||||||
|
encoderFactory,
|
||||||
|
muxerWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkState(!shouldTranscode || assetLoaderCanOutputDecoded);
|
checkState(!shouldTranscode || assetLoaderCanOutputDecoded);
|
||||||
|
|
||||||
return shouldTranscode;
|
return shouldTranscode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldTranscodeAudio(Format inputFormat) {
|
|
||||||
if (composition.sequences.size() > 1 || editedMediaItems.size() > 1) {
|
|
||||||
return !composition.transmuxAudio;
|
|
||||||
}
|
|
||||||
if (encoderFactory.audioNeedsEncoding()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (transformationRequest.audioMimeType != null
|
|
||||||
&& !transformationRequest.audioMimeType.equals(inputFormat.sampleMimeType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (transformationRequest.audioMimeType == null
|
|
||||||
&& !muxerWrapper.supportsSampleMimeType(inputFormat.sampleMimeType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
EditedMediaItem firstEditedMediaItem = editedMediaItems.get(0);
|
|
||||||
if (firstEditedMediaItem.flattenForSlowMotion && containsSlowMotionData(inputFormat)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!firstEditedMediaItem.effects.audioProcessors.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean shouldTranscodeVideo(Format inputFormat) {
|
|
||||||
if (composition.sequences.size() > 1 || editedMediaItems.size() > 1) {
|
|
||||||
return !composition.transmuxVideo;
|
|
||||||
}
|
|
||||||
EditedMediaItem firstEditedMediaItem = editedMediaItems.get(0);
|
|
||||||
if (firstEditedMediaItem.mediaItem.clippingConfiguration.startPositionMs > 0
|
|
||||||
&& !firstEditedMediaItem.mediaItem.clippingConfiguration.startsAtKeyFrame) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (encoderFactory.videoNeedsEncoding()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (transformationRequest.hdrMode != HDR_MODE_KEEP_HDR) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (transformationRequest.videoMimeType != null
|
|
||||||
&& !transformationRequest.videoMimeType.equals(inputFormat.sampleMimeType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (transformationRequest.videoMimeType == null
|
|
||||||
&& !muxerWrapper.supportsSampleMimeType(inputFormat.sampleMimeType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (inputFormat.pixelWidthHeightRatio != 1f) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
ImmutableList<Effect> videoEffects = firstEditedMediaItem.effects.videoEffects;
|
|
||||||
return !videoEffects.isEmpty()
|
|
||||||
&& !areVideoEffectsAllNoOp(videoEffects, inputFormat)
|
|
||||||
&& !hasOnlyRegularRotationEffect(videoEffects);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasOnlyRegularRotationEffect(ImmutableList<Effect> videoEffects) {
|
|
||||||
if (videoEffects.size() != 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Effect videoEffect = videoEffects.get(0);
|
|
||||||
if (!(videoEffect instanceof ScaleAndRotateTransformation)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ScaleAndRotateTransformation scaleAndRotateTransformation =
|
|
||||||
(ScaleAndRotateTransformation) videoEffect;
|
|
||||||
if (scaleAndRotateTransformation.scaleX != 1f || scaleAndRotateTransformation.scaleY != 1f) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
float rotationDegrees = scaleAndRotateTransformation.rotationDegrees;
|
|
||||||
if (rotationDegrees == 90f || rotationDegrees == 180f || rotationDegrees == 270f) {
|
|
||||||
// The MuxerWrapper rotation is clockwise while the ScaleAndRotateTransformation rotation
|
|
||||||
// is counterclockwise.
|
|
||||||
muxerWrapper.setAdditionalRotationDegrees(360 - Math.round(rotationDegrees));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tracks the inputs and outputs of {@link AssetLoader AssetLoaders}. */
|
/** Tracks the inputs and outputs of {@link AssetLoader AssetLoaders}. */
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package androidx.media3.transformer;
|
package androidx.media3.transformer;
|
||||||
|
|
||||||
|
import static androidx.media3.transformer.Composition.HDR_MODE_KEEP_HDR;
|
||||||
|
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
|
|
@ -24,6 +26,7 @@ import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.Metadata;
|
import androidx.media3.common.Metadata;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.effect.GlEffect;
|
import androidx.media3.effect.GlEffect;
|
||||||
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.extractor.metadata.mp4.SlowMotionData;
|
import androidx.media3.extractor.metadata.mp4.SlowMotionData;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
|
@ -45,6 +48,110 @@ import com.google.common.collect.ImmutableList;
|
||||||
return trackType == C.TRACK_TYPE_IMAGE ? C.TRACK_TYPE_VIDEO : trackType;
|
return trackType == C.TRACK_TYPE_IMAGE ? C.TRACK_TYPE_VIDEO : trackType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns {@link MediaCodec} flags corresponding to {@link C.BufferFlags}. */
|
||||||
|
public static int getMediaCodecFlags(@C.BufferFlags int flags) {
|
||||||
|
int mediaCodecFlags = 0;
|
||||||
|
if ((flags & C.BUFFER_FLAG_KEY_FRAME) == C.BUFFER_FLAG_KEY_FRAME) {
|
||||||
|
mediaCodecFlags |= MediaCodec.BUFFER_FLAG_KEY_FRAME;
|
||||||
|
}
|
||||||
|
if ((flags & C.BUFFER_FLAG_END_OF_STREAM) == C.BUFFER_FLAG_END_OF_STREAM) {
|
||||||
|
mediaCodecFlags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
|
||||||
|
}
|
||||||
|
return mediaCodecFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether the audio track should be transcoded. */
|
||||||
|
public static boolean shouldTranscodeAudio(
|
||||||
|
Format inputFormat,
|
||||||
|
Composition composition,
|
||||||
|
int sequenceIndex,
|
||||||
|
TransformationRequest transformationRequest,
|
||||||
|
Codec.EncoderFactory encoderFactory,
|
||||||
|
MuxerWrapper muxerWrapper) {
|
||||||
|
if (composition.sequences.size() > 1
|
||||||
|
|| composition.sequences.get(sequenceIndex).editedMediaItems.size() > 1) {
|
||||||
|
return !composition.transmuxAudio;
|
||||||
|
}
|
||||||
|
if (encoderFactory.audioNeedsEncoding()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (transformationRequest.audioMimeType != null
|
||||||
|
&& !transformationRequest.audioMimeType.equals(inputFormat.sampleMimeType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (transformationRequest.audioMimeType == null
|
||||||
|
&& !muxerWrapper.supportsSampleMimeType(inputFormat.sampleMimeType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
EditedMediaItem firstEditedMediaItem =
|
||||||
|
composition.sequences.get(sequenceIndex).editedMediaItems.get(0);
|
||||||
|
if (firstEditedMediaItem.flattenForSlowMotion && containsSlowMotionData(inputFormat)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!firstEditedMediaItem.effects.audioProcessors.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the {@link Format} contains {@linkplain SlowMotionData slow motion metadata}.
|
||||||
|
*/
|
||||||
|
private static boolean containsSlowMotionData(Format format) {
|
||||||
|
@Nullable Metadata metadata = format.metadata;
|
||||||
|
if (metadata == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < metadata.length(); i++) {
|
||||||
|
if (metadata.get(i) instanceof SlowMotionData) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether the video track should be transcoded. */
|
||||||
|
public static boolean shouldTranscodeVideo(
|
||||||
|
Format inputFormat,
|
||||||
|
Composition composition,
|
||||||
|
int sequenceIndex,
|
||||||
|
TransformationRequest transformationRequest,
|
||||||
|
Codec.EncoderFactory encoderFactory,
|
||||||
|
MuxerWrapper muxerWrapper) {
|
||||||
|
|
||||||
|
if (composition.sequences.size() > 1
|
||||||
|
|| composition.sequences.get(sequenceIndex).editedMediaItems.size() > 1) {
|
||||||
|
return !composition.transmuxVideo;
|
||||||
|
}
|
||||||
|
EditedMediaItem firstEditedMediaItem =
|
||||||
|
composition.sequences.get(sequenceIndex).editedMediaItems.get(0);
|
||||||
|
if (firstEditedMediaItem.mediaItem.clippingConfiguration.startPositionMs > 0
|
||||||
|
&& !firstEditedMediaItem.mediaItem.clippingConfiguration.startsAtKeyFrame) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (encoderFactory.videoNeedsEncoding()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (transformationRequest.hdrMode != HDR_MODE_KEEP_HDR) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (transformationRequest.videoMimeType != null
|
||||||
|
&& !transformationRequest.videoMimeType.equals(inputFormat.sampleMimeType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (transformationRequest.videoMimeType == null
|
||||||
|
&& !muxerWrapper.supportsSampleMimeType(inputFormat.sampleMimeType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (inputFormat.pixelWidthHeightRatio != 1f) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ImmutableList<Effect> videoEffects = firstEditedMediaItem.effects.videoEffects;
|
||||||
|
return !videoEffects.isEmpty()
|
||||||
|
&& !areVideoEffectsAllNoOp(videoEffects, inputFormat)
|
||||||
|
&& !hasOnlyRegularRotationEffect(videoEffects, muxerWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the collection of {@code videoEffects} would be a {@linkplain
|
* Returns whether the collection of {@code videoEffects} would be a {@linkplain
|
||||||
* GlEffect#isNoOp(int, int) no-op}, if queued samples of this {@link Format}.
|
* GlEffect#isNoOp(int, int) no-op}, if queued samples of this {@link Format}.
|
||||||
|
|
@ -70,31 +177,27 @@ import com.google.common.collect.ImmutableList;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static boolean hasOnlyRegularRotationEffect(
|
||||||
* Returns whether the {@link Format} contains {@linkplain SlowMotionData slow motion metadata}.
|
ImmutableList<Effect> videoEffects, MuxerWrapper muxerWrapper) {
|
||||||
*/
|
if (videoEffects.size() != 1) {
|
||||||
public static boolean containsSlowMotionData(Format format) {
|
|
||||||
@Nullable Metadata metadata = format.metadata;
|
|
||||||
if (metadata == null) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < metadata.length(); i++) {
|
Effect videoEffect = videoEffects.get(0);
|
||||||
if (metadata.get(i) instanceof SlowMotionData) {
|
if (!(videoEffect instanceof ScaleAndRotateTransformation)) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
ScaleAndRotateTransformation scaleAndRotateTransformation =
|
||||||
|
(ScaleAndRotateTransformation) videoEffect;
|
||||||
|
if (scaleAndRotateTransformation.scaleX != 1f || scaleAndRotateTransformation.scaleY != 1f) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
float rotationDegrees = scaleAndRotateTransformation.rotationDegrees;
|
||||||
|
if (rotationDegrees == 90f || rotationDegrees == 180f || rotationDegrees == 270f) {
|
||||||
|
// The MuxerWrapper rotation is clockwise while the ScaleAndRotateTransformation rotation
|
||||||
|
// is counterclockwise.
|
||||||
|
muxerWrapper.setAdditionalRotationDegrees(360 - Math.round(rotationDegrees));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns {@link MediaCodec} flags corresponding to {@link C.BufferFlags}. */
|
|
||||||
public static int getMediaCodecFlags(@C.BufferFlags int flags) {
|
|
||||||
int mediaCodecFlags = 0;
|
|
||||||
if ((flags & C.BUFFER_FLAG_KEY_FRAME) == C.BUFFER_FLAG_KEY_FRAME) {
|
|
||||||
mediaCodecFlags |= MediaCodec.BUFFER_FLAG_KEY_FRAME;
|
|
||||||
}
|
|
||||||
if ((flags & C.BUFFER_FLAG_END_OF_STREAM) == C.BUFFER_FLAG_END_OF_STREAM) {
|
|
||||||
mediaCodecFlags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
|
|
||||||
}
|
|
||||||
return mediaCodecFlags;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue