mirror of
https://github.com/samsonjs/media.git
synced 2026-04-09 11:55:46 +00:00
Explicitly set max input size for H264 decoders.
This works around an issue where some devices, such as the Acer Iconia, don't allocate large enough input buffers for H264. Issue: #616 Issue: #714
This commit is contained in:
parent
decb7f58c7
commit
15c2f9c328
3 changed files with 38 additions and 11 deletions
|
|
@ -196,7 +196,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void configureCodec(MediaCodec codec, String codecName,
|
||||
protected void configureCodec(MediaCodec codec, String codecName, boolean codecIsAdaptive,
|
||||
android.media.MediaFormat format, android.media.MediaCrypto crypto) {
|
||||
String mimeType = format.getString(android.media.MediaFormat.KEY_MIME);
|
||||
if (RAW_DECODER_NAME.equals(codecName) && !MimeTypes.AUDIO_RAW.equals(mimeType)) {
|
||||
|
|
|
|||
|
|
@ -269,10 +269,11 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
|||
*
|
||||
* @param codec The {@link MediaCodec} to configure.
|
||||
* @param codecName The name of the codec.
|
||||
* @param codecIsAdaptive Whether the codec is adaptive.
|
||||
* @param format The format for which the codec is being configured.
|
||||
* @param crypto For drm protected playbacks, a {@link MediaCrypto} to use for decryption.
|
||||
*/
|
||||
protected void configureCodec(MediaCodec codec, String codecName,
|
||||
protected void configureCodec(MediaCodec codec, String codecName, boolean codecIsAdaptive,
|
||||
android.media.MediaFormat format, MediaCrypto crypto) {
|
||||
codec.configure(format, null, crypto, 0);
|
||||
}
|
||||
|
|
@ -320,28 +321,29 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
|||
DecoderInitializationException.NO_SUITABLE_DECODER_ERROR));
|
||||
}
|
||||
|
||||
String decoderName = decoderInfo.name;
|
||||
String codecName = decoderInfo.name;
|
||||
codecIsAdaptive = decoderInfo.adaptive;
|
||||
codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(decoderName);
|
||||
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(decoderName);
|
||||
codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(codecName);
|
||||
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
|
||||
try {
|
||||
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
|
||||
TraceUtil.beginSection("createByCodecName(" + decoderName + ")");
|
||||
codec = MediaCodec.createByCodecName(decoderName);
|
||||
TraceUtil.beginSection("createByCodecName(" + codecName + ")");
|
||||
codec = MediaCodec.createByCodecName(codecName);
|
||||
TraceUtil.endSection();
|
||||
TraceUtil.beginSection("configureCodec");
|
||||
configureCodec(codec, decoderName, format.getFrameworkMediaFormatV16(), mediaCrypto);
|
||||
configureCodec(codec, codecName, codecIsAdaptive, format.getFrameworkMediaFormatV16(),
|
||||
mediaCrypto);
|
||||
TraceUtil.endSection();
|
||||
TraceUtil.beginSection("codec.start()");
|
||||
codec.start();
|
||||
TraceUtil.endSection();
|
||||
long codecInitializedTimestamp = SystemClock.elapsedRealtime();
|
||||
notifyDecoderInitialized(decoderName, codecInitializedTimestamp,
|
||||
notifyDecoderInitialized(codecName, codecInitializedTimestamp,
|
||||
codecInitializedTimestamp - codecInitializingTimestamp);
|
||||
inputBuffers = codec.getInputBuffers();
|
||||
outputBuffers = codec.getOutputBuffers();
|
||||
} catch (Exception e) {
|
||||
notifyAndThrowDecoderInitError(new DecoderInitializationException(format, e, decoderName));
|
||||
notifyAndThrowDecoderInitError(new DecoderInitializationException(format, e, codecName));
|
||||
}
|
||||
codecHotswapTimeMs = getState() == TrackRenderer.STATE_STARTED ?
|
||||
SystemClock.elapsedRealtime() : -1;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.google.android.exoplayer.util.MimeTypes;
|
|||
import com.google.android.exoplayer.util.TraceUtil;
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCrypto;
|
||||
|
|
@ -378,8 +379,9 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||
|
||||
// Override configureCodec to provide the surface.
|
||||
@Override
|
||||
protected void configureCodec(MediaCodec codec, String codecName,
|
||||
protected void configureCodec(MediaCodec codec, String codecName, boolean codecIsAdaptive,
|
||||
android.media.MediaFormat format, MediaCrypto crypto) {
|
||||
maybeSetMaxInputSize(format, codecIsAdaptive);
|
||||
codec.configure(format, surface, crypto, 0);
|
||||
codec.setVideoScalingMode(videoScalingMode);
|
||||
}
|
||||
|
|
@ -548,6 +550,29 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
|
|||
maybeNotifyDrawnToSurface();
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
private void maybeSetMaxInputSize(android.media.MediaFormat format, boolean codecIsAdaptive) {
|
||||
if (!MimeTypes.VIDEO_H264.equals(format.getString(android.media.MediaFormat.KEY_MIME))) {
|
||||
// Only set a max input size for H264 for now.
|
||||
return;
|
||||
}
|
||||
if (format.containsKey(android.media.MediaFormat.KEY_MAX_INPUT_SIZE)) {
|
||||
// Already set. The source of the format may know better, so do nothing.
|
||||
return;
|
||||
}
|
||||
int maxHeight = format.getInteger(android.media.MediaFormat.KEY_HEIGHT);
|
||||
if (codecIsAdaptive && format.containsKey(android.media.MediaFormat.KEY_MAX_HEIGHT)) {
|
||||
maxHeight = Math.max(maxHeight, format.getInteger(android.media.MediaFormat.KEY_MAX_HEIGHT));
|
||||
}
|
||||
int maxWidth = format.getInteger(android.media.MediaFormat.KEY_WIDTH);
|
||||
if (codecIsAdaptive && format.containsKey(android.media.MediaFormat.KEY_MAX_WIDTH)) {
|
||||
maxWidth = Math.max(maxHeight, format.getInteger(android.media.MediaFormat.KEY_MAX_WIDTH));
|
||||
}
|
||||
// H264 requires compression ratio of at least 2, and uses macroblocks.
|
||||
int maxInputSize = ((maxWidth + 15) / 16) * ((maxHeight + 15) / 16) * 192;
|
||||
format.setInteger(android.media.MediaFormat.KEY_MAX_INPUT_SIZE, maxInputSize);
|
||||
}
|
||||
|
||||
private void maybeNotifyVideoSizeChanged() {
|
||||
if (eventHandler == null || eventListener == null
|
||||
|| (lastReportedWidth == currentWidth && lastReportedHeight == currentHeight
|
||||
|
|
|
|||
Loading…
Reference in a new issue