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

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

Issue 2764573002: Deliver video frames on Android, on the decode thread. (Closed)
Patch Set: Update comments 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
« no previous file with comments | « webrtc/modules/video_coding/video_receiver.cc ('k') | webrtc/video/video_receive_stream.h » ('j') | 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 18 matching lines...) Expand all
29 #include "webrtc/common_video/h264/h264_bitstream_parser.h" 29 #include "webrtc/common_video/h264/h264_bitstream_parser.h"
30 #include "webrtc/common_video/include/i420_buffer_pool.h" 30 #include "webrtc/common_video/include/i420_buffer_pool.h"
31 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 31 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
32 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h" 32 #include "webrtc/modules/video_coding/utility/vp8_header_parser.h"
33 #include "webrtc/sdk/android/src/jni/androidmediacodeccommon.h" 33 #include "webrtc/sdk/android/src/jni/androidmediacodeccommon.h"
34 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" 34 #include "webrtc/sdk/android/src/jni/classreferenceholder.h"
35 #include "webrtc/sdk/android/src/jni/native_handle_impl.h" 35 #include "webrtc/sdk/android/src/jni/native_handle_impl.h"
36 #include "webrtc/sdk/android/src/jni/surfacetexturehelper_jni.h" 36 #include "webrtc/sdk/android/src/jni/surfacetexturehelper_jni.h"
37 #include "webrtc/system_wrappers/include/logcat_trace_context.h" 37 #include "webrtc/system_wrappers/include/logcat_trace_context.h"
38 38
39 // Logging macros.
40 #define TAG_DECODER "MediaCodecVideoDecoder"
41 #ifdef TRACK_BUFFER_TIMING
42 #define ALOGV(...)
43 __android_log_print(ANDROID_LOG_VERBOSE, TAG_DECODER, __VA_ARGS__)
44 #else
45 #define ALOGV(...)
46 #endif
47 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_DECODER)
48 #define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_DECODER)
49 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_DECODER)
50
39 using rtc::Bind; 51 using rtc::Bind;
40 using rtc::Thread; 52 using rtc::Thread;
41 using rtc::ThreadManager; 53 using rtc::ThreadManager;
42 54
43 using webrtc::CodecSpecificInfo; 55 using webrtc::CodecSpecificInfo;
44 using webrtc::DecodedImageCallback; 56 using webrtc::DecodedImageCallback;
45 using webrtc::EncodedImage; 57 using webrtc::EncodedImage;
46 using webrtc::VideoFrame; 58 using webrtc::VideoFrame;
47 using webrtc::RTPFragmentationHeader; 59 using webrtc::RTPFragmentationHeader;
48 using webrtc::VideoCodec; 60 using webrtc::VideoCodec;
49 using webrtc::VideoCodecType; 61 using webrtc::VideoCodecType;
50 using webrtc::kVideoCodecH264; 62 using webrtc::kVideoCodecH264;
51 using webrtc::kVideoCodecVP8; 63 using webrtc::kVideoCodecVP8;
52 using webrtc::kVideoCodecVP9; 64 using webrtc::kVideoCodecVP9;
53 65
54 namespace webrtc_jni { 66 namespace webrtc_jni {
55 67
56 // Logging macros. 68 class MediaCodecVideoDecoder : public webrtc::VideoDecoder {
57 #define TAG_DECODER "MediaCodecVideoDecoder"
58 #ifdef TRACK_BUFFER_TIMING
59 #define ALOGV(...)
60 __android_log_print(ANDROID_LOG_VERBOSE, TAG_DECODER, __VA_ARGS__)
61 #else
62 #define ALOGV(...)
63 #endif
64 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_DECODER)
65 #define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_DECODER)
66 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_DECODER)
67
68 enum { kMaxWarningLogFrames = 2 };
69
70 class MediaCodecVideoDecoder : public webrtc::VideoDecoder,
71 public rtc::MessageHandler {
72 public: 69 public:
73 explicit MediaCodecVideoDecoder( 70 explicit MediaCodecVideoDecoder(
74 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context); 71 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context);
75 virtual ~MediaCodecVideoDecoder(); 72 virtual ~MediaCodecVideoDecoder();
76 73
77 int32_t InitDecode(const VideoCodec* codecSettings, int32_t numberOfCores) 74 int32_t InitDecode(const VideoCodec* codecSettings, int32_t numberOfCores)
78 override; 75 override;
79 76
80 int32_t Decode( 77 int32_t Decode(
81 const EncodedImage& inputImage, bool missingFrames, 78 const EncodedImage& inputImage, bool missingFrames,
82 const RTPFragmentationHeader* fragmentation, 79 const RTPFragmentationHeader* fragmentation,
83 const CodecSpecificInfo* codecSpecificInfo = NULL, 80 const CodecSpecificInfo* codecSpecificInfo = NULL,
84 int64_t renderTimeMs = -1) override; 81 int64_t renderTimeMs = -1) override;
85 82
83 void PollDecodedFrames() override;
84
86 int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback) 85 int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback)
87 override; 86 override;
88 87
89 int32_t Release() override; 88 int32_t Release() override;
90 89
91 bool PrefersLateDecoding() const override { return true; } 90 bool PrefersLateDecoding() const override { return true; }
92 91
93 // rtc::MessageHandler implementation.
94 void OnMessage(rtc::Message* msg) override;
95
96 const char* ImplementationName() const override; 92 const char* ImplementationName() const override;
97 93
98 private: 94 private:
99 // CHECK-fail if not running on |codec_thread_|. 95 struct DecodedFrame {
100 void CheckOnCodecThread(); 96 DecodedFrame(VideoFrame frame,
97 int decode_time_ms,
98 int64_t timestamp,
99 int64_t ntp_timestamp,
100 rtc::Optional<uint8_t> qp)
101 : frame(std::move(frame)),
102 decode_time_ms(decode_time_ms),
103 qp(std::move(qp)) {
104 frame.set_timestamp(timestamp);
105 frame.set_ntp_time_ms(ntp_timestamp);
106 }
107
108 VideoFrame frame;
109 int decode_time_ms;
110 rtc::Optional<uint8_t> qp;
111 };
112
113 // Returns true if running on |codec_thread_|. Used for DCHECKing.
114 bool IsOnCodecThread();
101 115
102 int32_t InitDecodeOnCodecThread(); 116 int32_t InitDecodeOnCodecThread();
103 int32_t ResetDecodeOnCodecThread(); 117 int32_t ResetDecodeOnCodecThread();
104 int32_t ReleaseOnCodecThread(); 118 int32_t ReleaseOnCodecThread();
105 int32_t DecodeOnCodecThread(const EncodedImage& inputImage); 119 int32_t DecodeOnCodecThread(const EncodedImage& inputImage,
120 std::vector<DecodedFrame>* frames);
121 void PollDecodedFramesOnCodecThread(std::vector<DecodedFrame>* frames);
106 // Deliver any outputs pending in the MediaCodec to our |callback_| and return 122 // Deliver any outputs pending in the MediaCodec to our |callback_| and return
107 // true on success. 123 // true on success.
108 bool DeliverPendingOutputs(JNIEnv* jni, int dequeue_timeout_us); 124 bool DeliverPendingOutputs(JNIEnv* jni,
125 int dequeue_timeout_us,
126 std::vector<DecodedFrame>* frames);
109 int32_t ProcessHWErrorOnCodecThread(); 127 int32_t ProcessHWErrorOnCodecThread();
110 void EnableFrameLogOnWarning(); 128 void EnableFrameLogOnWarning();
111 void ResetVariables(); 129 void ResetVariables();
112 130
113 // Type of video codec. 131 // Type of video codec.
114 VideoCodecType codecType_; 132 VideoCodecType codecType_;
115 133
116 // Render EGL context - owned by factory, should not be allocated/destroyed 134 // Render EGL context - owned by factory, should not be allocated/destroyed
117 // by VideoDecoder. 135 // by VideoDecoder.
118 jobject render_egl_context_; 136 jobject render_egl_context_;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 jfieldID j_info_index_field_; 190 jfieldID j_info_index_field_;
173 jfieldID j_info_offset_field_; 191 jfieldID j_info_offset_field_;
174 jfieldID j_info_size_field_; 192 jfieldID j_info_size_field_;
175 jfieldID j_presentation_timestamp_ms_field_; 193 jfieldID j_presentation_timestamp_ms_field_;
176 jfieldID j_timestamp_ms_field_; 194 jfieldID j_timestamp_ms_field_;
177 jfieldID j_ntp_timestamp_ms_field_; 195 jfieldID j_ntp_timestamp_ms_field_;
178 jfieldID j_byte_buffer_decode_time_ms_field_; 196 jfieldID j_byte_buffer_decode_time_ms_field_;
179 197
180 // Global references; must be deleted in Release(). 198 // Global references; must be deleted in Release().
181 std::vector<jobject> input_buffers_; 199 std::vector<jobject> input_buffers_;
200
201 // Added to on the codec thread, frames are delivered on the decoder thread.
202 std::vector<DecodedFrame> decoded_frames_;
182 }; 203 };
183 204
184 MediaCodecVideoDecoder::MediaCodecVideoDecoder( 205 MediaCodecVideoDecoder::MediaCodecVideoDecoder(
185 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context) : 206 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context) :
186 codecType_(codecType), 207 codecType_(codecType),
187 render_egl_context_(render_egl_context), 208 render_egl_context_(render_egl_context),
188 key_frame_required_(true), 209 key_frame_required_(true),
189 inited_(false), 210 inited_(false),
190 sw_fallback_required_(false), 211 sw_fallback_required_(false),
191 codec_thread_(new Thread()), 212 codec_thread_(new Thread()),
192 j_media_codec_video_decoder_class_( 213 j_media_codec_video_decoder_class_(
193 jni, 214 jni,
194 FindClass(jni, "org/webrtc/MediaCodecVideoDecoder")), 215 FindClass(jni, "org/webrtc/MediaCodecVideoDecoder")),
195 j_media_codec_video_decoder_( 216 j_media_codec_video_decoder_(
196 jni, 217 jni,
197 jni->NewObject(*j_media_codec_video_decoder_class_, 218 jni->NewObject(*j_media_codec_video_decoder_class_,
198 GetMethodID(jni, 219 GetMethodID(jni,
199 *j_media_codec_video_decoder_class_, 220 *j_media_codec_video_decoder_class_,
200 "<init>", 221 "<init>",
201 "()V"))) { 222 "()V"))) {
202 codec_thread_->SetName("MediaCodecVideoDecoder", NULL); 223 codec_thread_->SetName("MediaCodecVideoDecoder", NULL);
203 RTC_CHECK(codec_thread_->Start()) << "Failed to start MediaCodecVideoDecoder"; 224 RTC_CHECK(codec_thread_->Start());
204 225
205 j_init_decode_method_ = GetMethodID( 226 j_init_decode_method_ = GetMethodID(
206 jni, *j_media_codec_video_decoder_class_, "initDecode", 227 jni, *j_media_codec_video_decoder_class_, "initDecode",
207 "(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;" 228 "(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;"
208 "IILorg/webrtc/SurfaceTextureHelper;)Z"); 229 "IILorg/webrtc/SurfaceTextureHelper;)Z");
209 j_reset_method_ = 230 j_reset_method_ =
210 GetMethodID(jni, *j_media_codec_video_decoder_class_, "reset", "(II)V"); 231 GetMethodID(jni, *j_media_codec_video_decoder_class_, "reset", "(II)V");
211 j_release_method_ = 232 j_release_method_ =
212 GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V"); 233 GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V");
213 j_dequeue_input_buffer_method_ = GetMethodID( 234 j_dequeue_input_buffer_method_ = GetMethodID(
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 } 309 }
289 310
290 int32_t MediaCodecVideoDecoder::InitDecode(const VideoCodec* inst, 311 int32_t MediaCodecVideoDecoder::InitDecode(const VideoCodec* inst,
291 int32_t numberOfCores) { 312 int32_t numberOfCores) {
292 ALOGD << "InitDecode."; 313 ALOGD << "InitDecode.";
293 if (inst == NULL) { 314 if (inst == NULL) {
294 ALOGE << "NULL VideoCodec instance"; 315 ALOGE << "NULL VideoCodec instance";
295 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 316 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
296 } 317 }
297 // Factory should guard against other codecs being used with us. 318 // Factory should guard against other codecs being used with us.
298 RTC_CHECK(inst->codecType == codecType_) 319 RTC_DCHECK(inst->codecType == codecType_)
299 << "Unsupported codec " << inst->codecType << " for " << codecType_; 320 << "Unsupported codec " << inst->codecType << " for " << codecType_;
300 321
301 if (sw_fallback_required_) { 322 if (sw_fallback_required_) {
302 ALOGE << "InitDecode() - fallback to SW decoder"; 323 ALOGE << "InitDecode() - fallback to SW decoder";
303 return WEBRTC_VIDEO_CODEC_OK; 324 return WEBRTC_VIDEO_CODEC_OK;
304 } 325 }
305 // Save VideoCodec instance for later. 326 // Save VideoCodec instance for later.
306 if (&codec_ != inst) { 327 if (&codec_ != inst) {
307 codec_ = *inst; 328 codec_ = *inst;
308 } 329 }
309 // If maxFramerate is not set then assume 30 fps. 330 // If maxFramerate is not set then assume 30 fps.
310 codec_.maxFramerate = (codec_.maxFramerate >= 1) ? codec_.maxFramerate : 30; 331 codec_.maxFramerate = (codec_.maxFramerate >= 1) ? codec_.maxFramerate : 30;
311 332
312 // Call Java init. 333 // Call Java init.
313 return codec_thread_->Invoke<int32_t>( 334 return codec_thread_->Invoke<int32_t>(
314 RTC_FROM_HERE, 335 RTC_FROM_HERE,
315 Bind(&MediaCodecVideoDecoder::InitDecodeOnCodecThread, this)); 336 Bind(&MediaCodecVideoDecoder::InitDecodeOnCodecThread, this));
316 } 337 }
317 338
318 void MediaCodecVideoDecoder::ResetVariables() { 339 void MediaCodecVideoDecoder::ResetVariables() {
319 CheckOnCodecThread(); 340 RTC_DCHECK(IsOnCodecThread());
320 341
321 key_frame_required_ = true; 342 key_frame_required_ = true;
322 frames_received_ = 0; 343 frames_received_ = 0;
323 frames_decoded_ = 0; 344 frames_decoded_ = 0;
324 frames_decoded_logged_ = kMaxDecodedLogFrames; 345 frames_decoded_logged_ = kMaxDecodedLogFrames;
325 start_time_ms_ = rtc::TimeMillis(); 346 start_time_ms_ = rtc::TimeMillis();
326 current_frames_ = 0; 347 current_frames_ = 0;
327 current_bytes_ = 0; 348 current_bytes_ = 0;
328 current_decoding_time_ms_ = 0; 349 current_decoding_time_ms_ = 0;
329 current_delay_time_ms_ = 0; 350 current_delay_time_ms_ = 0;
330 pending_frame_qps_.clear(); 351 pending_frame_qps_.clear();
331 } 352 }
332 353
333 int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { 354 int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() {
334 CheckOnCodecThread(); 355 RTC_DCHECK(IsOnCodecThread());
335 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 356 JNIEnv* jni = AttachCurrentThreadIfNeeded();
336 ScopedLocalRefFrame local_ref_frame(jni); 357 ScopedLocalRefFrame local_ref_frame(jni);
337 ALOGD << "InitDecodeOnCodecThread Type: " << (int)codecType_ << ". " 358 ALOGD << "InitDecodeOnCodecThread Type: " << (int)codecType_ << ". "
338 << codec_.width << " x " << codec_.height << ". Fps: " << 359 << codec_.width << " x " << codec_.height << ". Fps: " <<
339 (int)codec_.maxFramerate; 360 (int)codec_.maxFramerate;
340 361
341 // Release previous codec first if it was allocated before. 362 // Release previous codec first if it was allocated before.
342 int ret_val = ReleaseOnCodecThread(); 363 int ret_val = ReleaseOnCodecThread();
343 if (ret_val < 0) { 364 if (ret_val < 0) {
344 ALOGE << "Release failure: " << ret_val << " - fallback to SW codec"; 365 ALOGE << "Release failure: " << ret_val << " - fallback to SW codec";
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 for (size_t i = 0; i < num_input_buffers; ++i) { 419 for (size_t i = 0; i < num_input_buffers; ++i) {
399 input_buffers_[i] = 420 input_buffers_[i] =
400 jni->NewGlobalRef(jni->GetObjectArrayElement(input_buffers, i)); 421 jni->NewGlobalRef(jni->GetObjectArrayElement(input_buffers, i));
401 if (CheckException(jni)) { 422 if (CheckException(jni)) {
402 ALOGE << "NewGlobalRef error - fallback to SW codec."; 423 ALOGE << "NewGlobalRef error - fallback to SW codec.";
403 sw_fallback_required_ = true; 424 sw_fallback_required_ = true;
404 return WEBRTC_VIDEO_CODEC_ERROR; 425 return WEBRTC_VIDEO_CODEC_ERROR;
405 } 426 }
406 } 427 }
407 428
408 codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollMs, this);
409
410 return WEBRTC_VIDEO_CODEC_OK; 429 return WEBRTC_VIDEO_CODEC_OK;
411 } 430 }
412 431
413 int32_t MediaCodecVideoDecoder::ResetDecodeOnCodecThread() { 432 int32_t MediaCodecVideoDecoder::ResetDecodeOnCodecThread() {
414 CheckOnCodecThread(); 433 RTC_DCHECK(IsOnCodecThread());
415 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 434 JNIEnv* jni = AttachCurrentThreadIfNeeded();
416 ScopedLocalRefFrame local_ref_frame(jni); 435 ScopedLocalRefFrame local_ref_frame(jni);
417 ALOGD << "ResetDecodeOnCodecThread Type: " << (int)codecType_ << ". " 436 ALOGD << "ResetDecodeOnCodecThread Type: " << (int)codecType_ << ". "
418 << codec_.width << " x " << codec_.height; 437 << codec_.width << " x " << codec_.height;
419 ALOGD << " Frames received: " << frames_received_ << 438 ALOGD << " Frames received: " << frames_received_ <<
420 ". Frames decoded: " << frames_decoded_; 439 ". Frames decoded: " << frames_decoded_;
421 440
422 inited_ = false; 441 inited_ = false;
423 rtc::MessageQueueManager::Clear(this);
424 ResetVariables(); 442 ResetVariables();
425 443
426 jni->CallVoidMethod( 444 jni->CallVoidMethod(
427 *j_media_codec_video_decoder_, 445 *j_media_codec_video_decoder_,
428 j_reset_method_, 446 j_reset_method_,
429 codec_.width, 447 codec_.width,
430 codec_.height); 448 codec_.height);
431 449
432 if (CheckException(jni)) { 450 if (CheckException(jni)) {
433 ALOGE << "Soft reset error - fallback to SW codec."; 451 ALOGE << "Soft reset error - fallback to SW codec.";
434 sw_fallback_required_ = true; 452 sw_fallback_required_ = true;
435 return WEBRTC_VIDEO_CODEC_ERROR; 453 return WEBRTC_VIDEO_CODEC_ERROR;
436 } 454 }
437 inited_ = true; 455 inited_ = true;
438 456
439 codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollMs, this);
440
441 return WEBRTC_VIDEO_CODEC_OK; 457 return WEBRTC_VIDEO_CODEC_OK;
442 } 458 }
443 459
444 int32_t MediaCodecVideoDecoder::Release() { 460 int32_t MediaCodecVideoDecoder::Release() {
445 ALOGD << "DecoderRelease request"; 461 ALOGD << "DecoderRelease request";
446 return codec_thread_->Invoke<int32_t>( 462 return codec_thread_->Invoke<int32_t>(
447 RTC_FROM_HERE, Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this)); 463 RTC_FROM_HERE, Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this));
448 } 464 }
449 465
450 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() { 466 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() {
467 RTC_DCHECK(IsOnCodecThread());
451 if (!inited_) { 468 if (!inited_) {
452 return WEBRTC_VIDEO_CODEC_OK; 469 return WEBRTC_VIDEO_CODEC_OK;
453 } 470 }
454 CheckOnCodecThread();
455 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 471 JNIEnv* jni = AttachCurrentThreadIfNeeded();
456 ALOGD << "DecoderReleaseOnCodecThread: Frames received: " << 472 ALOGD << "DecoderReleaseOnCodecThread: Frames received: " <<
457 frames_received_ << ". Frames decoded: " << frames_decoded_; 473 frames_received_ << ". Frames decoded: " << frames_decoded_;
458 ScopedLocalRefFrame local_ref_frame(jni); 474 ScopedLocalRefFrame local_ref_frame(jni);
459 for (size_t i = 0; i < input_buffers_.size(); i++) { 475 for (size_t i = 0; i < input_buffers_.size(); i++) {
460 jni->DeleteGlobalRef(input_buffers_[i]); 476 jni->DeleteGlobalRef(input_buffers_[i]);
461 } 477 }
462 input_buffers_.clear(); 478 input_buffers_.clear();
463 jni->CallVoidMethod(*j_media_codec_video_decoder_, j_release_method_); 479 jni->CallVoidMethod(*j_media_codec_video_decoder_, j_release_method_);
464 surface_texture_helper_ = nullptr; 480 surface_texture_helper_ = nullptr;
465 inited_ = false; 481 inited_ = false;
466 rtc::MessageQueueManager::Clear(this);
467 if (CheckException(jni)) { 482 if (CheckException(jni)) {
468 ALOGE << "Decoder release exception"; 483 ALOGE << "Decoder release exception";
469 return WEBRTC_VIDEO_CODEC_ERROR; 484 return WEBRTC_VIDEO_CODEC_ERROR;
470 } 485 }
471 ALOGD << "DecoderReleaseOnCodecThread done"; 486 ALOGD << "DecoderReleaseOnCodecThread done";
472 return WEBRTC_VIDEO_CODEC_OK; 487 return WEBRTC_VIDEO_CODEC_OK;
473 } 488 }
474 489
475 void MediaCodecVideoDecoder::CheckOnCodecThread() { 490 bool MediaCodecVideoDecoder::IsOnCodecThread() {
476 RTC_CHECK(codec_thread_.get() == ThreadManager::Instance()->CurrentThread()) 491 return codec_thread_.get() == ThreadManager::Instance()->CurrentThread();
477 << "Running on wrong thread!";
478 } 492 }
479 493
480 void MediaCodecVideoDecoder::EnableFrameLogOnWarning() { 494 void MediaCodecVideoDecoder::EnableFrameLogOnWarning() {
481 // Log next 2 output frames. 495 // Log next 2 output frames.
496 static const int kMaxWarningLogFrames = 2;
482 frames_decoded_logged_ = std::max( 497 frames_decoded_logged_ = std::max(
483 frames_decoded_logged_, frames_decoded_ + kMaxWarningLogFrames); 498 frames_decoded_logged_, frames_decoded_ + kMaxWarningLogFrames);
484 } 499 }
485 500
486 int32_t MediaCodecVideoDecoder::ProcessHWErrorOnCodecThread() { 501 int32_t MediaCodecVideoDecoder::ProcessHWErrorOnCodecThread() {
487 CheckOnCodecThread(); 502 RTC_DCHECK(IsOnCodecThread());
488 int ret_val = ReleaseOnCodecThread(); 503 int ret_val = ReleaseOnCodecThread();
489 if (ret_val < 0) { 504 if (ret_val < 0) {
490 ALOGE << "ProcessHWError: Release failure"; 505 ALOGE << "ProcessHWError: Release failure";
491 } 506 }
492 if (codecType_ == kVideoCodecH264) { 507 if (codecType_ == kVideoCodecH264) {
493 // For now there is no SW H.264 which can be used as fallback codec. 508 // For now there is no SW H.264 which can be used as fallback codec.
494 // So try to restart hw codec for now. 509 // So try to restart hw codec for now.
495 ret_val = InitDecodeOnCodecThread(); 510 ret_val = InitDecodeOnCodecThread();
496 ALOGE << "Reset H.264 codec done. Status: " << ret_val; 511 ALOGE << "Reset H.264 codec done. Status: " << ret_val;
497 if (ret_val == WEBRTC_VIDEO_CODEC_OK) { 512 if (ret_val == WEBRTC_VIDEO_CODEC_OK) {
(...skipping 10 matching lines...) Expand all
508 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 523 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
509 } 524 }
510 } 525 }
511 526
512 int32_t MediaCodecVideoDecoder::Decode( 527 int32_t MediaCodecVideoDecoder::Decode(
513 const EncodedImage& inputImage, 528 const EncodedImage& inputImage,
514 bool missingFrames, 529 bool missingFrames,
515 const RTPFragmentationHeader* fragmentation, 530 const RTPFragmentationHeader* fragmentation,
516 const CodecSpecificInfo* codecSpecificInfo, 531 const CodecSpecificInfo* codecSpecificInfo,
517 int64_t renderTimeMs) { 532 int64_t renderTimeMs) {
533 RTC_DCHECK(callback_);
534 RTC_DCHECK(inited_);
535
518 if (sw_fallback_required_) { 536 if (sw_fallback_required_) {
519 ALOGE << "Decode() - fallback to SW codec"; 537 ALOGE << "Decode() - fallback to SW codec";
520 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 538 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
521 } 539 }
522 if (callback_ == NULL) {
523 ALOGE << "Decode() - callback_ is NULL";
524 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
525 }
526 if (inputImage._buffer == NULL && inputImage._length > 0) { 540 if (inputImage._buffer == NULL && inputImage._length > 0) {
527 ALOGE << "Decode() - inputImage is incorrect"; 541 ALOGE << "Decode() - inputImage is incorrect";
528 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 542 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
529 } 543 }
530 if (!inited_) {
531 ALOGE << "Decode() - decoder is not initialized";
532 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
533 }
534 544
535 // Check if encoded frame dimension has changed. 545 // Check if encoded frame dimension has changed.
536 if ((inputImage._encodedWidth * inputImage._encodedHeight > 0) && 546 if ((inputImage._encodedWidth * inputImage._encodedHeight > 0) &&
537 (inputImage._encodedWidth != codec_.width || 547 (inputImage._encodedWidth != codec_.width ||
538 inputImage._encodedHeight != codec_.height)) { 548 inputImage._encodedHeight != codec_.height)) {
539 ALOGW << "Input resolution changed from " << 549 ALOGW << "Input resolution changed from " <<
540 codec_.width << " x " << codec_.height << " to " << 550 codec_.width << " x " << codec_.height << " to " <<
541 inputImage._encodedWidth << " x " << inputImage._encodedHeight; 551 inputImage._encodedWidth << " x " << inputImage._encodedHeight;
542 codec_.width = inputImage._encodedWidth; 552 codec_.width = inputImage._encodedWidth;
543 codec_.height = inputImage._encodedHeight; 553 codec_.height = inputImage._encodedHeight;
(...skipping 24 matching lines...) Expand all
568 if (!inputImage._completeFrame) { 578 if (!inputImage._completeFrame) {
569 ALOGE << "Decode() - complete frame is required"; 579 ALOGE << "Decode() - complete frame is required";
570 return WEBRTC_VIDEO_CODEC_ERROR; 580 return WEBRTC_VIDEO_CODEC_ERROR;
571 } 581 }
572 key_frame_required_ = false; 582 key_frame_required_ = false;
573 } 583 }
574 if (inputImage._length == 0) { 584 if (inputImage._length == 0) {
575 return WEBRTC_VIDEO_CODEC_ERROR; 585 return WEBRTC_VIDEO_CODEC_ERROR;
576 } 586 }
577 587
578 return codec_thread_->Invoke<int32_t>( 588 std::vector<DecodedFrame> frames;
589 int32_t ret = codec_thread_->Invoke<int32_t>(
590 RTC_FROM_HERE, Bind(&MediaCodecVideoDecoder::DecodeOnCodecThread, this,
591 inputImage, &frames));
592 for (auto& f : frames)
593 callback_->Decoded(f.frame, rtc::Optional<int32_t>(f.decode_time_ms), f.qp);
594 return ret;
595 }
596
597 void MediaCodecVideoDecoder::PollDecodedFrames() {
598 RTC_DCHECK(callback_);
599
600 std::vector<DecodedFrame> frames;
601 codec_thread_->Invoke<void>(
579 RTC_FROM_HERE, 602 RTC_FROM_HERE,
580 Bind(&MediaCodecVideoDecoder::DecodeOnCodecThread, this, inputImage)); 603 Bind(&MediaCodecVideoDecoder::PollDecodedFramesOnCodecThread, this,
604 &frames));
605
606 for (auto& f : frames)
607 callback_->Decoded(f.frame, rtc::Optional<int32_t>(f.decode_time_ms), f.qp);
581 } 608 }
582 609
583 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( 610 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread(
584 const EncodedImage& inputImage) { 611 const EncodedImage& inputImage,
585 CheckOnCodecThread(); 612 std::vector<DecodedFrame>* frames) {
613 RTC_DCHECK(IsOnCodecThread());
586 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 614 JNIEnv* jni = AttachCurrentThreadIfNeeded();
587 ScopedLocalRefFrame local_ref_frame(jni); 615 ScopedLocalRefFrame local_ref_frame(jni);
588 616
589 // Try to drain the decoder and wait until output is not too 617 // Try to drain the decoder and wait until output is not too
590 // much behind the input. 618 // much behind the input.
591 if (codecType_ == kVideoCodecH264 && 619 if (codecType_ == kVideoCodecH264 &&
592 frames_received_ > frames_decoded_ + max_pending_frames_) { 620 frames_received_ > frames_decoded_ + max_pending_frames_) {
593 // Print warning for H.264 only - for VP8/VP9 one frame delay is ok. 621 // Print warning for H.264 only - for VP8/VP9 one frame delay is ok.
594 ALOGW << "Decoder is too far behind. Try to drain. Received: " << 622 ALOGW << "Decoder is too far behind. Try to drain. Received: " <<
595 frames_received_ << ". Decoded: " << frames_decoded_; 623 frames_received_ << ". Decoded: " << frames_decoded_;
596 EnableFrameLogOnWarning(); 624 EnableFrameLogOnWarning();
597 } 625 }
598 const int64 drain_start = rtc::TimeMillis(); 626 const int64 drain_start = rtc::TimeMillis();
599 while ((frames_received_ > frames_decoded_ + max_pending_frames_) && 627 while ((frames_received_ > frames_decoded_ + max_pending_frames_) &&
600 (rtc::TimeMillis() - drain_start) < kMediaCodecTimeoutMs) { 628 (rtc::TimeMillis() - drain_start) < kMediaCodecTimeoutMs) {
601 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs)) { 629 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs, frames)) {
602 ALOGE << "DeliverPendingOutputs error. Frames received: " << 630 ALOGE << "DeliverPendingOutputs error. Frames received: " <<
603 frames_received_ << ". Frames decoded: " << frames_decoded_; 631 frames_received_ << ". Frames decoded: " << frames_decoded_;
604 return ProcessHWErrorOnCodecThread(); 632 return ProcessHWErrorOnCodecThread();
605 } 633 }
606 } 634 }
607 if (frames_received_ > frames_decoded_ + max_pending_frames_) { 635 if (frames_received_ > frames_decoded_ + max_pending_frames_) {
608 ALOGE << "Output buffer dequeue timeout. Frames received: " << 636 ALOGE << "Output buffer dequeue timeout. Frames received: " <<
609 frames_received_ << ". Frames decoded: " << frames_decoded_; 637 frames_received_ << ". Frames decoded: " << frames_decoded_;
610 return ProcessHWErrorOnCodecThread(); 638 return ProcessHWErrorOnCodecThread();
611 } 639 }
612 640
613 // Get input buffer. 641 // Get input buffer.
614 int j_input_buffer_index = jni->CallIntMethod( 642 int j_input_buffer_index = jni->CallIntMethod(
615 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_); 643 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_);
616 if (CheckException(jni) || j_input_buffer_index < 0) { 644 if (CheckException(jni) || j_input_buffer_index < 0) {
617 ALOGE << "dequeueInputBuffer error: " << j_input_buffer_index << 645 ALOGE << "dequeueInputBuffer error: " << j_input_buffer_index <<
618 ". Retry DeliverPendingOutputs."; 646 ". Retry DeliverPendingOutputs.";
619 EnableFrameLogOnWarning(); 647 EnableFrameLogOnWarning();
620 // Try to drain the decoder. 648 // Try to drain the decoder.
621 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs)) { 649 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs, frames)) {
622 ALOGE << "DeliverPendingOutputs error. Frames received: " << 650 ALOGE << "DeliverPendingOutputs error. Frames received: " <<
623 frames_received_ << ". Frames decoded: " << frames_decoded_; 651 frames_received_ << ". Frames decoded: " << frames_decoded_;
624 return ProcessHWErrorOnCodecThread(); 652 return ProcessHWErrorOnCodecThread();
625 } 653 }
626 // Try dequeue input buffer one last time. 654 // Try dequeue input buffer one last time.
627 j_input_buffer_index = jni->CallIntMethod( 655 j_input_buffer_index = jni->CallIntMethod(
628 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_); 656 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_);
629 if (CheckException(jni) || j_input_buffer_index < 0) { 657 if (CheckException(jni) || j_input_buffer_index < 0) {
630 ALOGE << "dequeueInputBuffer critical error: " << j_input_buffer_index; 658 ALOGE << "dequeueInputBuffer critical error: " << j_input_buffer_index;
631 return ProcessHWErrorOnCodecThread(); 659 return ProcessHWErrorOnCodecThread();
632 } 660 }
633 } 661 }
634 662
635 // Copy encoded data to Java ByteBuffer. 663 // Copy encoded data to Java ByteBuffer.
636 jobject j_input_buffer = input_buffers_[j_input_buffer_index]; 664 jobject j_input_buffer = input_buffers_[j_input_buffer_index];
637 uint8_t* buffer = 665 uint8_t* buffer =
638 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer)); 666 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer));
639 RTC_CHECK(buffer) << "Indirect buffer??"; 667 RTC_DCHECK(buffer) << "Indirect buffer??";
640 int64_t buffer_capacity = jni->GetDirectBufferCapacity(j_input_buffer); 668 int64_t buffer_capacity = jni->GetDirectBufferCapacity(j_input_buffer);
641 if (CheckException(jni) || buffer_capacity < inputImage._length) { 669 if (CheckException(jni) || buffer_capacity < inputImage._length) {
642 ALOGE << "Input frame size "<< inputImage._length << 670 ALOGE << "Input frame size "<< inputImage._length <<
643 " is bigger than buffer size " << buffer_capacity; 671 " is bigger than buffer size " << buffer_capacity;
644 return ProcessHWErrorOnCodecThread(); 672 return ProcessHWErrorOnCodecThread();
645 } 673 }
646 jlong presentation_timestamp_us = static_cast<jlong>( 674 jlong presentation_timestamp_us = static_cast<jlong>(
647 static_cast<int64_t>(frames_received_) * 1000000 / codec_.maxFramerate); 675 static_cast<int64_t>(frames_received_) * 1000000 / codec_.maxFramerate);
648 memcpy(buffer, inputImage._buffer, inputImage._length); 676 memcpy(buffer, inputImage._buffer, inputImage._length);
649 677
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 inputImage._length, 710 inputImage._length,
683 presentation_timestamp_us, 711 presentation_timestamp_us,
684 static_cast<int64_t> (inputImage._timeStamp), 712 static_cast<int64_t> (inputImage._timeStamp),
685 inputImage.ntp_time_ms_); 713 inputImage.ntp_time_ms_);
686 if (CheckException(jni) || !success) { 714 if (CheckException(jni) || !success) {
687 ALOGE << "queueInputBuffer error"; 715 ALOGE << "queueInputBuffer error";
688 return ProcessHWErrorOnCodecThread(); 716 return ProcessHWErrorOnCodecThread();
689 } 717 }
690 718
691 // Try to drain the decoder 719 // Try to drain the decoder
692 if (!DeliverPendingOutputs(jni, 0)) { 720 if (!DeliverPendingOutputs(jni, 0, frames)) {
693 ALOGE << "DeliverPendingOutputs error"; 721 ALOGE << "DeliverPendingOutputs error";
694 return ProcessHWErrorOnCodecThread(); 722 return ProcessHWErrorOnCodecThread();
695 } 723 }
696 724
697 return WEBRTC_VIDEO_CODEC_OK; 725 return WEBRTC_VIDEO_CODEC_OK;
698 } 726 }
699 727
728 void MediaCodecVideoDecoder::PollDecodedFramesOnCodecThread(
729 std::vector<DecodedFrame>* frames) {
730 RTC_DCHECK(IsOnCodecThread());
731
732 JNIEnv* jni = AttachCurrentThreadIfNeeded();
733 ScopedLocalRefFrame local_ref_frame(jni);
734
735 if (!DeliverPendingOutputs(jni, 0, frames)) {
736 ALOGE << "PollDecodedFramesOnCodecThread: DeliverPendingOutputs error";
737 ProcessHWErrorOnCodecThread();
738 }
739 }
740
700 bool MediaCodecVideoDecoder::DeliverPendingOutputs( 741 bool MediaCodecVideoDecoder::DeliverPendingOutputs(
701 JNIEnv* jni, int dequeue_timeout_ms) { 742 JNIEnv* jni,
702 CheckOnCodecThread(); 743 int dequeue_timeout_ms,
744 std::vector<DecodedFrame>* frames) {
745 RTC_DCHECK(IsOnCodecThread());
746 RTC_DCHECK(frames);
747
703 if (frames_received_ <= frames_decoded_) { 748 if (frames_received_ <= frames_decoded_) {
704 // No need to query for output buffers - decoder is drained. 749 // No need to query for output buffers - decoder is drained.
705 return true; 750 return true;
706 } 751 }
707 // Get decoder output. 752 // Get decoder output.
708 jobject j_decoder_output_buffer = 753 jobject j_decoder_output_buffer =
709 jni->CallObjectMethod(*j_media_codec_video_decoder_, 754 jni->CallObjectMethod(*j_media_codec_video_decoder_,
710 use_surface_ ? j_dequeue_texture_buffer_method_ 755 use_surface_ ? j_dequeue_texture_buffer_method_
711 : j_dequeue_byte_buffer_method_, 756 : j_dequeue_byte_buffer_method_,
712 dequeue_timeout_ms); 757 dequeue_timeout_ms);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 output_buffer)); 846 output_buffer));
802 if (CheckException(jni)) { 847 if (CheckException(jni)) {
803 return false; 848 return false;
804 } 849 }
805 payload += output_buffer_offset; 850 payload += output_buffer_offset;
806 851
807 // Create yuv420 frame. 852 // Create yuv420 frame.
808 rtc::scoped_refptr<webrtc::I420Buffer> i420_buffer = 853 rtc::scoped_refptr<webrtc::I420Buffer> i420_buffer =
809 decoded_frame_pool_.CreateBuffer(width, height); 854 decoded_frame_pool_.CreateBuffer(width, height);
810 if (color_format == COLOR_FormatYUV420Planar) { 855 if (color_format == COLOR_FormatYUV420Planar) {
811 RTC_CHECK_EQ(0, stride % 2); 856 RTC_DCHECK_EQ(0, stride % 2);
812 const int uv_stride = stride / 2; 857 const int uv_stride = stride / 2;
813 const uint8_t* y_ptr = payload; 858 const uint8_t* y_ptr = payload;
814 const uint8_t* u_ptr = y_ptr + stride * slice_height; 859 const uint8_t* u_ptr = y_ptr + stride * slice_height;
815 860
816 // Note that the case with odd |slice_height| is handled in a special way. 861 // Note that the case with odd |slice_height| is handled in a special way.
817 // The chroma height contained in the payload is rounded down instead of 862 // The chroma height contained in the payload is rounded down instead of
818 // up, making it one row less than what we expect in WebRTC. Therefore, we 863 // up, making it one row less than what we expect in WebRTC. Therefore, we
819 // have to duplicate the last chroma rows for this case. Also, the offset 864 // have to duplicate the last chroma rows for this case. Also, the offset
820 // between the Y plane and the U plane is unintuitive for this case. See 865 // between the Y plane and the U plane is unintuitive for this case. See
821 // http://bugs.webrtc.org/6651 for more info. 866 // http://bugs.webrtc.org/6651 for more info.
822 const int chroma_width = (width + 1) / 2; 867 const int chroma_width = (width + 1) / 2;
823 const int chroma_height = 868 const int chroma_height =
824 (slice_height % 2 == 0) ? (height + 1) / 2 : height / 2; 869 (slice_height % 2 == 0) ? (height + 1) / 2 : height / 2;
825 const int u_offset = uv_stride * slice_height / 2; 870 const int u_offset = uv_stride * slice_height / 2;
826 const uint8_t* v_ptr = u_ptr + u_offset; 871 const uint8_t* v_ptr = u_ptr + u_offset;
827 libyuv::CopyPlane(y_ptr, stride, 872 libyuv::CopyPlane(y_ptr, stride,
828 i420_buffer->MutableDataY(), i420_buffer->StrideY(), 873 i420_buffer->MutableDataY(), i420_buffer->StrideY(),
829 width, height); 874 width, height);
830 libyuv::CopyPlane(u_ptr, uv_stride, 875 libyuv::CopyPlane(u_ptr, uv_stride,
831 i420_buffer->MutableDataU(), i420_buffer->StrideU(), 876 i420_buffer->MutableDataU(), i420_buffer->StrideU(),
832 chroma_width, chroma_height); 877 chroma_width, chroma_height);
833 libyuv::CopyPlane(v_ptr, uv_stride, 878 libyuv::CopyPlane(v_ptr, uv_stride,
834 i420_buffer->MutableDataV(), i420_buffer->StrideV(), 879 i420_buffer->MutableDataV(), i420_buffer->StrideV(),
835 chroma_width, chroma_height); 880 chroma_width, chroma_height);
836 if (slice_height % 2 == 1) { 881 if (slice_height % 2 == 1) {
837 RTC_CHECK_EQ(height, slice_height); 882 RTC_DCHECK_EQ(height, slice_height);
838 // Duplicate the last chroma rows. 883 // Duplicate the last chroma rows.
839 uint8_t* u_last_row_ptr = i420_buffer->MutableDataU() + 884 uint8_t* u_last_row_ptr = i420_buffer->MutableDataU() +
840 chroma_height * i420_buffer->StrideU(); 885 chroma_height * i420_buffer->StrideU();
841 memcpy(u_last_row_ptr, u_last_row_ptr - i420_buffer->StrideU(), 886 memcpy(u_last_row_ptr, u_last_row_ptr - i420_buffer->StrideU(),
842 i420_buffer->StrideU()); 887 i420_buffer->StrideU());
843 uint8_t* v_last_row_ptr = i420_buffer->MutableDataV() + 888 uint8_t* v_last_row_ptr = i420_buffer->MutableDataV() +
844 chroma_height * i420_buffer->StrideV(); 889 chroma_height * i420_buffer->StrideV();
845 memcpy(v_last_row_ptr, v_last_row_ptr - i420_buffer->StrideV(), 890 memcpy(v_last_row_ptr, v_last_row_ptr - i420_buffer->StrideV(),
846 i420_buffer->StrideV()); 891 i420_buffer->StrideV());
847 } 892 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 } 947 }
903 948
904 // If the frame was dropped, frame_buffer is left as nullptr. 949 // If the frame was dropped, frame_buffer is left as nullptr.
905 if (frame_buffer) { 950 if (frame_buffer) {
906 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0); 951 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0);
907 decoded_frame.set_timestamp(output_timestamps_ms); 952 decoded_frame.set_timestamp(output_timestamps_ms);
908 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); 953 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms);
909 954
910 rtc::Optional<uint8_t> qp = pending_frame_qps_.front(); 955 rtc::Optional<uint8_t> qp = pending_frame_qps_.front();
911 pending_frame_qps_.pop_front(); 956 pending_frame_qps_.pop_front();
912 callback_->Decoded(decoded_frame, rtc::Optional<int32_t>(decode_time_ms), 957 decoded_frames_.push_back(DecodedFrame(std::move(decoded_frame),
913 qp); 958 decode_time_ms, output_timestamps_ms,
959 output_ntp_timestamps_ms, qp));
914 } 960 }
961
962 frames->reserve(frames->size() + decoded_frames_.size());
963 std::move(decoded_frames_.begin(), decoded_frames_.end(),
964 std::back_inserter(*frames));
965 decoded_frames_.clear();
966
915 return true; 967 return true;
916 } 968 }
917 969
918 int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback( 970 int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback(
919 DecodedImageCallback* callback) { 971 DecodedImageCallback* callback) {
920 callback_ = callback; 972 callback_ = callback;
921 return WEBRTC_VIDEO_CODEC_OK; 973 return WEBRTC_VIDEO_CODEC_OK;
922 } 974 }
923 975
924 void MediaCodecVideoDecoder::OnMessage(rtc::Message* msg) {
925 JNIEnv* jni = AttachCurrentThreadIfNeeded();
926 ScopedLocalRefFrame local_ref_frame(jni);
927 if (!inited_) {
928 return;
929 }
930 // We only ever send one message to |this| directly (not through a Bind()'d
931 // functor), so expect no ID/data.
932 RTC_CHECK(!msg->message_id) << "Unexpected message!";
933 RTC_CHECK(!msg->pdata) << "Unexpected message!";
934 CheckOnCodecThread();
935
936 if (!DeliverPendingOutputs(jni, 0)) {
937 ALOGE << "OnMessage: DeliverPendingOutputs error";
938 ProcessHWErrorOnCodecThread();
939 return;
940 }
941 codec_thread_->PostDelayed(RTC_FROM_HERE, kMediaCodecPollMs, this);
942 }
943
944 MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() 976 MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory()
945 : egl_context_(nullptr) { 977 : egl_context_(nullptr) {
946 ALOGD << "MediaCodecVideoDecoderFactory ctor"; 978 ALOGD << "MediaCodecVideoDecoderFactory ctor";
947 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 979 JNIEnv* jni = AttachCurrentThreadIfNeeded();
948 ScopedLocalRefFrame local_ref_frame(jni); 980 ScopedLocalRefFrame local_ref_frame(jni);
949 jclass j_decoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoDecoder"); 981 jclass j_decoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoDecoder");
950 supported_codec_types_.clear(); 982 supported_codec_types_.clear();
951 983
952 bool is_vp8_hw_supported = jni->CallStaticBooleanMethod( 984 bool is_vp8_hw_supported = jni->CallStaticBooleanMethod(
953 j_decoder_class, 985 j_decoder_class,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 webrtc::VideoDecoder* decoder) { 1058 webrtc::VideoDecoder* decoder) {
1027 ALOGD << "Destroy video decoder."; 1059 ALOGD << "Destroy video decoder.";
1028 delete decoder; 1060 delete decoder;
1029 } 1061 }
1030 1062
1031 const char* MediaCodecVideoDecoder::ImplementationName() const { 1063 const char* MediaCodecVideoDecoder::ImplementationName() const {
1032 return "MediaCodec"; 1064 return "MediaCodec";
1033 } 1065 }
1034 1066
1035 } // namespace webrtc_jni 1067 } // namespace webrtc_jni
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/video_receiver.cc ('k') | webrtc/video/video_receive_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698