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

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

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