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

Side by Side Diff: webrtc/sdk/android/src/jni/androidmediaencoder_jni.cc

Issue 2833493003: Don't re-randomize picture_id/tl0_pic_idx when re-initializing internal encoders. (Closed)
Patch Set: Created 3 years, 8 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
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
11 // NOTICE: androidmediaencoder_jni.h must be included before 11 // NOTICE: androidmediaencoder_jni.h must be included before
12 // androidmediacodeccommon.h to avoid build errors. 12 // androidmediacodeccommon.h to avoid build errors.
13 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" 13 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h"
14 14
15 #include <algorithm> 15 #include <algorithm>
16 #include <list> 16 #include <list>
17 #include <memory> 17 #include <memory>
18 #include <string> 18 #include <string>
19 #include <utility> 19 #include <utility>
20 20
21 #include "third_party/libyuv/include/libyuv/convert.h" 21 #include "third_party/libyuv/include/libyuv/convert.h"
22 #include "third_party/libyuv/include/libyuv/convert_from.h" 22 #include "third_party/libyuv/include/libyuv/convert_from.h"
23 #include "third_party/libyuv/include/libyuv/video_common.h" 23 #include "third_party/libyuv/include/libyuv/video_common.h"
24 #include "webrtc/api/video_codecs/video_encoder.h" 24 #include "webrtc/api/video_codecs/video_encoder.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/random.h"
28 #include "webrtc/base/sequenced_task_checker.h" 29 #include "webrtc/base/sequenced_task_checker.h"
29 #include "webrtc/base/task_queue.h" 30 #include "webrtc/base/task_queue.h"
30 #include "webrtc/base/thread.h" 31 #include "webrtc/base/thread.h"
31 #include "webrtc/base/timeutils.h" 32 #include "webrtc/base/timeutils.h"
32 #include "webrtc/base/weak_ptr.h" 33 #include "webrtc/base/weak_ptr.h"
33 #include "webrtc/common_types.h" 34 #include "webrtc/common_types.h"
34 #include "webrtc/common_video/h264/h264_bitstream_parser.h" 35 #include "webrtc/common_video/h264/h264_bitstream_parser.h"
35 #include "webrtc/common_video/h264/h264_common.h" 36 #include "webrtc/common_video/h264/h264_common.h"
36 #include "webrtc/common_video/h264/profile_level_id.h" 37 #include "webrtc/common_video/h264/profile_level_id.h"
37 #include "webrtc/media/engine/internalencoderfactory.h" 38 #include "webrtc/media/engine/internalencoderfactory.h"
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 jfieldID j_info_index_field_; 216 jfieldID j_info_index_field_;
216 jfieldID j_info_buffer_field_; 217 jfieldID j_info_buffer_field_;
217 jfieldID j_info_is_key_frame_field_; 218 jfieldID j_info_is_key_frame_field_;
218 jfieldID j_info_presentation_timestamp_us_field_; 219 jfieldID j_info_presentation_timestamp_us_field_;
219 220
220 // State that is valid only between InitEncode() and the next Release(). 221 // State that is valid only between InitEncode() and the next Release().
221 int width_; // Frame width in pixels. 222 int width_; // Frame width in pixels.
222 int height_; // Frame height in pixels. 223 int height_; // Frame height in pixels.
223 bool inited_; 224 bool inited_;
224 bool use_surface_; 225 bool use_surface_;
225 uint16_t picture_id_;
226 enum libyuv::FourCC encoder_fourcc_; // Encoder color space format. 226 enum libyuv::FourCC encoder_fourcc_; // Encoder color space format.
227 int last_set_bitrate_kbps_; // Last-requested bitrate in kbps. 227 int last_set_bitrate_kbps_; // Last-requested bitrate in kbps.
228 int last_set_fps_; // Last-requested frame rate. 228 int last_set_fps_; // Last-requested frame rate.
229 int64_t current_timestamp_us_; // Current frame timestamps in us. 229 int64_t current_timestamp_us_; // Current frame timestamps in us.
230 int frames_received_; // Number of frames received by encoder. 230 int frames_received_; // Number of frames received by encoder.
231 int frames_encoded_; // Number of frames encoded by encoder. 231 int frames_encoded_; // Number of frames encoded by encoder.
232 int frames_dropped_media_encoder_; // Number of frames dropped by encoder. 232 int frames_dropped_media_encoder_; // Number of frames dropped by encoder.
233 // Number of dropped frames caused by full queue. 233 // Number of dropped frames caused by full queue.
234 int consecutive_full_queue_frame_drops_; 234 int consecutive_full_queue_frame_drops_;
235 int64_t stat_start_time_ms_; // Start time for statistics. 235 int64_t stat_start_time_ms_; // Start time for statistics.
(...skipping 23 matching lines...) Expand all
259 const int64_t frame_render_time_ms; 259 const int64_t frame_render_time_ms;
260 const webrtc::VideoRotation rotation; 260 const webrtc::VideoRotation rotation;
261 }; 261 };
262 std::list<InputFrameInfo> input_frame_infos_; 262 std::list<InputFrameInfo> input_frame_infos_;
263 int32_t output_timestamp_; // Last output frame timestamp from 263 int32_t output_timestamp_; // Last output frame timestamp from
264 // |input_frame_infos_|. 264 // |input_frame_infos_|.
265 int64_t output_render_time_ms_; // Last output frame render time from 265 int64_t output_render_time_ms_; // Last output frame render time from
266 // |input_frame_infos_|. 266 // |input_frame_infos_|.
267 webrtc::VideoRotation output_rotation_; // Last output frame rotation from 267 webrtc::VideoRotation output_rotation_; // Last output frame rotation from
268 // |input_frame_infos_|. 268 // |input_frame_infos_|.
269
269 // Frame size in bytes fed to MediaCodec. 270 // Frame size in bytes fed to MediaCodec.
270 int yuv_size_; 271 int yuv_size_;
271 // True only when between a callback_->OnEncodedImage() call return a positive 272 // True only when between a callback_->OnEncodedImage() call return a positive
272 // value and the next Encode() call being ignored. 273 // value and the next Encode() call being ignored.
273 bool drop_next_input_frame_; 274 bool drop_next_input_frame_;
274 bool scale_; 275 bool scale_;
275 // Global references; must be deleted in Release(). 276 // Global references; must be deleted in Release().
276 std::vector<jobject> input_buffers_; 277 std::vector<jobject> input_buffers_;
277 webrtc::H264BitstreamParser h264_bitstream_parser_; 278 webrtc::H264BitstreamParser h264_bitstream_parser_;
278 279
279 // VP9 variables to populate codec specific structure. 280 // VP9 variables to populate codec specific structure.
280 webrtc::GofInfoVP9 gof_; // Contains each frame's temporal information for 281 webrtc::GofInfoVP9 gof_; // Contains each frame's temporal information for
281 // non-flexible VP9 mode. 282 // non-flexible VP9 mode.
282 uint8_t tl0_pic_idx_;
283 size_t gof_idx_; 283 size_t gof_idx_;
284 284
285 // EGL context - owned by factory, should not be allocated/destroyed 285 // EGL context - owned by factory, should not be allocated/destroyed
286 // by MediaCodecVideoEncoder. 286 // by MediaCodecVideoEncoder.
287 jobject egl_context_; 287 jobject egl_context_;
288 288
289 // Temporary fix for VP8. 289 // Temporary fix for VP8.
290 // Sends a key frame if frames are largely spaced apart (possibly 290 // Sends a key frame if frames are largely spaced apart (possibly
291 // corresponding to a large image change). 291 // corresponding to a large image change).
292 int64_t last_frame_received_ms_; 292 int64_t last_frame_received_ms_;
293 int frames_received_since_last_key_; 293 int frames_received_since_last_key_;
294 webrtc::VideoCodecMode codec_mode_; 294 webrtc::VideoCodecMode codec_mode_;
295 295
296 // Used to randomize the initial |picture_id_| and |tl0_pic_idx_|.
297 webrtc::Random random_;
magjed_webrtc 2017/04/21 15:11:18 I would like to not keep this as a member variable
brandtr 2017/04/24 07:53:47 Good idea. Done.
298
299 // RTP state.
300 uint16_t picture_id_;
301 uint8_t tl0_pic_idx_;
302
296 bool sw_fallback_required_; 303 bool sw_fallback_required_;
297 304
298 // All other member variables should be before WeakPtrFactory. Valid only from 305 // All other member variables should be before WeakPtrFactory. Valid only from
299 // InitEncode to Release. 306 // InitEncode to Release.
300 std::unique_ptr<rtc::WeakPtrFactory<MediaCodecVideoEncoder>> weak_factory_; 307 std::unique_ptr<rtc::WeakPtrFactory<MediaCodecVideoEncoder>> weak_factory_;
301 }; 308 };
302 309
303 MediaCodecVideoEncoder::~MediaCodecVideoEncoder() { 310 MediaCodecVideoEncoder::~MediaCodecVideoEncoder() {
304 #if RTC_DCHECK_IS_ON 311 #if RTC_DCHECK_IS_ON
305 rtc::CritScope lock(&inited_crit_); 312 rtc::CritScope lock(&inited_crit_);
(...skipping 11 matching lines...) Expand all
317 FindClass(jni, "org/webrtc/MediaCodecVideoEncoder")), 324 FindClass(jni, "org/webrtc/MediaCodecVideoEncoder")),
318 j_media_codec_video_encoder_( 325 j_media_codec_video_encoder_(
319 jni, 326 jni,
320 jni->NewObject(*j_media_codec_video_encoder_class_, 327 jni->NewObject(*j_media_codec_video_encoder_class_,
321 GetMethodID(jni, 328 GetMethodID(jni,
322 *j_media_codec_video_encoder_class_, 329 *j_media_codec_video_encoder_class_,
323 "<init>", 330 "<init>",
324 "()V"))), 331 "()V"))),
325 inited_(false), 332 inited_(false),
326 use_surface_(false), 333 use_surface_(false),
327 picture_id_(0),
328 egl_context_(egl_context), 334 egl_context_(egl_context),
335 random_(rtc::TimeMicros()),
336 picture_id_(random_.Rand<uint16_t>() & 0x7FFF),
magjed_webrtc 2017/04/20 12:39:12 Is it possible to pass in the start |picture_id_|
brandtr 2017/04/21 08:29:31 That is something that we maybe want to do long-te
magjed_webrtc 2017/04/21 15:11:18 Acknowledged.
337 tl0_pic_idx_(random_.Rand<uint8_t>()),
329 sw_fallback_required_(false) { 338 sw_fallback_required_(false) {
330 encoder_queue_checker_.Detach(); 339 encoder_queue_checker_.Detach();
331 340
332 jclass j_output_buffer_info_class = 341 jclass j_output_buffer_info_class =
333 FindClass(jni, "org/webrtc/MediaCodecVideoEncoder$OutputBufferInfo"); 342 FindClass(jni, "org/webrtc/MediaCodecVideoEncoder$OutputBufferInfo");
334 j_init_encode_method_ = GetMethodID( 343 j_init_encode_method_ = GetMethodID(
335 jni, 344 jni,
336 *j_media_codec_video_encoder_class_, 345 *j_media_codec_video_encoder_class_,
337 "initEncode", 346 "initEncode",
338 "(Lorg/webrtc/MediaCodecVideoEncoder$VideoCodecType;" 347 "(Lorg/webrtc/MediaCodecVideoEncoder$VideoCodecType;"
(...skipping 29 matching lines...) Expand all
368 j_info_buffer_field_ = GetFieldID( 377 j_info_buffer_field_ = GetFieldID(
369 jni, j_output_buffer_info_class, "buffer", "Ljava/nio/ByteBuffer;"); 378 jni, j_output_buffer_info_class, "buffer", "Ljava/nio/ByteBuffer;");
370 j_info_is_key_frame_field_ = 379 j_info_is_key_frame_field_ =
371 GetFieldID(jni, j_output_buffer_info_class, "isKeyFrame", "Z"); 380 GetFieldID(jni, j_output_buffer_info_class, "isKeyFrame", "Z");
372 j_info_presentation_timestamp_us_field_ = GetFieldID( 381 j_info_presentation_timestamp_us_field_ = GetFieldID(
373 jni, j_output_buffer_info_class, "presentationTimestampUs", "J"); 382 jni, j_output_buffer_info_class, "presentationTimestampUs", "J");
374 if (CheckException(jni)) { 383 if (CheckException(jni)) {
375 ALOGW << "MediaCodecVideoEncoder ctor failed."; 384 ALOGW << "MediaCodecVideoEncoder ctor failed.";
376 ProcessHWError(true /* reset_if_fallback_unavailable */); 385 ProcessHWError(true /* reset_if_fallback_unavailable */);
377 } 386 }
378 srand(rtc::Time32());
379 } 387 }
380 388
381 int32_t MediaCodecVideoEncoder::InitEncode( 389 int32_t MediaCodecVideoEncoder::InitEncode(
382 const webrtc::VideoCodec* codec_settings, 390 const webrtc::VideoCodec* codec_settings,
383 int32_t /* number_of_cores */, 391 int32_t /* number_of_cores */,
384 size_t /* max_payload_size */) { 392 size_t /* max_payload_size */) {
385 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_); 393 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_checker_);
386 if (codec_settings == NULL) { 394 if (codec_settings == NULL) {
387 ALOGE << "NULL VideoCodec instance"; 395 ALOGE << "NULL VideoCodec instance";
388 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 396 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 current_bytes_ = 0; 553 current_bytes_ = 0;
546 current_acc_qp_ = 0; 554 current_acc_qp_ = 0;
547 current_encoding_time_ms_ = 0; 555 current_encoding_time_ms_ = 0;
548 last_input_timestamp_ms_ = -1; 556 last_input_timestamp_ms_ = -1;
549 last_output_timestamp_ms_ = -1; 557 last_output_timestamp_ms_ = -1;
550 output_timestamp_ = 0; 558 output_timestamp_ = 0;
551 output_render_time_ms_ = 0; 559 output_render_time_ms_ = 0;
552 input_frame_infos_.clear(); 560 input_frame_infos_.clear();
553 drop_next_input_frame_ = false; 561 drop_next_input_frame_ = false;
554 use_surface_ = use_surface; 562 use_surface_ = use_surface;
555 // TODO(ilnik): Use rand_r() instead to avoid LINT warnings below.
556 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF; // NOLINT
557 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1); 563 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1);
558 tl0_pic_idx_ = static_cast<uint8_t>(rand()); // NOLINT
559 gof_idx_ = 0; 564 gof_idx_ = 0;
560 last_frame_received_ms_ = -1; 565 last_frame_received_ms_ = -1;
561 frames_received_since_last_key_ = kMinKeyFrameInterval; 566 frames_received_since_last_key_ = kMinKeyFrameInterval;
562 567
563 // We enforce no extra stride/padding in the format creation step. 568 // We enforce no extra stride/padding in the format creation step.
564 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( 569 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName(
565 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type); 570 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type);
566 const bool encode_status = jni->CallBooleanMethod( 571 const bool encode_status = jni->CallBooleanMethod(
567 *j_media_codec_video_encoder_, j_init_encode_method_, 572 *j_media_codec_video_encoder_, j_init_encode_method_,
568 j_video_codec_enum, width, height, kbps, fps, 573 j_video_codec_enum, width, height, kbps, fps,
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 } 1353 }
1349 } 1354 }
1350 1355
1351 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( 1356 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(
1352 webrtc::VideoEncoder* encoder) { 1357 webrtc::VideoEncoder* encoder) {
1353 ALOGD << "Destroy video encoder."; 1358 ALOGD << "Destroy video encoder.";
1354 delete encoder; 1359 delete encoder;
1355 } 1360 }
1356 1361
1357 } // namespace webrtc_jni 1362 } // namespace webrtc_jni
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698