Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: webrtc/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java

Issue 3007133002: Add support for H264 high-profile in injectable video encoder. (Closed)
Patch Set: Rebase Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/sdk/android/api/org/webrtc/VideoCodecInfo.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 android.annotation.TargetApi; 13 import android.annotation.TargetApi;
14 import android.graphics.Matrix; 14 import android.graphics.Matrix;
15 import android.media.MediaCodec; 15 import android.media.MediaCodec;
16 import android.media.MediaCodecInfo; 16 import android.media.MediaCodecInfo;
17 import android.media.MediaFormat; 17 import android.media.MediaFormat;
18 import android.opengl.GLES20; 18 import android.opengl.GLES20;
19 import android.os.Bundle; 19 import android.os.Bundle;
20 import android.view.Surface; 20 import android.view.Surface;
21 import java.io.IOException; 21 import java.io.IOException;
22 import java.nio.ByteBuffer; 22 import java.nio.ByteBuffer;
23 import java.util.Arrays;
24 import java.util.Deque; 23 import java.util.Deque;
25 import java.util.HashSet; 24 import java.util.Map;
26 import java.util.Set;
27 import java.util.concurrent.LinkedBlockingDeque; 25 import java.util.concurrent.LinkedBlockingDeque;
28 import java.util.concurrent.TimeUnit; 26 import java.util.concurrent.TimeUnit;
29 27
30 /** Android hardware video encoder. */ 28 /** Android hardware video encoder. */
31 @TargetApi(19) 29 @TargetApi(19)
32 @SuppressWarnings("deprecation") // Cannot support API level 19 without using de precated methods. 30 @SuppressWarnings("deprecation") // Cannot support API level 19 without using de precated methods.
33 class HardwareVideoEncoder implements VideoEncoder { 31 class HardwareVideoEncoder implements VideoEncoder {
34 private static final String TAG = "HardwareVideoEncoder"; 32 private static final String TAG = "HardwareVideoEncoder";
35 33
36 // Bitrate modes - should be in sync with OMX_VIDEO_CONTROLRATETYPE defined 34 // Bitrate modes - should be in sync with OMX_VIDEO_CONTROLRATETYPE defined
37 // in OMX_Video.h 35 // in OMX_Video.h
38 private static final int VIDEO_ControlRateConstant = 2; 36 private static final int VIDEO_ControlRateConstant = 2;
39 // Key associated with the bitrate control mode value (above). Not present as a MediaFormat 37 // Key associated with the bitrate control mode value (above). Not present as a MediaFormat
40 // constant until API level 21. 38 // constant until API level 21.
41 private static final String KEY_BITRATE_MODE = "bitrate-mode"; 39 private static final String KEY_BITRATE_MODE = "bitrate-mode";
42 40
41 private static final int VIDEO_AVC_PROFILE_HIGH = 8;
42 private static final int VIDEO_AVC_LEVEL_3 = 0x100;
43
43 private static final int MAX_VIDEO_FRAMERATE = 30; 44 private static final int MAX_VIDEO_FRAMERATE = 30;
44 45
45 // See MAX_ENCODER_Q_SIZE in androidmediaencoder_jni.cc. 46 // See MAX_ENCODER_Q_SIZE in androidmediaencoder_jni.cc.
46 private static final int MAX_ENCODER_Q_SIZE = 2; 47 private static final int MAX_ENCODER_Q_SIZE = 2;
47 48
48 private static final int MEDIA_CODEC_RELEASE_TIMEOUT_MS = 5000; 49 private static final int MEDIA_CODEC_RELEASE_TIMEOUT_MS = 5000;
49 private static final int DEQUEUE_OUTPUT_BUFFER_TIMEOUT_US = 100000; 50 private static final int DEQUEUE_OUTPUT_BUFFER_TIMEOUT_US = 100000;
50 51
51 private final String codecName; 52 private final String codecName;
52 private final VideoCodecType codecType; 53 private final VideoCodecType codecType;
53 private final int colorFormat; 54 private final int colorFormat;
55 private final Map<String, String> params;
54 private final ColorFormat inputColorFormat; 56 private final ColorFormat inputColorFormat;
55 // Base interval for generating key frames. 57 // Base interval for generating key frames.
56 private final int keyFrameIntervalSec; 58 private final int keyFrameIntervalSec;
57 // Interval at which to force a key frame. Used to reduce color distortions ca used by some 59 // Interval at which to force a key frame. Used to reduce color distortions ca used by some
58 // Qualcomm video encoders. 60 // Qualcomm video encoders.
59 private final long forcedKeyFrameNs; 61 private final long forcedKeyFrameNs;
60 // Presentation timestamp of the last requested (or forced) key frame. 62 // Presentation timestamp of the last requested (or forced) key frame.
61 private long lastKeyFrameNs; 63 private long lastKeyFrameNs;
62 64
63 private final BitrateAdjuster bitrateAdjuster; 65 private final BitrateAdjuster bitrateAdjuster;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 * @param codecType the type of the given video codec (eg. VP8, VP9, or H264) 110 * @param codecType the type of the given video codec (eg. VP8, VP9, or H264)
109 * @param colorFormat color format used by the input buffer 111 * @param colorFormat color format used by the input buffer
110 * @param keyFrameIntervalSec interval in seconds between key frames; used to initialize the codec 112 * @param keyFrameIntervalSec interval in seconds between key frames; used to initialize the codec
111 * @param forceKeyFrameIntervalMs interval at which to force a key frame if on e is not requested; 113 * @param forceKeyFrameIntervalMs interval at which to force a key frame if on e is not requested;
112 * used to reduce distortion caused by some codec implementations 114 * used to reduce distortion caused by some codec implementations
113 * @param bitrateAdjuster algorithm used to correct codec implementations that do not produce the 115 * @param bitrateAdjuster algorithm used to correct codec implementations that do not produce the
114 * desired bitrates 116 * desired bitrates
115 * @throws IllegalArgumentException if colorFormat is unsupported 117 * @throws IllegalArgumentException if colorFormat is unsupported
116 */ 118 */
117 public HardwareVideoEncoder(String codecName, VideoCodecType codecType, int co lorFormat, 119 public HardwareVideoEncoder(String codecName, VideoCodecType codecType, int co lorFormat,
118 int keyFrameIntervalSec, int forceKeyFrameIntervalMs, BitrateAdjuster bitr ateAdjuster, 120 Map<String, String> params, int keyFrameIntervalSec, int forceKeyFrameInte rvalMs,
119 EglBase14.Context textureContext) { 121 BitrateAdjuster bitrateAdjuster, EglBase14.Context textureContext) {
120 this.codecName = codecName; 122 this.codecName = codecName;
121 this.codecType = codecType; 123 this.codecType = codecType;
122 this.colorFormat = colorFormat; 124 this.colorFormat = colorFormat;
125 this.params = params;
123 if (textureContext == null) { 126 if (textureContext == null) {
124 this.inputColorFormat = ColorFormat.valueOf(colorFormat); 127 this.inputColorFormat = ColorFormat.valueOf(colorFormat);
125 } else { 128 } else {
126 // ColorFormat copies bytes between buffers. It is not used in texture mo de. 129 // ColorFormat copies bytes between buffers. It is not used in texture mo de.
127 this.inputColorFormat = null; 130 this.inputColorFormat = null;
128 } 131 }
129 this.keyFrameIntervalSec = keyFrameIntervalSec; 132 this.keyFrameIntervalSec = keyFrameIntervalSec;
130 this.forcedKeyFrameNs = TimeUnit.MILLISECONDS.toNanos(forceKeyFrameIntervalM s); 133 this.forcedKeyFrameNs = TimeUnit.MILLISECONDS.toNanos(forceKeyFrameIntervalM s);
131 this.bitrateAdjuster = bitrateAdjuster; 134 this.bitrateAdjuster = bitrateAdjuster;
132 this.outputBuilders = new LinkedBlockingDeque<>(); 135 this.outputBuilders = new LinkedBlockingDeque<>();
(...skipping 29 matching lines...) Expand all
162 Logging.e(TAG, "Cannot create media encoder " + codecName); 165 Logging.e(TAG, "Cannot create media encoder " + codecName);
163 return VideoCodecStatus.ERROR; 166 return VideoCodecStatus.ERROR;
164 } 167 }
165 try { 168 try {
166 MediaFormat format = MediaFormat.createVideoFormat(codecType.mimeType(), w idth, height); 169 MediaFormat format = MediaFormat.createVideoFormat(codecType.mimeType(), w idth, height);
167 format.setInteger(MediaFormat.KEY_BIT_RATE, adjustedBitrate); 170 format.setInteger(MediaFormat.KEY_BIT_RATE, adjustedBitrate);
168 format.setInteger(KEY_BITRATE_MODE, VIDEO_ControlRateConstant); 171 format.setInteger(KEY_BITRATE_MODE, VIDEO_ControlRateConstant);
169 format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); 172 format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
170 format.setInteger(MediaFormat.KEY_FRAME_RATE, bitrateAdjuster.getAdjustedF ramerate()); 173 format.setInteger(MediaFormat.KEY_FRAME_RATE, bitrateAdjuster.getAdjustedF ramerate());
171 format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec); 174 format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec);
175 if (codecType == VideoCodecType.H264) {
176 String profileLevelId = params.get(VideoCodecInfo.H264_FMTP_PROFILE_LEVE L_ID);
177 if (profileLevelId == null) {
178 profileLevelId = VideoCodecInfo.H264_CONSTRAINED_BASELINE_3_1;
179 }
180 switch (profileLevelId) {
181 case VideoCodecInfo.H264_CONSTRAINED_HIGH_3_1:
182 format.setInteger("profile", VIDEO_AVC_PROFILE_HIGH);
183 format.setInteger("level", VIDEO_AVC_LEVEL_3);
184 break;
185 case VideoCodecInfo.H264_CONSTRAINED_BASELINE_3_1:
186 break;
187 default:
188 Logging.w(TAG, "Unknown profile level id: " + profileLevelId);
189 }
190 }
172 Logging.d(TAG, "Format: " + format); 191 Logging.d(TAG, "Format: " + format);
173 codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 192 codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
174 193
175 if (textureContext != null) { 194 if (textureContext != null) {
176 // Texture mode. 195 // Texture mode.
177 textureEglBase = new EglBase14(textureContext, EglBase.CONFIG_RECORDABLE ); 196 textureEglBase = new EglBase14(textureContext, EglBase.CONFIG_RECORDABLE );
178 textureInputSurface = codec.createInputSurface(); 197 textureInputSurface = codec.createInputSurface();
179 textureEglBase.createSurface(textureInputSurface); 198 textureEglBase.createSurface(textureInputSurface);
180 textureDrawer = new GlRectDrawer(); 199 textureDrawer = new GlRectDrawer();
181 } 200 }
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar: 572 case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
554 case MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar: 573 case MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar:
555 case MediaCodecUtils.COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m: 574 case MediaCodecUtils.COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m:
556 return NV12; 575 return NV12;
557 default: 576 default:
558 throw new IllegalArgumentException("Unsupported colorFormat: " + color Format); 577 throw new IllegalArgumentException("Unsupported colorFormat: " + color Format);
559 } 578 }
560 } 579 }
561 } 580 }
562 } 581 }
OLDNEW
« no previous file with comments | « webrtc/sdk/android/api/org/webrtc/VideoCodecInfo.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698