Add debug logging when codec support checks fail

Issue: #2034

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=138698239
This commit is contained in:
olly 2016-11-09 16:07:55 -08:00 committed by Oliver Woodman
parent aefc5165fd
commit 2620045b0d
5 changed files with 66 additions and 8 deletions

View File

@ -29,6 +29,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
/** /**
@ -73,7 +74,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
*/ */
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
public ExoPlayerImpl(Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl) { public ExoPlayerImpl(Renderer[] renderers, TrackSelector trackSelector, LoadControl loadControl) {
Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION); Log.i(TAG, "Init " + ExoPlayerLibraryInfo.VERSION + " [" + Util.DEVICE_DEBUG_INFO + "]");
Assertions.checkState(renderers.length > 0); Assertions.checkState(renderers.length > 0);
this.renderers = Assertions.checkNotNull(renderers); this.renderers = Assertions.checkNotNull(renderers);
this.trackSelector = Assertions.checkNotNull(trackSelector); this.trackSelector = Assertions.checkNotNull(trackSelector);

View File

@ -21,6 +21,7 @@ import android.media.MediaCodecInfo.AudioCapabilities;
import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecInfo.CodecProfileLevel; import android.media.MediaCodecInfo.CodecProfileLevel;
import android.media.MediaCodecInfo.VideoCapabilities; import android.media.MediaCodecInfo.VideoCapabilities;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
@ -32,6 +33,8 @@ import com.google.android.exoplayer2.util.Util;
@TargetApi(16) @TargetApi(16)
public final class MediaCodecInfo { public final class MediaCodecInfo {
public static final String TAG = "MediaCodecInfo";
/** /**
* The name of the decoder. * The name of the decoder.
* <p> * <p>
@ -111,6 +114,7 @@ public final class MediaCodecInfo {
return true; return true;
} }
if (!mimeType.equals(codecMimeType)) { if (!mimeType.equals(codecMimeType)) {
logNoSupport("codec.mime " + codec + ", " + codecMimeType);
return false; return false;
} }
Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(codec); Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(codec);
@ -124,6 +128,7 @@ public final class MediaCodecInfo {
return true; return true;
} }
} }
logNoSupport("codec.profileLevel, " + codec + ", " + codecMimeType);
return false; return false;
} }
@ -139,10 +144,19 @@ public final class MediaCodecInfo {
@TargetApi(21) @TargetApi(21)
public boolean isVideoSizeSupportedV21(int width, int height) { public boolean isVideoSizeSupportedV21(int width, int height) {
if (capabilities == null) { if (capabilities == null) {
logNoSupport("size.caps");
return false; return false;
} }
VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities();
return videoCapabilities != null && videoCapabilities.isSizeSupported(width, height); if (videoCapabilities == null) {
logNoSupport("size.vCaps");
return false;
}
if (!videoCapabilities.isSizeSupported(width, height)) {
logNoSupport("size.support, " + width + "x" + height);
return false;
}
return true;
} }
/** /**
@ -158,11 +172,19 @@ public final class MediaCodecInfo {
@TargetApi(21) @TargetApi(21)
public boolean isVideoSizeAndRateSupportedV21(int width, int height, double frameRate) { public boolean isVideoSizeAndRateSupportedV21(int width, int height, double frameRate) {
if (capabilities == null) { if (capabilities == null) {
logNoSupport("sizeAndRate.caps");
return false; return false;
} }
VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities(); VideoCapabilities videoCapabilities = capabilities.getVideoCapabilities();
return videoCapabilities != null && videoCapabilities.areSizeAndRateSupported(width, height, if (videoCapabilities == null) {
frameRate); logNoSupport("sizeAndRate.vCaps");
return false;
}
if (!videoCapabilities.areSizeAndRateSupported(width, height, frameRate)) {
logNoSupport("sizeAndRate.support, " + width + "x" + height + "x" + frameRate);
return false;
}
return true;
} }
/** /**
@ -176,10 +198,19 @@ public final class MediaCodecInfo {
@TargetApi(21) @TargetApi(21)
public boolean isAudioSampleRateSupportedV21(int sampleRate) { public boolean isAudioSampleRateSupportedV21(int sampleRate) {
if (capabilities == null) { if (capabilities == null) {
logNoSupport("sampleRate.caps");
return false; return false;
} }
AudioCapabilities audioCapabilities = capabilities.getAudioCapabilities(); AudioCapabilities audioCapabilities = capabilities.getAudioCapabilities();
return audioCapabilities != null && audioCapabilities.isSampleRateSupported(sampleRate); if (audioCapabilities == null) {
logNoSupport("sampleRate.aCaps");
return false;
}
if (!audioCapabilities.isSampleRateSupported(sampleRate)) {
logNoSupport("sampleRate.support, " + sampleRate);
return false;
}
return true;
} }
/** /**
@ -193,10 +224,24 @@ public final class MediaCodecInfo {
@TargetApi(21) @TargetApi(21)
public boolean isAudioChannelCountSupportedV21(int channelCount) { public boolean isAudioChannelCountSupportedV21(int channelCount) {
if (capabilities == null) { if (capabilities == null) {
logNoSupport("channelCount.caps");
return false; return false;
} }
AudioCapabilities audioCapabilities = capabilities.getAudioCapabilities(); AudioCapabilities audioCapabilities = capabilities.getAudioCapabilities();
return audioCapabilities != null && audioCapabilities.getMaxInputChannelCount() >= channelCount; if (audioCapabilities == null) {
logNoSupport("channelCount.aCaps");
return false;
}
if (audioCapabilities.getMaxInputChannelCount() < channelCount) {
logNoSupport("channelCount.support, " + channelCount);
return false;
}
return true;
}
private void logNoSupport(String message) {
Log.d(TAG, "FalseCheck [" + message + "] [" + name + ", " + mimeType + "] ["
+ Util.DEVICE_DEBUG_INFO + "]");
} }
private static boolean isAdaptive(CodecCapabilities capabilities) { private static boolean isAdaptive(CodecCapabilities capabilities) {

View File

@ -297,8 +297,9 @@ public final class MediaCodecUtil {
for (CodecProfileLevel profileLevel : decoderInfo.getProfileLevels()) { for (CodecProfileLevel profileLevel : decoderInfo.getProfileLevels()) {
result = Math.max(avcLevelToMaxFrameSize(profileLevel.level), result); result = Math.max(avcLevelToMaxFrameSize(profileLevel.level), result);
} }
// We assume support for at least 360p. // We assume support for at least 480p (SDK_INT >= 21) or 360p (SDK_INT < 21), which are
result = Math.max(result, 480 * 360); // the levels mandated by the Android CDD.
result = Math.max(result, Util.SDK_INT >= 21 ? (720 * 480) : (480 * 360));
} }
maxH264DecodableFrameSize = result; maxH264DecodableFrameSize = result;
} }

View File

@ -85,6 +85,12 @@ public final class Util {
*/ */
public static final String MODEL = Build.MODEL; public static final String MODEL = Build.MODEL;
/**
* A concise description of the device that it can be useful to log for debugging purposes.
*/
public static final String DEVICE_DEBUG_INFO = DEVICE + ", " + MODEL + ", " + MANUFACTURER + ", "
+ SDK_INT;
private static final String TAG = "Util"; private static final String TAG = "Util";
private static final Pattern XS_DATE_TIME_PATTERN = Pattern.compile( private static final Pattern XS_DATE_TIME_PATTERN = Pattern.compile(
"(\\d\\d\\d\\d)\\-(\\d\\d)\\-(\\d\\d)[Tt]" "(\\d\\d\\d\\d)\\-(\\d\\d)\\-(\\d\\d)[Tt]"

View File

@ -23,6 +23,7 @@ import android.media.MediaCrypto;
import android.media.MediaFormat; import android.media.MediaFormat;
import android.os.Handler; import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log;
import android.view.Surface; import android.view.Surface;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
@ -198,6 +199,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
} else { } else {
decoderCapable = format.width * format.height <= MediaCodecUtil.maxH264DecodableFrameSize(); decoderCapable = format.width * format.height <= MediaCodecUtil.maxH264DecodableFrameSize();
if (!decoderCapable) {
Log.d(TAG, "FalseCheck [legacyFrameSize, " + format.width + "x" + format.height + "] ["
+ Util.DEVICE_DEBUG_INFO + "]");
}
} }
} }