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

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

Issue 2777203003: Android: Remove codec thread from MediaCodecVideoDecoder. (Closed)
Patch Set: Rebase. 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/sdk/android/api/org/webrtc/MediaCodecVideoDecoder.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 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 #include <algorithm> 11 #include <algorithm>
12 #include <deque> 12 #include <deque>
13 #include <memory> 13 #include <memory>
14 #include <vector> 14 #include <vector>
15 15
16 // NOTICE: androidmediadecoder_jni.h must be included before 16 // NOTICE: androidmediadecoder_jni.h must be included before
17 // androidmediacodeccommon.h to avoid build errors. 17 // androidmediacodeccommon.h to avoid build errors.
18 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" 18 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h"
19 19
20 #include "third_party/libyuv/include/libyuv/convert.h" 20 #include "third_party/libyuv/include/libyuv/convert.h"
21 #include "third_party/libyuv/include/libyuv/convert_from.h" 21 #include "third_party/libyuv/include/libyuv/convert_from.h"
22 #include "third_party/libyuv/include/libyuv/video_common.h" 22 #include "third_party/libyuv/include/libyuv/video_common.h"
23 #include "webrtc/base/bind.h" 23 #include "webrtc/base/bind.h"
24 #include "webrtc/base/checks.h" 24 #include "webrtc/base/checks.h"
25 #include "webrtc/base/logging.h" 25 #include "webrtc/base/logging.h"
26 #include "webrtc/base/scoped_ref_ptr.h" 26 #include "webrtc/base/scoped_ref_ptr.h"
27 #include "webrtc/base/thread.h" 27 #include "webrtc/base/thread_checker.h"
28 #include "webrtc/base/timeutils.h" 28 #include "webrtc/base/timeutils.h"
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"
(...skipping 20 matching lines...) Expand all
58 using webrtc::VideoFrame; 58 using webrtc::VideoFrame;
59 using webrtc::RTPFragmentationHeader; 59 using webrtc::RTPFragmentationHeader;
60 using webrtc::VideoCodec; 60 using webrtc::VideoCodec;
61 using webrtc::VideoCodecType; 61 using webrtc::VideoCodecType;
62 using webrtc::kVideoCodecH264; 62 using webrtc::kVideoCodecH264;
63 using webrtc::kVideoCodecVP8; 63 using webrtc::kVideoCodecVP8;
64 using webrtc::kVideoCodecVP9; 64 using webrtc::kVideoCodecVP9;
65 65
66 namespace webrtc_jni { 66 namespace webrtc_jni {
67 67
68 // All calls should be made on the decoding thread expect for release which can
69 // be called after the decoder thread has been stopped.
68 class MediaCodecVideoDecoder : public webrtc::VideoDecoder { 70 class MediaCodecVideoDecoder : public webrtc::VideoDecoder {
69 public: 71 public:
70 explicit MediaCodecVideoDecoder( 72 explicit MediaCodecVideoDecoder(
71 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context); 73 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context);
72 virtual ~MediaCodecVideoDecoder(); 74 virtual ~MediaCodecVideoDecoder();
73 75
74 int32_t InitDecode(const VideoCodec* codecSettings, int32_t numberOfCores) 76 int32_t InitDecode(const VideoCodec* codecSettings, int32_t numberOfCores)
75 override; 77 override;
76 78
77 int32_t Decode( 79 int32_t Decode(
78 const EncodedImage& inputImage, bool missingFrames, 80 const EncodedImage& inputImage, bool missingFrames,
79 const RTPFragmentationHeader* fragmentation, 81 const RTPFragmentationHeader* fragmentation,
80 const CodecSpecificInfo* codecSpecificInfo = NULL, 82 const CodecSpecificInfo* codecSpecificInfo = NULL,
81 int64_t renderTimeMs = -1) override; 83 int64_t renderTimeMs = -1) override;
82 84
83 void PollDecodedFrames() override; 85 void PollDecodedFrames() override;
84 86
85 int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback) 87 int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback)
86 override; 88 override;
87 89
88 int32_t Release() override; 90 int32_t Release() override;
89 91
90 bool PrefersLateDecoding() const override { return true; } 92 bool PrefersLateDecoding() const override { return true; }
91 93
92 const char* ImplementationName() const override; 94 const char* ImplementationName() const override;
93 95
94 private: 96 private:
95 struct DecodedFrame { 97 int32_t InitDecodeInternal();
96 DecodedFrame(VideoFrame frame, 98 int32_t ResetDecode();
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
116 int32_t InitDecodeOnCodecThread();
117 int32_t ResetDecodeOnCodecThread();
118 int32_t ReleaseOnCodecThread();
119 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 99 // Deliver any outputs pending in the MediaCodec to our |callback_| and return
123 // true on success. 100 // true on success.
124 bool DeliverPendingOutputs(JNIEnv* jni, 101 bool DeliverPendingOutputs(JNIEnv* jni, int dequeue_timeout_us);
125 int dequeue_timeout_us, 102 int32_t ProcessHWError();
126 std::vector<DecodedFrame>* frames);
127 int32_t ProcessHWErrorOnCodecThread();
128 void EnableFrameLogOnWarning(); 103 void EnableFrameLogOnWarning();
129 void ResetVariables(); 104 void ResetVariables();
130 105
131 // Type of video codec. 106 // Type of video codec.
132 VideoCodecType codecType_; 107 VideoCodecType codecType_;
133 108
134 // Render EGL context - owned by factory, should not be allocated/destroyed 109 // Render EGL context - owned by factory, should not be allocated/destroyed
135 // by VideoDecoder. 110 // by VideoDecoder.
136 jobject render_egl_context_; 111 jobject render_egl_context_;
137 112
(...skipping 13 matching lines...) Expand all
151 int current_frames_; // Number of frames in the current statistics interval. 126 int current_frames_; // Number of frames in the current statistics interval.
152 int current_bytes_; // Encoded bytes in the current statistics interval. 127 int current_bytes_; // Encoded bytes in the current statistics interval.
153 int current_decoding_time_ms_; // Overall decoding time in the current second 128 int current_decoding_time_ms_; // Overall decoding time in the current second
154 int current_delay_time_ms_; // Overall delay time in the current second. 129 int current_delay_time_ms_; // Overall delay time in the current second.
155 uint32_t max_pending_frames_; // Maximum number of pending input frames. 130 uint32_t max_pending_frames_; // Maximum number of pending input frames.
156 webrtc::H264BitstreamParser h264_bitstream_parser_; 131 webrtc::H264BitstreamParser h264_bitstream_parser_;
157 std::deque<rtc::Optional<uint8_t>> pending_frame_qps_; 132 std::deque<rtc::Optional<uint8_t>> pending_frame_qps_;
158 133
159 // State that is constant for the lifetime of this object once the ctor 134 // State that is constant for the lifetime of this object once the ctor
160 // returns. 135 // returns.
161 std::unique_ptr<Thread> 136 rtc::ThreadChecker decode_thread_checker_;
162 codec_thread_; // Thread on which to operate MediaCodec.
163 ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_; 137 ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_;
164 ScopedGlobalRef<jobject> j_media_codec_video_decoder_; 138 ScopedGlobalRef<jobject> j_media_codec_video_decoder_;
165 jmethodID j_init_decode_method_; 139 jmethodID j_init_decode_method_;
166 jmethodID j_reset_method_; 140 jmethodID j_reset_method_;
167 jmethodID j_release_method_; 141 jmethodID j_release_method_;
168 jmethodID j_dequeue_input_buffer_method_; 142 jmethodID j_dequeue_input_buffer_method_;
169 jmethodID j_queue_input_buffer_method_; 143 jmethodID j_queue_input_buffer_method_;
170 jmethodID j_dequeue_byte_buffer_method_; 144 jmethodID j_dequeue_byte_buffer_method_;
171 jmethodID j_dequeue_texture_buffer_method_; 145 jmethodID j_dequeue_texture_buffer_method_;
172 jmethodID j_return_decoded_byte_buffer_method_; 146 jmethodID j_return_decoded_byte_buffer_method_;
(...skipping 17 matching lines...) Expand all
190 jfieldID j_info_index_field_; 164 jfieldID j_info_index_field_;
191 jfieldID j_info_offset_field_; 165 jfieldID j_info_offset_field_;
192 jfieldID j_info_size_field_; 166 jfieldID j_info_size_field_;
193 jfieldID j_presentation_timestamp_ms_field_; 167 jfieldID j_presentation_timestamp_ms_field_;
194 jfieldID j_timestamp_ms_field_; 168 jfieldID j_timestamp_ms_field_;
195 jfieldID j_ntp_timestamp_ms_field_; 169 jfieldID j_ntp_timestamp_ms_field_;
196 jfieldID j_byte_buffer_decode_time_ms_field_; 170 jfieldID j_byte_buffer_decode_time_ms_field_;
197 171
198 // Global references; must be deleted in Release(). 172 // Global references; must be deleted in Release().
199 std::vector<jobject> input_buffers_; 173 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 }; 174 };
204 175
205 MediaCodecVideoDecoder::MediaCodecVideoDecoder( 176 MediaCodecVideoDecoder::MediaCodecVideoDecoder(
206 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context) : 177 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context) :
207 codecType_(codecType), 178 codecType_(codecType),
208 render_egl_context_(render_egl_context), 179 render_egl_context_(render_egl_context),
209 key_frame_required_(true), 180 key_frame_required_(true),
210 inited_(false), 181 inited_(false),
211 sw_fallback_required_(false), 182 sw_fallback_required_(false),
212 codec_thread_(new Thread()),
213 j_media_codec_video_decoder_class_( 183 j_media_codec_video_decoder_class_(
214 jni, 184 jni,
215 FindClass(jni, "org/webrtc/MediaCodecVideoDecoder")), 185 FindClass(jni, "org/webrtc/MediaCodecVideoDecoder")),
216 j_media_codec_video_decoder_( 186 j_media_codec_video_decoder_(
217 jni, 187 jni,
218 jni->NewObject(*j_media_codec_video_decoder_class_, 188 jni->NewObject(*j_media_codec_video_decoder_class_,
219 GetMethodID(jni, 189 GetMethodID(jni,
220 *j_media_codec_video_decoder_class_, 190 *j_media_codec_video_decoder_class_,
221 "<init>", 191 "<init>",
222 "()V"))) { 192 "()V"))) {
223 codec_thread_->SetName("MediaCodecVideoDecoder", NULL); 193 decode_thread_checker_.DetachFromThread();
224 RTC_CHECK(codec_thread_->Start());
225 194
226 j_init_decode_method_ = GetMethodID( 195 j_init_decode_method_ = GetMethodID(
227 jni, *j_media_codec_video_decoder_class_, "initDecode", 196 jni, *j_media_codec_video_decoder_class_, "initDecode",
228 "(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;" 197 "(Lorg/webrtc/MediaCodecVideoDecoder$VideoCodecType;"
229 "IILorg/webrtc/SurfaceTextureHelper;)Z"); 198 "IILorg/webrtc/SurfaceTextureHelper;)Z");
230 j_reset_method_ = 199 j_reset_method_ =
231 GetMethodID(jni, *j_media_codec_video_decoder_class_, "reset", "(II)V"); 200 GetMethodID(jni, *j_media_codec_video_decoder_class_, "reset", "(II)V");
232 j_release_method_ = 201 j_release_method_ =
233 GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V"); 202 GetMethodID(jni, *j_media_codec_video_decoder_class_, "release", "()V");
234 j_dequeue_input_buffer_method_ = GetMethodID( 203 j_dequeue_input_buffer_method_ = GetMethodID(
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 AllowBlockingCalls(); 272 AllowBlockingCalls();
304 } 273 }
305 274
306 MediaCodecVideoDecoder::~MediaCodecVideoDecoder() { 275 MediaCodecVideoDecoder::~MediaCodecVideoDecoder() {
307 // Call Release() to ensure no more callbacks to us after we are deleted. 276 // Call Release() to ensure no more callbacks to us after we are deleted.
308 Release(); 277 Release();
309 } 278 }
310 279
311 int32_t MediaCodecVideoDecoder::InitDecode(const VideoCodec* inst, 280 int32_t MediaCodecVideoDecoder::InitDecode(const VideoCodec* inst,
312 int32_t numberOfCores) { 281 int32_t numberOfCores) {
282 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
313 ALOGD << "InitDecode."; 283 ALOGD << "InitDecode.";
314 if (inst == NULL) { 284 if (inst == NULL) {
315 ALOGE << "NULL VideoCodec instance"; 285 ALOGE << "NULL VideoCodec instance";
316 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 286 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
317 } 287 }
318 // Factory should guard against other codecs being used with us. 288 // Factory should guard against other codecs being used with us.
319 RTC_DCHECK(inst->codecType == codecType_) 289 RTC_DCHECK(inst->codecType == codecType_)
320 << "Unsupported codec " << inst->codecType << " for " << codecType_; 290 << "Unsupported codec " << inst->codecType << " for " << codecType_;
321 291
322 if (sw_fallback_required_) { 292 if (sw_fallback_required_) {
323 ALOGE << "InitDecode() - fallback to SW decoder"; 293 ALOGE << "InitDecode() - fallback to SW decoder";
324 return WEBRTC_VIDEO_CODEC_OK; 294 return WEBRTC_VIDEO_CODEC_OK;
325 } 295 }
326 // Save VideoCodec instance for later. 296 // Save VideoCodec instance for later.
327 if (&codec_ != inst) { 297 if (&codec_ != inst) {
328 codec_ = *inst; 298 codec_ = *inst;
329 } 299 }
330 // If maxFramerate is not set then assume 30 fps. 300 // If maxFramerate is not set then assume 30 fps.
331 codec_.maxFramerate = (codec_.maxFramerate >= 1) ? codec_.maxFramerate : 30; 301 codec_.maxFramerate = (codec_.maxFramerate >= 1) ? codec_.maxFramerate : 30;
332 302
333 // Call Java init. 303 // Call Java init.
334 return codec_thread_->Invoke<int32_t>( 304 return InitDecodeInternal();
335 RTC_FROM_HERE,
336 Bind(&MediaCodecVideoDecoder::InitDecodeOnCodecThread, this));
337 } 305 }
338 306
339 void MediaCodecVideoDecoder::ResetVariables() { 307 void MediaCodecVideoDecoder::ResetVariables() {
340 RTC_DCHECK(IsOnCodecThread()); 308 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
341 309
342 key_frame_required_ = true; 310 key_frame_required_ = true;
343 frames_received_ = 0; 311 frames_received_ = 0;
344 frames_decoded_ = 0; 312 frames_decoded_ = 0;
345 frames_decoded_logged_ = kMaxDecodedLogFrames; 313 frames_decoded_logged_ = kMaxDecodedLogFrames;
346 start_time_ms_ = rtc::TimeMillis(); 314 start_time_ms_ = rtc::TimeMillis();
347 current_frames_ = 0; 315 current_frames_ = 0;
348 current_bytes_ = 0; 316 current_bytes_ = 0;
349 current_decoding_time_ms_ = 0; 317 current_decoding_time_ms_ = 0;
350 current_delay_time_ms_ = 0; 318 current_delay_time_ms_ = 0;
351 pending_frame_qps_.clear(); 319 pending_frame_qps_.clear();
352 } 320 }
353 321
354 int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { 322 int32_t MediaCodecVideoDecoder::InitDecodeInternal() {
355 RTC_DCHECK(IsOnCodecThread()); 323 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
356 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 324 JNIEnv* jni = AttachCurrentThreadIfNeeded();
357 ScopedLocalRefFrame local_ref_frame(jni); 325 ScopedLocalRefFrame local_ref_frame(jni);
358 ALOGD << "InitDecodeOnCodecThread Type: " << (int)codecType_ << ". " 326 ALOGD << "InitDecodeInternal Type: " << (int)codecType_ << ". "
359 << codec_.width << " x " << codec_.height << ". Fps: " << 327 << codec_.width << " x " << codec_.height
360 (int)codec_.maxFramerate; 328 << ". Fps: " << (int)codec_.maxFramerate;
361 329
362 // Release previous codec first if it was allocated before. 330 // Release previous codec first if it was allocated before.
363 int ret_val = ReleaseOnCodecThread(); 331 int ret_val = Release();
364 if (ret_val < 0) { 332 if (ret_val < 0) {
365 ALOGE << "Release failure: " << ret_val << " - fallback to SW codec"; 333 ALOGE << "Release failure: " << ret_val << " - fallback to SW codec";
366 sw_fallback_required_ = true; 334 sw_fallback_required_ = true;
367 return WEBRTC_VIDEO_CODEC_ERROR; 335 return WEBRTC_VIDEO_CODEC_ERROR;
368 } 336 }
369 337
370 ResetVariables(); 338 ResetVariables();
371 339
372 if (use_surface_) { 340 if (use_surface_) {
373 surface_texture_helper_ = SurfaceTextureHelper::create( 341 surface_texture_helper_ = SurfaceTextureHelper::create(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (CheckException(jni)) { 390 if (CheckException(jni)) {
423 ALOGE << "NewGlobalRef error - fallback to SW codec."; 391 ALOGE << "NewGlobalRef error - fallback to SW codec.";
424 sw_fallback_required_ = true; 392 sw_fallback_required_ = true;
425 return WEBRTC_VIDEO_CODEC_ERROR; 393 return WEBRTC_VIDEO_CODEC_ERROR;
426 } 394 }
427 } 395 }
428 396
429 return WEBRTC_VIDEO_CODEC_OK; 397 return WEBRTC_VIDEO_CODEC_OK;
430 } 398 }
431 399
432 int32_t MediaCodecVideoDecoder::ResetDecodeOnCodecThread() { 400 int32_t MediaCodecVideoDecoder::ResetDecode() {
433 RTC_DCHECK(IsOnCodecThread()); 401 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
434 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 402 JNIEnv* jni = AttachCurrentThreadIfNeeded();
435 ScopedLocalRefFrame local_ref_frame(jni); 403 ScopedLocalRefFrame local_ref_frame(jni);
436 ALOGD << "ResetDecodeOnCodecThread Type: " << (int)codecType_ << ". " 404 ALOGD << "ResetDecode Type: " << (int)codecType_ << ". " << codec_.width
437 << codec_.width << " x " << codec_.height; 405 << " x " << codec_.height;
438 ALOGD << " Frames received: " << frames_received_ << 406 ALOGD << " Frames received: " << frames_received_ <<
439 ". Frames decoded: " << frames_decoded_; 407 ". Frames decoded: " << frames_decoded_;
440 408
441 inited_ = false; 409 inited_ = false;
442 ResetVariables(); 410 ResetVariables();
443 411
444 jni->CallVoidMethod( 412 jni->CallVoidMethod(
445 *j_media_codec_video_decoder_, 413 *j_media_codec_video_decoder_,
446 j_reset_method_, 414 j_reset_method_,
447 codec_.width, 415 codec_.width,
448 codec_.height); 416 codec_.height);
449 417
450 if (CheckException(jni)) { 418 if (CheckException(jni)) {
451 ALOGE << "Soft reset error - fallback to SW codec."; 419 ALOGE << "Soft reset error - fallback to SW codec.";
452 sw_fallback_required_ = true; 420 sw_fallback_required_ = true;
453 return WEBRTC_VIDEO_CODEC_ERROR; 421 return WEBRTC_VIDEO_CODEC_ERROR;
454 } 422 }
455 inited_ = true; 423 inited_ = true;
456 424
457 return WEBRTC_VIDEO_CODEC_OK; 425 return WEBRTC_VIDEO_CODEC_OK;
458 } 426 }
459 427
460 int32_t MediaCodecVideoDecoder::Release() { 428 int32_t MediaCodecVideoDecoder::Release() {
461 ALOGD << "DecoderRelease request"; 429 ALOGD << "DecoderRelease request";
462 return codec_thread_->Invoke<int32_t>(
463 RTC_FROM_HERE, Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this));
464 }
465
466 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() {
467 RTC_DCHECK(IsOnCodecThread());
468 if (!inited_) { 430 if (!inited_) {
469 return WEBRTC_VIDEO_CODEC_OK; 431 return WEBRTC_VIDEO_CODEC_OK;
470 } 432 }
471 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 433 JNIEnv* jni = AttachCurrentThreadIfNeeded();
472 ALOGD << "DecoderReleaseOnCodecThread: Frames received: " << 434 ALOGD << "DecoderRelease: Frames received: " << frames_received_
473 frames_received_ << ". Frames decoded: " << frames_decoded_; 435 << ". Frames decoded: " << frames_decoded_;
474 ScopedLocalRefFrame local_ref_frame(jni); 436 ScopedLocalRefFrame local_ref_frame(jni);
475 for (size_t i = 0; i < input_buffers_.size(); i++) { 437 for (size_t i = 0; i < input_buffers_.size(); i++) {
476 jni->DeleteGlobalRef(input_buffers_[i]); 438 jni->DeleteGlobalRef(input_buffers_[i]);
477 } 439 }
478 input_buffers_.clear(); 440 input_buffers_.clear();
479 jni->CallVoidMethod(*j_media_codec_video_decoder_, j_release_method_); 441 jni->CallVoidMethod(*j_media_codec_video_decoder_, j_release_method_);
480 surface_texture_helper_ = nullptr; 442 surface_texture_helper_ = nullptr;
481 inited_ = false; 443 inited_ = false;
482 if (CheckException(jni)) { 444 if (CheckException(jni)) {
483 ALOGE << "Decoder release exception"; 445 ALOGE << "Decoder release exception";
484 return WEBRTC_VIDEO_CODEC_ERROR; 446 return WEBRTC_VIDEO_CODEC_ERROR;
485 } 447 }
486 ALOGD << "DecoderReleaseOnCodecThread done"; 448 ALOGD << "DecoderRelease done";
487 return WEBRTC_VIDEO_CODEC_OK; 449 return WEBRTC_VIDEO_CODEC_OK;
488 } 450 }
489 451
490 bool MediaCodecVideoDecoder::IsOnCodecThread() {
491 return codec_thread_.get() == ThreadManager::Instance()->CurrentThread();
492 }
493
494 void MediaCodecVideoDecoder::EnableFrameLogOnWarning() { 452 void MediaCodecVideoDecoder::EnableFrameLogOnWarning() {
495 // Log next 2 output frames. 453 // Log next 2 output frames.
496 static const int kMaxWarningLogFrames = 2; 454 static const int kMaxWarningLogFrames = 2;
497 frames_decoded_logged_ = std::max( 455 frames_decoded_logged_ = std::max(
498 frames_decoded_logged_, frames_decoded_ + kMaxWarningLogFrames); 456 frames_decoded_logged_, frames_decoded_ + kMaxWarningLogFrames);
499 } 457 }
500 458
501 int32_t MediaCodecVideoDecoder::ProcessHWErrorOnCodecThread() { 459 int32_t MediaCodecVideoDecoder::ProcessHWError() {
502 RTC_DCHECK(IsOnCodecThread()); 460 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
503 int ret_val = ReleaseOnCodecThread(); 461 int ret_val = Release();
504 if (ret_val < 0) { 462 if (ret_val < 0) {
505 ALOGE << "ProcessHWError: Release failure"; 463 ALOGE << "ProcessHWError: Release failure";
506 } 464 }
507 if (codecType_ == kVideoCodecH264) { 465 if (codecType_ == kVideoCodecH264) {
508 // For now there is no SW H.264 which can be used as fallback codec. 466 // For now there is no SW H.264 which can be used as fallback codec.
509 // So try to restart hw codec for now. 467 // So try to restart hw codec for now.
510 ret_val = InitDecodeOnCodecThread(); 468 ret_val = InitDecodeInternal();
511 ALOGE << "Reset H.264 codec done. Status: " << ret_val; 469 ALOGE << "Reset H.264 codec done. Status: " << ret_val;
512 if (ret_val == WEBRTC_VIDEO_CODEC_OK) { 470 if (ret_val == WEBRTC_VIDEO_CODEC_OK) {
513 // H.264 codec was succesfully reset - return regular error code. 471 // H.264 codec was succesfully reset - return regular error code.
514 return WEBRTC_VIDEO_CODEC_ERROR; 472 return WEBRTC_VIDEO_CODEC_ERROR;
515 } else { 473 } else {
516 // Fail to restart H.264 codec - return error code which should stop the 474 // Fail to restart H.264 codec - return error code which should stop the
517 // call. 475 // call.
518 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 476 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
519 } 477 }
520 } else { 478 } else {
521 sw_fallback_required_ = true; 479 sw_fallback_required_ = true;
522 ALOGE << "Return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE"; 480 ALOGE << "Return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE";
523 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 481 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
524 } 482 }
525 } 483 }
526 484
527 int32_t MediaCodecVideoDecoder::Decode( 485 int32_t MediaCodecVideoDecoder::Decode(
528 const EncodedImage& inputImage, 486 const EncodedImage& inputImage,
529 bool missingFrames, 487 bool missingFrames,
530 const RTPFragmentationHeader* fragmentation, 488 const RTPFragmentationHeader* fragmentation,
531 const CodecSpecificInfo* codecSpecificInfo, 489 const CodecSpecificInfo* codecSpecificInfo,
532 int64_t renderTimeMs) { 490 int64_t renderTimeMs) {
491 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
533 RTC_DCHECK(callback_); 492 RTC_DCHECK(callback_);
534 RTC_DCHECK(inited_); 493 RTC_DCHECK(inited_);
535 494
536 if (sw_fallback_required_) { 495 if (sw_fallback_required_) {
537 ALOGE << "Decode() - fallback to SW codec"; 496 ALOGE << "Decode() - fallback to SW codec";
538 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 497 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
539 } 498 }
540 if (inputImage._buffer == NULL && inputImage._length > 0) { 499 if (inputImage._buffer == NULL && inputImage._length > 0) {
541 ALOGE << "Decode() - inputImage is incorrect"; 500 ALOGE << "Decode() - inputImage is incorrect";
542 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 501 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
543 } 502 }
544 503
545 // Check if encoded frame dimension has changed. 504 // Check if encoded frame dimension has changed.
546 if ((inputImage._encodedWidth * inputImage._encodedHeight > 0) && 505 if ((inputImage._encodedWidth * inputImage._encodedHeight > 0) &&
547 (inputImage._encodedWidth != codec_.width || 506 (inputImage._encodedWidth != codec_.width ||
548 inputImage._encodedHeight != codec_.height)) { 507 inputImage._encodedHeight != codec_.height)) {
549 ALOGW << "Input resolution changed from " << 508 ALOGW << "Input resolution changed from " <<
550 codec_.width << " x " << codec_.height << " to " << 509 codec_.width << " x " << codec_.height << " to " <<
551 inputImage._encodedWidth << " x " << inputImage._encodedHeight; 510 inputImage._encodedWidth << " x " << inputImage._encodedHeight;
552 codec_.width = inputImage._encodedWidth; 511 codec_.width = inputImage._encodedWidth;
553 codec_.height = inputImage._encodedHeight; 512 codec_.height = inputImage._encodedHeight;
554 int32_t ret; 513 int32_t ret;
555 if (use_surface_ && 514 if (use_surface_ &&
556 (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecH264)) { 515 (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecH264)) {
557 // Soft codec reset - only for surface decoding. 516 // Soft codec reset - only for surface decoding.
558 ret = codec_thread_->Invoke<int32_t>( 517 ret = ResetDecode();
559 RTC_FROM_HERE,
560 Bind(&MediaCodecVideoDecoder::ResetDecodeOnCodecThread, this));
561 } else { 518 } else {
562 // Hard codec reset. 519 // Hard codec reset.
563 ret = InitDecode(&codec_, 1); 520 ret = InitDecode(&codec_, 1);
564 } 521 }
565 if (ret < 0) { 522 if (ret < 0) {
566 ALOGE << "InitDecode failure: " << ret << " - fallback to SW codec"; 523 ALOGE << "InitDecode failure: " << ret << " - fallback to SW codec";
567 sw_fallback_required_ = true; 524 sw_fallback_required_ = true;
568 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; 525 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
569 } 526 }
570 } 527 }
571 528
572 // Always start with a complete key frame. 529 // Always start with a complete key frame.
573 if (key_frame_required_) { 530 if (key_frame_required_) {
574 if (inputImage._frameType != webrtc::kVideoFrameKey) { 531 if (inputImage._frameType != webrtc::kVideoFrameKey) {
575 ALOGE << "Decode() - key frame is required"; 532 ALOGE << "Decode() - key frame is required";
576 return WEBRTC_VIDEO_CODEC_ERROR; 533 return WEBRTC_VIDEO_CODEC_ERROR;
577 } 534 }
578 if (!inputImage._completeFrame) { 535 if (!inputImage._completeFrame) {
579 ALOGE << "Decode() - complete frame is required"; 536 ALOGE << "Decode() - complete frame is required";
580 return WEBRTC_VIDEO_CODEC_ERROR; 537 return WEBRTC_VIDEO_CODEC_ERROR;
581 } 538 }
582 key_frame_required_ = false; 539 key_frame_required_ = false;
583 } 540 }
584 if (inputImage._length == 0) { 541 if (inputImage._length == 0) {
585 return WEBRTC_VIDEO_CODEC_ERROR; 542 return WEBRTC_VIDEO_CODEC_ERROR;
586 } 543 }
587 544
588 std::vector<DecodedFrame> frames; 545 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
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,
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);
608 }
609
610 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread(
611 const EncodedImage& inputImage,
612 std::vector<DecodedFrame>* frames) {
613 RTC_DCHECK(IsOnCodecThread());
614 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 546 JNIEnv* jni = AttachCurrentThreadIfNeeded();
615 ScopedLocalRefFrame local_ref_frame(jni); 547 ScopedLocalRefFrame local_ref_frame(jni);
616 548
617 // Try to drain the decoder and wait until output is not too 549 // Try to drain the decoder and wait until output is not too
618 // much behind the input. 550 // much behind the input.
619 if (codecType_ == kVideoCodecH264 && 551 if (codecType_ == kVideoCodecH264 &&
620 frames_received_ > frames_decoded_ + max_pending_frames_) { 552 frames_received_ > frames_decoded_ + max_pending_frames_) {
621 // Print warning for H.264 only - for VP8/VP9 one frame delay is ok. 553 // 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: " << 554 ALOGW << "Decoder is too far behind. Try to drain. Received: " <<
623 frames_received_ << ". Decoded: " << frames_decoded_; 555 frames_received_ << ". Decoded: " << frames_decoded_;
624 EnableFrameLogOnWarning(); 556 EnableFrameLogOnWarning();
625 } 557 }
626 const int64 drain_start = rtc::TimeMillis(); 558 const int64 drain_start = rtc::TimeMillis();
627 while ((frames_received_ > frames_decoded_ + max_pending_frames_) && 559 while ((frames_received_ > frames_decoded_ + max_pending_frames_) &&
628 (rtc::TimeMillis() - drain_start) < kMediaCodecTimeoutMs) { 560 (rtc::TimeMillis() - drain_start) < kMediaCodecTimeoutMs) {
629 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs, frames)) { 561 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs)) {
630 ALOGE << "DeliverPendingOutputs error. Frames received: " << 562 ALOGE << "DeliverPendingOutputs error. Frames received: " <<
631 frames_received_ << ". Frames decoded: " << frames_decoded_; 563 frames_received_ << ". Frames decoded: " << frames_decoded_;
632 return ProcessHWErrorOnCodecThread(); 564 return ProcessHWError();
633 } 565 }
634 } 566 }
635 if (frames_received_ > frames_decoded_ + max_pending_frames_) { 567 if (frames_received_ > frames_decoded_ + max_pending_frames_) {
636 ALOGE << "Output buffer dequeue timeout. Frames received: " << 568 ALOGE << "Output buffer dequeue timeout. Frames received: " <<
637 frames_received_ << ". Frames decoded: " << frames_decoded_; 569 frames_received_ << ". Frames decoded: " << frames_decoded_;
638 return ProcessHWErrorOnCodecThread(); 570 return ProcessHWError();
639 } 571 }
640 572
641 // Get input buffer. 573 // Get input buffer.
642 int j_input_buffer_index = jni->CallIntMethod( 574 int j_input_buffer_index = jni->CallIntMethod(
643 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_); 575 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_);
644 if (CheckException(jni) || j_input_buffer_index < 0) { 576 if (CheckException(jni) || j_input_buffer_index < 0) {
645 ALOGE << "dequeueInputBuffer error: " << j_input_buffer_index << 577 ALOGE << "dequeueInputBuffer error: " << j_input_buffer_index <<
646 ". Retry DeliverPendingOutputs."; 578 ". Retry DeliverPendingOutputs.";
647 EnableFrameLogOnWarning(); 579 EnableFrameLogOnWarning();
648 // Try to drain the decoder. 580 // Try to drain the decoder.
649 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs, frames)) { 581 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs)) {
650 ALOGE << "DeliverPendingOutputs error. Frames received: " << 582 ALOGE << "DeliverPendingOutputs error. Frames received: " <<
651 frames_received_ << ". Frames decoded: " << frames_decoded_; 583 frames_received_ << ". Frames decoded: " << frames_decoded_;
652 return ProcessHWErrorOnCodecThread(); 584 return ProcessHWError();
653 } 585 }
654 // Try dequeue input buffer one last time. 586 // Try dequeue input buffer one last time.
655 j_input_buffer_index = jni->CallIntMethod( 587 j_input_buffer_index = jni->CallIntMethod(
656 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_); 588 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_);
657 if (CheckException(jni) || j_input_buffer_index < 0) { 589 if (CheckException(jni) || j_input_buffer_index < 0) {
658 ALOGE << "dequeueInputBuffer critical error: " << j_input_buffer_index; 590 ALOGE << "dequeueInputBuffer critical error: " << j_input_buffer_index;
659 return ProcessHWErrorOnCodecThread(); 591 return ProcessHWError();
660 } 592 }
661 } 593 }
662 594
663 // Copy encoded data to Java ByteBuffer. 595 // Copy encoded data to Java ByteBuffer.
664 jobject j_input_buffer = input_buffers_[j_input_buffer_index]; 596 jobject j_input_buffer = input_buffers_[j_input_buffer_index];
665 uint8_t* buffer = 597 uint8_t* buffer =
666 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer)); 598 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer));
667 RTC_DCHECK(buffer) << "Indirect buffer??"; 599 RTC_DCHECK(buffer) << "Indirect buffer??";
668 int64_t buffer_capacity = jni->GetDirectBufferCapacity(j_input_buffer); 600 int64_t buffer_capacity = jni->GetDirectBufferCapacity(j_input_buffer);
669 if (CheckException(jni) || buffer_capacity < inputImage._length) { 601 if (CheckException(jni) || buffer_capacity < inputImage._length) {
670 ALOGE << "Input frame size "<< inputImage._length << 602 ALOGE << "Input frame size "<< inputImage._length <<
671 " is bigger than buffer size " << buffer_capacity; 603 " is bigger than buffer size " << buffer_capacity;
672 return ProcessHWErrorOnCodecThread(); 604 return ProcessHWError();
673 } 605 }
674 jlong presentation_timestamp_us = static_cast<jlong>( 606 jlong presentation_timestamp_us = static_cast<jlong>(
675 static_cast<int64_t>(frames_received_) * 1000000 / codec_.maxFramerate); 607 static_cast<int64_t>(frames_received_) * 1000000 / codec_.maxFramerate);
676 memcpy(buffer, inputImage._buffer, inputImage._length); 608 memcpy(buffer, inputImage._buffer, inputImage._length);
677 609
678 if (frames_decoded_ < frames_decoded_logged_) { 610 if (frames_decoded_ < frames_decoded_logged_) {
679 ALOGD << "Decoder frame in # " << frames_received_ << 611 ALOGD << "Decoder frame in # " << frames_received_ <<
680 ". Type: " << inputImage._frameType << 612 ". Type: " << inputImage._frameType <<
681 ". Buffer # " << j_input_buffer_index << 613 ". Buffer # " << j_input_buffer_index <<
682 ". TS: " << presentation_timestamp_us / 1000 << 614 ". TS: " << presentation_timestamp_us / 1000 <<
(...skipping 23 matching lines...) Expand all
706 bool success = jni->CallBooleanMethod( 638 bool success = jni->CallBooleanMethod(
707 *j_media_codec_video_decoder_, 639 *j_media_codec_video_decoder_,
708 j_queue_input_buffer_method_, 640 j_queue_input_buffer_method_,
709 j_input_buffer_index, 641 j_input_buffer_index,
710 inputImage._length, 642 inputImage._length,
711 presentation_timestamp_us, 643 presentation_timestamp_us,
712 static_cast<int64_t> (inputImage._timeStamp), 644 static_cast<int64_t> (inputImage._timeStamp),
713 inputImage.ntp_time_ms_); 645 inputImage.ntp_time_ms_);
714 if (CheckException(jni) || !success) { 646 if (CheckException(jni) || !success) {
715 ALOGE << "queueInputBuffer error"; 647 ALOGE << "queueInputBuffer error";
716 return ProcessHWErrorOnCodecThread(); 648 return ProcessHWError();
717 } 649 }
718 650
719 // Try to drain the decoder 651 // Try to drain the decoder
720 if (!DeliverPendingOutputs(jni, 0, frames)) { 652 if (!DeliverPendingOutputs(jni, 0)) {
721 ALOGE << "DeliverPendingOutputs error"; 653 ALOGE << "DeliverPendingOutputs error";
722 return ProcessHWErrorOnCodecThread(); 654 return ProcessHWError();
723 } 655 }
724 656
725 return WEBRTC_VIDEO_CODEC_OK; 657 return WEBRTC_VIDEO_CODEC_OK;
726 } 658 }
727 659
728 void MediaCodecVideoDecoder::PollDecodedFramesOnCodecThread( 660 void MediaCodecVideoDecoder::PollDecodedFrames() {
729 std::vector<DecodedFrame>* frames) { 661 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
730 RTC_DCHECK(IsOnCodecThread());
731 662
732 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 663 JNIEnv* jni = AttachCurrentThreadIfNeeded();
733 ScopedLocalRefFrame local_ref_frame(jni); 664 ScopedLocalRefFrame local_ref_frame(jni);
734 665
735 if (!DeliverPendingOutputs(jni, 0, frames)) { 666 if (!DeliverPendingOutputs(jni, 0)) {
736 ALOGE << "PollDecodedFramesOnCodecThread: DeliverPendingOutputs error"; 667 ALOGE << "PollDecodedFrames: DeliverPendingOutputs error";
737 ProcessHWErrorOnCodecThread(); 668 ProcessHWError();
738 } 669 }
739 } 670 }
740 671
741 bool MediaCodecVideoDecoder::DeliverPendingOutputs( 672 bool MediaCodecVideoDecoder::DeliverPendingOutputs(JNIEnv* jni,
742 JNIEnv* jni, 673 int dequeue_timeout_ms) {
743 int dequeue_timeout_ms, 674 RTC_DCHECK(decode_thread_checker_.CalledOnValidThread());
744 std::vector<DecodedFrame>* frames) {
745 RTC_DCHECK(IsOnCodecThread());
746 RTC_DCHECK(frames);
747 675
748 if (frames_received_ <= frames_decoded_) { 676 if (frames_received_ <= frames_decoded_) {
749 // No need to query for output buffers - decoder is drained. 677 // No need to query for output buffers - decoder is drained.
750 return true; 678 return true;
751 } 679 }
752 // Get decoder output. 680 // Get decoder output.
753 jobject j_decoder_output_buffer = 681 jobject j_decoder_output_buffer =
754 jni->CallObjectMethod(*j_media_codec_video_decoder_, 682 jni->CallObjectMethod(*j_media_codec_video_decoder_,
755 use_surface_ ? j_dequeue_texture_buffer_method_ 683 use_surface_ ? j_dequeue_texture_buffer_method_
756 : j_dequeue_byte_buffer_method_, 684 : j_dequeue_byte_buffer_method_,
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 } 875 }
948 876
949 // If the frame was dropped, frame_buffer is left as nullptr. 877 // If the frame was dropped, frame_buffer is left as nullptr.
950 if (frame_buffer) { 878 if (frame_buffer) {
951 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0); 879 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0);
952 decoded_frame.set_timestamp(output_timestamps_ms); 880 decoded_frame.set_timestamp(output_timestamps_ms);
953 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); 881 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms);
954 882
955 rtc::Optional<uint8_t> qp = pending_frame_qps_.front(); 883 rtc::Optional<uint8_t> qp = pending_frame_qps_.front();
956 pending_frame_qps_.pop_front(); 884 pending_frame_qps_.pop_front();
957 decoded_frames_.push_back(DecodedFrame(std::move(decoded_frame), 885 callback_->Decoded(decoded_frame, rtc::Optional<int32_t>(decode_time_ms),
958 decode_time_ms, output_timestamps_ms, 886 qp);
959 output_ntp_timestamps_ms, qp));
960 } 887 }
961 888
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; 889 return true;
968 } 890 }
969 891
970 int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback( 892 int32_t MediaCodecVideoDecoder::RegisterDecodeCompleteCallback(
971 DecodedImageCallback* callback) { 893 DecodedImageCallback* callback) {
972 callback_ = callback; 894 callback_ = callback;
973 return WEBRTC_VIDEO_CODEC_OK; 895 return WEBRTC_VIDEO_CODEC_OK;
974 } 896 }
975 897
976 MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() 898 MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory()
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 webrtc::VideoDecoder* decoder) { 980 webrtc::VideoDecoder* decoder) {
1059 ALOGD << "Destroy video decoder."; 981 ALOGD << "Destroy video decoder.";
1060 delete decoder; 982 delete decoder;
1061 } 983 }
1062 984
1063 const char* MediaCodecVideoDecoder::ImplementationName() const { 985 const char* MediaCodecVideoDecoder::ImplementationName() const {
1064 return "MediaCodec"; 986 return "MediaCodec";
1065 } 987 }
1066 988
1067 } // namespace webrtc_jni 989 } // namespace webrtc_jni
OLDNEW
« no previous file with comments | « webrtc/sdk/android/api/org/webrtc/MediaCodecVideoDecoder.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698