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

Side by Side Diff: webrtc/api/android/jni/androidmediaencoder_jni.cc

Issue 2538133002: Delete nalu parser in mediaencoder (Closed)
Patch Set: Created 4 years 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 | « no previous file | 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 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2015 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
(...skipping 12 matching lines...) Expand all
23 #include "webrtc/api/android/jni/classreferenceholder.h" 23 #include "webrtc/api/android/jni/classreferenceholder.h"
24 #include "webrtc/api/android/jni/native_handle_impl.h" 24 #include "webrtc/api/android/jni/native_handle_impl.h"
25 #include "webrtc/base/bind.h" 25 #include "webrtc/base/bind.h"
26 #include "webrtc/base/checks.h" 26 #include "webrtc/base/checks.h"
27 #include "webrtc/base/logging.h" 27 #include "webrtc/base/logging.h"
28 #include "webrtc/base/thread.h" 28 #include "webrtc/base/thread.h"
29 #include "webrtc/base/thread_checker.h" 29 #include "webrtc/base/thread_checker.h"
30 #include "webrtc/base/timeutils.h" 30 #include "webrtc/base/timeutils.h"
31 #include "webrtc/common_types.h" 31 #include "webrtc/common_types.h"
32 #include "webrtc/common_video/h264/h264_bitstream_parser.h" 32 #include "webrtc/common_video/h264/h264_bitstream_parser.h"
33 #include "webrtc/common_video/h264/h264_common.h"
33 #include "webrtc/common_video/h264/profile_level_id.h" 34 #include "webrtc/common_video/h264/profile_level_id.h"
34 #include "webrtc/media/engine/internalencoderfactory.h" 35 #include "webrtc/media/engine/internalencoderfactory.h"
35 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 36 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
36 #include "webrtc/modules/video_coding/utility/quality_scaler.h" 37 #include "webrtc/modules/video_coding/utility/quality_scaler.h"
37 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h" 38 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h"
38 #include "webrtc/system_wrappers/include/field_trial.h" 39 #include "webrtc/system_wrappers/include/field_trial.h"
39 #include "webrtc/system_wrappers/include/logcat_trace_context.h" 40 #include "webrtc/system_wrappers/include/logcat_trace_context.h"
40 #include "webrtc/video_encoder.h" 41 #include "webrtc/video_encoder.h"
41 42
42 using rtc::Bind; 43 using rtc::Bind;
43 using rtc::Thread; 44 using rtc::Thread;
44 using rtc::ThreadManager; 45 using rtc::ThreadManager;
45 46
46 using webrtc::CodecSpecificInfo; 47 using webrtc::CodecSpecificInfo;
47 using webrtc::EncodedImage; 48 using webrtc::EncodedImage;
48 using webrtc::VideoFrame; 49 using webrtc::VideoFrame;
49 using webrtc::RTPFragmentationHeader; 50 using webrtc::RTPFragmentationHeader;
50 using webrtc::VideoCodec; 51 using webrtc::VideoCodec;
51 using webrtc::VideoCodecType; 52 using webrtc::VideoCodecType;
52 using webrtc::kVideoCodecH264; 53 using webrtc::kVideoCodecH264;
53 using webrtc::kVideoCodecVP8; 54 using webrtc::kVideoCodecVP8;
54 using webrtc::kVideoCodecVP9; 55 using webrtc::kVideoCodecVP9;
55 using webrtc::QualityScaler; 56 using webrtc::QualityScaler;
56 57
57 namespace webrtc_jni { 58 namespace webrtc_jni {
58 59
59 // H.264 start code length.
60 #define H264_SC_LENGTH 4
61 // Maximum allowed NALUs in one output frame.
62 #define MAX_NALUS_PERFRAME 32
63 // Maximum supported HW video encoder fps. 60 // Maximum supported HW video encoder fps.
64 #define MAX_VIDEO_FPS 30 61 #define MAX_VIDEO_FPS 30
65 // Maximum allowed fps value in SetRates() call. 62 // Maximum allowed fps value in SetRates() call.
66 #define MAX_ALLOWED_VIDEO_FPS 60 63 #define MAX_ALLOWED_VIDEO_FPS 60
67 // Maximum allowed frames in encoder input queue. 64 // Maximum allowed frames in encoder input queue.
68 #define MAX_ENCODER_Q_SIZE 2 65 #define MAX_ENCODER_Q_SIZE 2
69 // Maximum amount of dropped frames caused by full encoder queue - exceeding 66 // Maximum amount of dropped frames caused by full encoder queue - exceeding
70 // this threshold means that encoder probably got stuck and need to be reset. 67 // this threshold means that encoder probably got stuck and need to be reset.
71 #define ENCODER_STALL_FRAMEDROP_THRESHOLD 60 68 #define ENCODER_STALL_FRAMEDROP_THRESHOLD 60
72 69
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 int GetOutputBufferInfoIndex(JNIEnv* jni, jobject j_output_buffer_info); 169 int GetOutputBufferInfoIndex(JNIEnv* jni, jobject j_output_buffer_info);
173 jobject GetOutputBufferInfoBuffer(JNIEnv* jni, jobject j_output_buffer_info); 170 jobject GetOutputBufferInfoBuffer(JNIEnv* jni, jobject j_output_buffer_info);
174 bool GetOutputBufferInfoIsKeyFrame(JNIEnv* jni, jobject j_output_buffer_info); 171 bool GetOutputBufferInfoIsKeyFrame(JNIEnv* jni, jobject j_output_buffer_info);
175 jlong GetOutputBufferInfoPresentationTimestampUs( 172 jlong GetOutputBufferInfoPresentationTimestampUs(
176 JNIEnv* jni, jobject j_output_buffer_info); 173 JNIEnv* jni, jobject j_output_buffer_info);
177 174
178 // Deliver any outputs pending in the MediaCodec to our |callback_| and return 175 // Deliver any outputs pending in the MediaCodec to our |callback_| and return
179 // true on success. 176 // true on success.
180 bool DeliverPendingOutputs(JNIEnv* jni); 177 bool DeliverPendingOutputs(JNIEnv* jni);
181 178
182 // Search for H.264 start codes.
183 int32_t NextNaluPosition(uint8_t *buffer, size_t buffer_size);
184
185 VideoEncoder::ScalingSettings GetScalingSettings() const override; 179 VideoEncoder::ScalingSettings GetScalingSettings() const override;
186 180
187 // Displays encoder statistics. 181 // Displays encoder statistics.
188 void LogStatistics(bool force_log); 182 void LogStatistics(bool force_log);
189 183
190 // Type of video codec. 184 // Type of video codec.
191 const cricket::VideoCodec codec_; 185 const cricket::VideoCodec codec_;
192 186
193 // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to 187 // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to
194 // |codec_thread_| synchronously. 188 // |codec_thread_| synchronously.
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 } 1088 }
1095 } 1089 }
1096 } else if (codec_type == kVideoCodecH264) { 1090 } else if (codec_type == kVideoCodecH264) {
1097 h264_bitstream_parser_.ParseBitstream(payload, payload_size); 1091 h264_bitstream_parser_.ParseBitstream(payload, payload_size);
1098 int qp; 1092 int qp;
1099 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) { 1093 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) {
1100 current_acc_qp_ += qp; 1094 current_acc_qp_ += qp;
1101 image->qp_ = qp; 1095 image->qp_ = qp;
1102 } 1096 }
1103 // For H.264 search for start codes. 1097 // For H.264 search for start codes.
1104 int32_t scPositions[MAX_NALUS_PERFRAME + 1] = {}; 1098 const std::vector<webrtc::H264::NaluIndex> nalu_idxs =
1105 int32_t scPositionsLength = 0; 1099 webrtc::H264::FindNaluIndices(payload, payload_size);
1106 int32_t scPosition = 0; 1100 if (nalu_idxs.empty()) {
1107 while (scPositionsLength < MAX_NALUS_PERFRAME) {
1108 int32_t naluPosition = NextNaluPosition(
1109 payload + scPosition, payload_size - scPosition);
1110 if (naluPosition < 0) {
1111 break;
1112 }
1113 scPosition += naluPosition;
1114 scPositions[scPositionsLength++] = scPosition;
1115 scPosition += H264_SC_LENGTH;
1116 }
1117 if (scPositionsLength == 0) {
1118 ALOGE << "Start code is not found!"; 1101 ALOGE << "Start code is not found!";
1119 ALOGE << "Data:" << image->_buffer[0] << " " << image->_buffer[1] 1102 ALOGE << "Data:" << image->_buffer[0] << " " << image->_buffer[1]
1120 << " " << image->_buffer[2] << " " << image->_buffer[3] 1103 << " " << image->_buffer[2] << " " << image->_buffer[3]
1121 << " " << image->_buffer[4] << " " << image->_buffer[5]; 1104 << " " << image->_buffer[4] << " " << image->_buffer[5];
1122 ProcessHWErrorOnCodecThread(true /* reset_if_fallback_unavailable */); 1105 ProcessHWErrorOnCodecThread(true /* reset_if_fallback_unavailable */);
1123 return false; 1106 return false;
1124 } 1107 }
1125 scPositions[scPositionsLength] = payload_size; 1108 header.VerifyAndAllocateFragmentationHeader(nalu_idxs.size());
1126 header.VerifyAndAllocateFragmentationHeader(scPositionsLength); 1109 for (size_t i = 0; i < nalu_idxs.size(); i++) {
1127 for (size_t i = 0; i < scPositionsLength; i++) { 1110 header.fragmentationOffset[i] = nalu_idxs[i].payload_start_offset;
1128 header.fragmentationOffset[i] = scPositions[i] + H264_SC_LENGTH; 1111 header.fragmentationLength[i] = nalu_idxs[i].payload_size;
1129 header.fragmentationLength[i] =
1130 scPositions[i + 1] - header.fragmentationOffset[i];
1131 header.fragmentationPlType[i] = 0; 1112 header.fragmentationPlType[i] = 0;
1132 header.fragmentationTimeDiff[i] = 0; 1113 header.fragmentationTimeDiff[i] = 0;
1133 } 1114 }
1134 } 1115 }
1135 1116
1136 callback_result = callback_->OnEncodedImage(*image, &info, &header); 1117 callback_result = callback_->OnEncodedImage(*image, &info, &header);
1137 } 1118 }
1138 1119
1139 // Return output buffer back to the encoder. 1120 // Return output buffer back to the encoder.
1140 bool success = jni->CallBooleanMethod(*j_media_codec_video_encoder_, 1121 bool success = jni->CallBooleanMethod(*j_media_codec_video_encoder_,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 current_acc_qp_ = 0; 1178 current_acc_qp_ = 0;
1198 current_encoding_time_ms_ = 0; 1179 current_encoding_time_ms_ = 0;
1199 } 1180 }
1200 } 1181 }
1201 1182
1202 webrtc::VideoEncoder::ScalingSettings 1183 webrtc::VideoEncoder::ScalingSettings
1203 MediaCodecVideoEncoder::GetScalingSettings() const { 1184 MediaCodecVideoEncoder::GetScalingSettings() const {
1204 return VideoEncoder::ScalingSettings(scale_); 1185 return VideoEncoder::ScalingSettings(scale_);
1205 } 1186 }
1206 1187
1207 int32_t MediaCodecVideoEncoder::NextNaluPosition(
1208 uint8_t *buffer, size_t buffer_size) {
1209 if (buffer_size < H264_SC_LENGTH) {
1210 return -1;
1211 }
1212 uint8_t *head = buffer;
1213 // Set end buffer pointer to 4 bytes before actual buffer end so we can
1214 // access head[1], head[2] and head[3] in a loop without buffer overrun.
1215 uint8_t *end = buffer + buffer_size - H264_SC_LENGTH;
1216
1217 while (head < end) {
1218 if (head[0]) {
1219 head++;
1220 continue;
1221 }
1222 if (head[1]) { // got 00xx
1223 head += 2;
1224 continue;
1225 }
1226 if (head[2]) { // got 0000xx
1227 head += 3;
1228 continue;
1229 }
1230 if (head[3] != 0x01) { // got 000000xx
1231 head++; // xx != 1, continue searching.
1232 continue;
1233 }
1234 return (int32_t)(head - buffer);
1235 }
1236 return -1;
1237 }
1238
1239 const char* MediaCodecVideoEncoder::ImplementationName() const { 1188 const char* MediaCodecVideoEncoder::ImplementationName() const {
1240 return "MediaCodec"; 1189 return "MediaCodec";
1241 } 1190 }
1242 1191
1243 MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory() 1192 MediaCodecVideoEncoderFactory::MediaCodecVideoEncoderFactory()
1244 : egl_context_(nullptr) { 1193 : egl_context_(nullptr) {
1245 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 1194 JNIEnv* jni = AttachCurrentThreadIfNeeded();
1246 ScopedLocalRefFrame local_ref_frame(jni); 1195 ScopedLocalRefFrame local_ref_frame(jni);
1247 jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder"); 1196 jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder");
1248 supported_codecs_.clear(); 1197 supported_codecs_.clear();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 return supported_codecs_; 1279 return supported_codecs_;
1331 } 1280 }
1332 1281
1333 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( 1282 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(
1334 webrtc::VideoEncoder* encoder) { 1283 webrtc::VideoEncoder* encoder) {
1335 ALOGD << "Destroy video encoder."; 1284 ALOGD << "Destroy video encoder.";
1336 delete encoder; 1285 delete encoder;
1337 } 1286 }
1338 1287
1339 } // namespace webrtc_jni 1288 } // namespace webrtc_jni
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698