use of android.media.MediaFormat in project ExoPlayer by google.
the class MediaCodecAudioRenderer method getMediaCodecConfiguration.
@Override
protected MediaCodecAdapter.Configuration getMediaCodecConfiguration(MediaCodecInfo codecInfo, Format format, @Nullable MediaCrypto crypto, float codecOperatingRate) {
codecMaxInputSize = getCodecMaxInputSize(codecInfo, format, getStreamFormats());
codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name);
MediaFormat mediaFormat = getMediaFormat(format, codecInfo.codecMimeType, codecMaxInputSize, codecOperatingRate);
// Store the input MIME type if we're only using the codec for decryption.
boolean decryptOnlyCodecEnabled = MimeTypes.AUDIO_RAW.equals(codecInfo.mimeType) && !MimeTypes.AUDIO_RAW.equals(format.sampleMimeType);
decryptOnlyCodecFormat = decryptOnlyCodecEnabled ? format : null;
return MediaCodecAdapter.Configuration.createForAudioDecoding(codecInfo, mediaFormat, format, crypto);
}
use of android.media.MediaFormat in project ExoPlayer by google.
the class AsynchronousMediaCodecBufferEnqueuerTest method setUp.
@Before
public void setUp() throws IOException {
codec = MediaCodec.createByCodecName("h264");
codec.configure(new MediaFormat(), /* surface= */
null, /* crypto= */
null, /* flags= */
0);
codec.start();
handlerThread = new TestHandlerThread("TestHandlerThread");
enqueuer = new AsynchronousMediaCodecBufferEnqueuer(codec, handlerThread, mockConditionVariable);
}
use of android.media.MediaFormat in project ExoPlayer by google.
the class AsynchronousMediaCodecCallbackTest method dequeOutputBufferIndex_withPendingOutputFormat_returnsPendingOutputFormat.
@Test
public void dequeOutputBufferIndex_withPendingOutputFormat_returnsPendingOutputFormat() {
MediaCodec.BufferInfo outBufferInfo = new MediaCodec.BufferInfo();
Looper callbackThreadLooper = callbackThread.getLooper();
AtomicBoolean flushCompleted = new AtomicBoolean();
asynchronousMediaCodecCallback.onOutputFormatChanged(codec, new MediaFormat());
asynchronousMediaCodecCallback.onOutputBufferAvailable(codec, /* index= */
0, outBufferInfo);
MediaFormat pendingMediaFormat = new MediaFormat();
asynchronousMediaCodecCallback.onOutputFormatChanged(codec, pendingMediaFormat);
// flush() should not discard the last format.
asynchronousMediaCodecCallback.flush(/* codec= */
null);
new Handler(callbackThreadLooper).post(() -> flushCompleted.set(true));
// Progress the callback looper so that flush() completes.
shadowOf(callbackThreadLooper).idle();
// Right after flush(), we send an output buffer: the pending output format should be
// dequeued first.
asynchronousMediaCodecCallback.onOutputBufferAvailable(codec, /* index= */
1, outBufferInfo);
assertThat(flushCompleted.get()).isTrue();
assertThat(asynchronousMediaCodecCallback.dequeueOutputBufferIndex(outBufferInfo)).isEqualTo(MediaCodec.INFO_OUTPUT_FORMAT_CHANGED);
assertThat(asynchronousMediaCodecCallback.getOutputFormat()).isEqualTo(pendingMediaFormat);
assertThat(asynchronousMediaCodecCallback.dequeueOutputBufferIndex(outBufferInfo)).isEqualTo(1);
}
use of android.media.MediaFormat in project ExoPlayer by google.
the class MediaCodecVideoRenderer method getMediaFormat.
/**
* Returns the framework {@link MediaFormat} that should be used to configure the decoder.
*
* @param format The {@link Format} of media.
* @param codecMimeType The MIME type handled by the codec.
* @param codecMaxValues Codec max values that should be used when configuring the decoder.
* @param codecOperatingRate The codec operating rate, or {@link #CODEC_OPERATING_RATE_UNSET} if
* no codec operating rate should be set.
* @param deviceNeedsNoPostProcessWorkaround Whether the device is known to do post processing by
* default that isn't compatible with ExoPlayer.
* @param tunnelingAudioSessionId The audio session id to use for tunneling, or {@link
* C#AUDIO_SESSION_ID_UNSET} if tunneling should not be enabled.
* @return The framework {@link MediaFormat} that should be used to configure the decoder.
*/
@SuppressLint("InlinedApi")
// tunnelingAudioSessionId is unset if Util.SDK_INT < 21
@TargetApi(21)
protected MediaFormat getMediaFormat(Format format, String codecMimeType, CodecMaxValues codecMaxValues, float codecOperatingRate, boolean deviceNeedsNoPostProcessWorkaround, int tunnelingAudioSessionId) {
MediaFormat mediaFormat = new MediaFormat();
// Set format parameters that should always be set.
mediaFormat.setString(MediaFormat.KEY_MIME, codecMimeType);
mediaFormat.setInteger(MediaFormat.KEY_WIDTH, format.width);
mediaFormat.setInteger(MediaFormat.KEY_HEIGHT, format.height);
MediaFormatUtil.setCsdBuffers(mediaFormat, format.initializationData);
// Set format parameters that may be unset.
MediaFormatUtil.maybeSetFloat(mediaFormat, MediaFormat.KEY_FRAME_RATE, format.frameRate);
MediaFormatUtil.maybeSetInteger(mediaFormat, MediaFormat.KEY_ROTATION, format.rotationDegrees);
MediaFormatUtil.maybeSetColorInfo(mediaFormat, format.colorInfo);
if (MimeTypes.VIDEO_DOLBY_VISION.equals(format.sampleMimeType)) {
// Some phones require the profile to be set on the codec.
// See https://github.com/google/ExoPlayer/pull/5438.
Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format);
if (codecProfileAndLevel != null) {
MediaFormatUtil.maybeSetInteger(mediaFormat, MediaFormat.KEY_PROFILE, codecProfileAndLevel.first);
}
}
// Set codec max values.
mediaFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, codecMaxValues.width);
mediaFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, codecMaxValues.height);
MediaFormatUtil.maybeSetInteger(mediaFormat, MediaFormat.KEY_MAX_INPUT_SIZE, codecMaxValues.inputSize);
// Set codec configuration values.
if (Util.SDK_INT >= 23) {
mediaFormat.setInteger(MediaFormat.KEY_PRIORITY, 0);
if (codecOperatingRate != CODEC_OPERATING_RATE_UNSET) {
mediaFormat.setFloat(MediaFormat.KEY_OPERATING_RATE, codecOperatingRate);
}
}
if (deviceNeedsNoPostProcessWorkaround) {
mediaFormat.setInteger("no-post-process", 1);
mediaFormat.setInteger("auto-frc", 0);
}
if (tunnelingAudioSessionId != C.AUDIO_SESSION_ID_UNSET) {
configureTunnelingV21(mediaFormat, tunnelingAudioSessionId);
}
return mediaFormat;
}
use of android.media.MediaFormat in project ExoPlayer by google.
the class DefaultCodecFactory method createForVideoEncoding.
@Override
public Codec createForVideoEncoding(Format format, List<String> allowedMimeTypes) throws TransformationException {
checkArgument(format.width != Format.NO_VALUE);
checkArgument(format.height != Format.NO_VALUE);
// According to interface Javadoc, format.rotationDegrees should be 0. The video should always
// be in landscape orientation.
checkArgument(format.height <= format.width);
checkArgument(format.rotationDegrees == 0);
checkNotNull(format.sampleMimeType);
checkArgument(!allowedMimeTypes.isEmpty());
format = getVideoEncoderSupportedFormat(format, allowedMimeTypes);
MediaFormat mediaFormat = MediaFormat.createVideoFormat(checkNotNull(format.sampleMimeType), format.width, format.height);
mediaFormat.setFloat(MediaFormat.KEY_FRAME_RATE, format.frameRate);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, format.averageBitrate);
@Nullable Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format);
if (codecProfileAndLevel != null) {
mediaFormat.setInteger(MediaFormat.KEY_PROFILE, codecProfileAndLevel.first);
if (SDK_INT >= 23) {
mediaFormat.setInteger(MediaFormat.KEY_LEVEL, codecProfileAndLevel.second);
}
}
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, DEFAULT_COLOR_FORMAT);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, DEFAULT_I_FRAME_INTERVAL_SECS);
return createCodec(format, mediaFormat, /* isVideo= */
true, /* isDecoder= */
false, /* outputSurface= */
null);
}
Aggregations