Add list of devices with HW H.264 encoder non suitable for WebRTC.
For now add only Galaxy S4 to the list, since its H.264 HW encoder generates two times lower bitrate comparing to target. Also use VBR mode for H.264 encoder configuration. R=wzh@webrtc.org Review URL: https://codereview.webrtc.org/1270603007 . Cr-Commit-Position: refs/heads/master@{#9673}
This commit is contained in:
@ -38,6 +38,8 @@ import android.os.Bundle;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
// Java-side of peerconnection_jni.cc:MediaCodecVideoEncoder.
|
// Java-side of peerconnection_jni.cc:MediaCodecVideoEncoder.
|
||||||
// This class is an implementation detail of the Java PeerConnection API.
|
// This class is an implementation detail of the Java PeerConnection API.
|
||||||
@ -70,6 +72,13 @@ public class MediaCodecVideoEncoder {
|
|||||||
// List of supported HW H.264 codecs.
|
// List of supported HW H.264 codecs.
|
||||||
private static final String[] supportedH264HwCodecPrefixes =
|
private static final String[] supportedH264HwCodecPrefixes =
|
||||||
{"OMX.qcom." };
|
{"OMX.qcom." };
|
||||||
|
// List of devices with poor H.264 encoder quality.
|
||||||
|
private static final String[] H264_HW_EXCEPTION_MODELS = new String[] {
|
||||||
|
// HW H.264 encoder on Galaxy S4 generates 2 times lower bitrate comparing
|
||||||
|
// to target.
|
||||||
|
"SAMSUNG-SGH-I337",
|
||||||
|
};
|
||||||
|
|
||||||
// Bitrate modes - should be in sync with OMX_VIDEO_CONTROLRATETYPE defined
|
// Bitrate modes - should be in sync with OMX_VIDEO_CONTROLRATETYPE defined
|
||||||
// in OMX_Video.h
|
// in OMX_Video.h
|
||||||
private static final int VIDEO_ControlRateVariable = 1;
|
private static final int VIDEO_ControlRateVariable = 1;
|
||||||
@ -105,8 +114,21 @@ public class MediaCodecVideoEncoder {
|
|||||||
|
|
||||||
private static EncoderProperties findHwEncoder(
|
private static EncoderProperties findHwEncoder(
|
||||||
String mime, String[] supportedHwCodecPrefixes) {
|
String mime, String[] supportedHwCodecPrefixes) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
|
// MediaCodec.setParameters is missing for JB and below, so bitrate
|
||||||
return null; // MediaCodec.setParameters is missing.
|
// can not be adjusted dynamically.
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if device is in H.264 exception list.
|
||||||
|
if (mime.equals(H264_MIME_TYPE)) {
|
||||||
|
List<String> exceptionModels = Arrays.asList(H264_HW_EXCEPTION_MODELS);
|
||||||
|
if (exceptionModels.contains(Build.MODEL)) {
|
||||||
|
Log.w(TAG, "Model: " + Build.MODEL +
|
||||||
|
" has black listed H.264 encoder.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
|
for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
|
||||||
MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
|
MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
|
||||||
@ -196,13 +218,16 @@ public class MediaCodecVideoEncoder {
|
|||||||
EncoderProperties properties = null;
|
EncoderProperties properties = null;
|
||||||
String mime = null;
|
String mime = null;
|
||||||
int keyFrameIntervalSec = 0;
|
int keyFrameIntervalSec = 0;
|
||||||
|
int bitrateMode = 0;
|
||||||
if (type == VideoCodecType.VIDEO_CODEC_VP8) {
|
if (type == VideoCodecType.VIDEO_CODEC_VP8) {
|
||||||
mime = VP8_MIME_TYPE;
|
mime = VP8_MIME_TYPE;
|
||||||
properties = findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes);
|
properties = findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes);
|
||||||
keyFrameIntervalSec = 100;
|
keyFrameIntervalSec = 100;
|
||||||
|
bitrateMode = VIDEO_ControlRateConstant;
|
||||||
} else if (type == VideoCodecType.VIDEO_CODEC_H264) {
|
} else if (type == VideoCodecType.VIDEO_CODEC_H264) {
|
||||||
mime = H264_MIME_TYPE;
|
mime = H264_MIME_TYPE;
|
||||||
properties = findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes);
|
properties = findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes);
|
||||||
|
bitrateMode = VIDEO_ControlRateVariable;
|
||||||
keyFrameIntervalSec = 20;
|
keyFrameIntervalSec = 20;
|
||||||
}
|
}
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
@ -212,7 +237,7 @@ public class MediaCodecVideoEncoder {
|
|||||||
try {
|
try {
|
||||||
MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
|
MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
|
||||||
format.setInteger(MediaFormat.KEY_BIT_RATE, 1000 * kbps);
|
format.setInteger(MediaFormat.KEY_BIT_RATE, 1000 * kbps);
|
||||||
format.setInteger("bitrate-mode", VIDEO_ControlRateConstant);
|
format.setInteger("bitrate-mode", bitrateMode);
|
||||||
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
|
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
|
||||||
format.setInteger(MediaFormat.KEY_FRAME_RATE, fps);
|
format.setInteger(MediaFormat.KEY_FRAME_RATE, fps);
|
||||||
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec);
|
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec);
|
||||||
|
Reference in New Issue
Block a user