OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 package org.webrtc; | 11 package org.webrtc; |
12 | 12 |
13 import static org.webrtc.MediaCodecUtils.EXYNOS_PREFIX; | 13 import static org.webrtc.MediaCodecUtils.EXYNOS_PREFIX; |
14 import static org.webrtc.MediaCodecUtils.INTEL_PREFIX; | 14 import static org.webrtc.MediaCodecUtils.INTEL_PREFIX; |
15 import static org.webrtc.MediaCodecUtils.QCOM_PREFIX; | 15 import static org.webrtc.MediaCodecUtils.QCOM_PREFIX; |
16 | 16 |
17 import android.media.MediaCodec; | |
18 import android.media.MediaCodecInfo; | 17 import android.media.MediaCodecInfo; |
19 import android.media.MediaCodecInfo.CodecCapabilities; | |
20 import android.media.MediaCodecList; | 18 import android.media.MediaCodecList; |
21 import android.os.Build; | 19 import android.os.Build; |
| 20 import java.util.ArrayList; |
22 import java.util.Arrays; | 21 import java.util.Arrays; |
23 import java.util.ArrayList; | |
24 import java.util.HashMap; | 22 import java.util.HashMap; |
25 import java.util.List; | 23 import java.util.List; |
26 import java.util.Map; | 24 import java.util.Map; |
27 | 25 |
28 /** Factory for android hardware video encoders. */ | 26 /** Factory for android hardware video encoders. */ |
29 @SuppressWarnings("deprecation") // API 16 requires the use of deprecated method
s. | 27 @SuppressWarnings("deprecation") // API 16 requires the use of deprecated method
s. |
30 public class HardwareVideoEncoderFactory implements VideoEncoderFactory { | 28 public class HardwareVideoEncoderFactory implements VideoEncoderFactory { |
31 private static final String TAG = "HardwareVideoEncoderFactory"; | 29 private static final String TAG = "HardwareVideoEncoderFactory"; |
32 | 30 |
33 // Forced key frame interval - used to reduce color distortions on Qualcomm pl
atforms. | 31 // Forced key frame interval - used to reduce color distortions on Qualcomm pl
atforms. |
34 private static final int QCOM_VP8_KEY_FRAME_INTERVAL_ANDROID_L_MS = 15000; | 32 private static final int QCOM_VP8_KEY_FRAME_INTERVAL_ANDROID_L_MS = 15000; |
35 private static final int QCOM_VP8_KEY_FRAME_INTERVAL_ANDROID_M_MS = 20000; | 33 private static final int QCOM_VP8_KEY_FRAME_INTERVAL_ANDROID_M_MS = 20000; |
36 private static final int QCOM_VP8_KEY_FRAME_INTERVAL_ANDROID_N_MS = 15000; | 34 private static final int QCOM_VP8_KEY_FRAME_INTERVAL_ANDROID_N_MS = 15000; |
37 | 35 |
38 // List of devices with poor H.264 encoder quality. | 36 // List of devices with poor H.264 encoder quality. |
39 // HW H.264 encoder on below devices has poor bitrate control - actual | 37 // HW H.264 encoder on below devices has poor bitrate control - actual |
40 // bitrates deviates a lot from the target value. | 38 // bitrates deviates a lot from the target value. |
41 private static final List<String> H264_HW_EXCEPTION_MODELS = | 39 private static final List<String> H264_HW_EXCEPTION_MODELS = |
42 Arrays.asList("SAMSUNG-SGH-I337", "Nexus 7", "Nexus 4"); | 40 Arrays.asList("SAMSUNG-SGH-I337", "Nexus 7", "Nexus 4"); |
43 | 41 |
44 // Keys for H264 VideoCodecInfo properties. | |
45 private static final String H264_FMTP_PROFILE_LEVEL_ID = "profile-level-id"; | |
46 private static final String H264_FMTP_LEVEL_ASYMMETRY_ALLOWED = "level-asymmet
ry-allowed"; | |
47 private static final String H264_FMTP_PACKETIZATION_MODE = "packetization-mode
"; | |
48 | |
49 // Supported H264 profile ids and levels. | |
50 private static final String H264_PROFILE_CONSTRAINED_BASELINE = "4200"; | |
51 private static final String H264_PROFILE_CONSTRAINED_HIGH = "640c"; | |
52 private static final String H264_LEVEL_3_1 = "1f"; // 31 in hex. | |
53 private static final String H264_CONSTRAINED_BASELINE_3_1 = | |
54 H264_PROFILE_CONSTRAINED_BASELINE + H264_LEVEL_3_1; | |
55 private static final String H264_CONSTRAINED_HIGH_3_1 = | |
56 H264_PROFILE_CONSTRAINED_HIGH + H264_LEVEL_3_1; | |
57 | |
58 private final EglBase14.Context sharedContext; | 42 private final EglBase14.Context sharedContext; |
59 private final boolean enableIntelVp8Encoder; | 43 private final boolean enableIntelVp8Encoder; |
60 private final boolean enableH264HighProfile; | 44 private final boolean enableH264HighProfile; |
61 | 45 |
62 public HardwareVideoEncoderFactory( | 46 public HardwareVideoEncoderFactory( |
63 EglBase.Context sharedContext, boolean enableIntelVp8Encoder, boolean enab
leH264HighProfile) { | 47 EglBase.Context sharedContext, boolean enableIntelVp8Encoder, boolean enab
leH264HighProfile) { |
64 // Texture mode requires EglBase14. | 48 // Texture mode requires EglBase14. |
65 if (sharedContext instanceof EglBase14.Context) { | 49 if (sharedContext instanceof EglBase14.Context) { |
66 this.sharedContext = (EglBase14.Context) sharedContext; | 50 this.sharedContext = (EglBase14.Context) sharedContext; |
67 } else { | 51 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
86 return null; // No support for this type. | 70 return null; // No support for this type. |
87 } | 71 } |
88 | 72 |
89 String codecName = info.getName(); | 73 String codecName = info.getName(); |
90 String mime = type.mimeType(); | 74 String mime = type.mimeType(); |
91 int colorFormat = MediaCodecUtils.selectColorFormat(sharedContext == null | 75 int colorFormat = MediaCodecUtils.selectColorFormat(sharedContext == null |
92 ? MediaCodecUtils.ENCODER_COLOR_FORMATS | 76 ? MediaCodecUtils.ENCODER_COLOR_FORMATS |
93 : MediaCodecUtils.TEXTURE_COLOR_FORMATS, | 77 : MediaCodecUtils.TEXTURE_COLOR_FORMATS, |
94 info.getCapabilitiesForType(mime)); | 78 info.getCapabilitiesForType(mime)); |
95 | 79 |
96 return new HardwareVideoEncoder(codecName, type, colorFormat, getKeyFrameInt
ervalSec(type), | 80 return new HardwareVideoEncoder(codecName, type, colorFormat, input.params, |
97 getForcedKeyFrameIntervalMs(type, codecName), createBitrateAdjuster(type
, codecName), | 81 getKeyFrameIntervalSec(type), getForcedKeyFrameIntervalMs(type, codecNam
e), |
98 sharedContext); | 82 createBitrateAdjuster(type, codecName), sharedContext); |
99 } | 83 } |
100 | 84 |
101 @Override | 85 @Override |
102 public VideoCodecInfo[] getSupportedCodecs() { | 86 public VideoCodecInfo[] getSupportedCodecs() { |
103 List<VideoCodecInfo> supportedCodecInfos = new ArrayList<VideoCodecInfo>(); | 87 List<VideoCodecInfo> supportedCodecInfos = new ArrayList<VideoCodecInfo>(); |
104 // Generate a list of supported codecs in order of preference: | 88 // Generate a list of supported codecs in order of preference: |
105 // VP8, VP9, H264 (high profile), and H264 (baseline profile). | 89 // VP8, VP9, H264 (high profile), and H264 (baseline profile). |
106 for (VideoCodecType type : | 90 for (VideoCodecType type : |
107 new VideoCodecType[] {VideoCodecType.VP8, VideoCodecType.VP9, VideoCodec
Type.H264}) { | 91 new VideoCodecType[] {VideoCodecType.VP8, VideoCodecType.VP9, VideoCodec
Type.H264}) { |
108 MediaCodecInfo codec = findCodecForType(type); | 92 MediaCodecInfo codec = findCodecForType(type); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 return enableH264HighProfile && info.getName().startsWith(QCOM_PREFIX); | 227 return enableH264HighProfile && info.getName().startsWith(QCOM_PREFIX); |
244 } | 228 } |
245 | 229 |
246 private Map<String, String> getCodecProperties(VideoCodecType type, boolean hi
ghProfile) { | 230 private Map<String, String> getCodecProperties(VideoCodecType type, boolean hi
ghProfile) { |
247 switch (type) { | 231 switch (type) { |
248 case VP8: | 232 case VP8: |
249 case VP9: | 233 case VP9: |
250 return new HashMap<String, String>(); | 234 return new HashMap<String, String>(); |
251 case H264: | 235 case H264: |
252 Map<String, String> properties = new HashMap<>(); | 236 Map<String, String> properties = new HashMap<>(); |
253 properties.put(H264_FMTP_LEVEL_ASYMMETRY_ALLOWED, "1"); | 237 properties.put(VideoCodecInfo.H264_FMTP_LEVEL_ASYMMETRY_ALLOWED, "1"); |
254 properties.put(H264_FMTP_PACKETIZATION_MODE, "1"); | 238 properties.put(VideoCodecInfo.H264_FMTP_PACKETIZATION_MODE, "1"); |
255 properties.put(H264_FMTP_PROFILE_LEVEL_ID, | 239 properties.put(VideoCodecInfo.H264_FMTP_PROFILE_LEVEL_ID, |
256 highProfile ? H264_CONSTRAINED_HIGH_3_1 : H264_CONSTRAINED_BASELINE_
3_1); | 240 highProfile ? VideoCodecInfo.H264_CONSTRAINED_HIGH_3_1 |
| 241 : VideoCodecInfo.H264_CONSTRAINED_BASELINE_3_1); |
257 return properties; | 242 return properties; |
258 default: | 243 default: |
259 throw new IllegalArgumentException("Unsupported codec: " + type); | 244 throw new IllegalArgumentException("Unsupported codec: " + type); |
260 } | 245 } |
261 } | 246 } |
262 } | 247 } |
OLD | NEW |