OLD | NEW |
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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 } | 300 } |
301 // Save VideoCodec instance for later. | 301 // Save VideoCodec instance for later. |
302 if (&codec_ != inst) { | 302 if (&codec_ != inst) { |
303 codec_ = *inst; | 303 codec_ = *inst; |
304 } | 304 } |
305 // If maxFramerate is not set then assume 30 fps. | 305 // If maxFramerate is not set then assume 30 fps. |
306 codec_.maxFramerate = (codec_.maxFramerate >= 1) ? codec_.maxFramerate : 30; | 306 codec_.maxFramerate = (codec_.maxFramerate >= 1) ? codec_.maxFramerate : 30; |
307 | 307 |
308 // Call Java init. | 308 // Call Java init. |
309 return codec_thread_->Invoke<int32_t>( | 309 return codec_thread_->Invoke<int32_t>( |
310 Bind(&MediaCodecVideoDecoder::InitDecodeOnCodecThread, this)); | 310 FROM_HERE, Bind(&MediaCodecVideoDecoder::InitDecodeOnCodecThread, this)); |
311 } | 311 } |
312 | 312 |
313 void MediaCodecVideoDecoder::ResetVariables() { | 313 void MediaCodecVideoDecoder::ResetVariables() { |
314 CheckOnCodecThread(); | 314 CheckOnCodecThread(); |
315 | 315 |
316 key_frame_required_ = true; | 316 key_frame_required_ = true; |
317 frames_received_ = 0; | 317 frames_received_ = 0; |
318 frames_decoded_ = 0; | 318 frames_decoded_ = 0; |
319 frames_decoded_logged_ = kMaxDecodedLogFrames; | 319 frames_decoded_logged_ = kMaxDecodedLogFrames; |
320 start_time_ms_ = rtc::TimeMillis(); | 320 start_time_ms_ = rtc::TimeMillis(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 for (size_t i = 0; i < num_input_buffers; ++i) { | 392 for (size_t i = 0; i < num_input_buffers; ++i) { |
393 input_buffers_[i] = | 393 input_buffers_[i] = |
394 jni->NewGlobalRef(jni->GetObjectArrayElement(input_buffers, i)); | 394 jni->NewGlobalRef(jni->GetObjectArrayElement(input_buffers, i)); |
395 if (CheckException(jni)) { | 395 if (CheckException(jni)) { |
396 ALOGE << "NewGlobalRef error - fallback to SW codec."; | 396 ALOGE << "NewGlobalRef error - fallback to SW codec."; |
397 sw_fallback_required_ = true; | 397 sw_fallback_required_ = true; |
398 return WEBRTC_VIDEO_CODEC_ERROR; | 398 return WEBRTC_VIDEO_CODEC_ERROR; |
399 } | 399 } |
400 } | 400 } |
401 | 401 |
402 codec_thread_->PostDelayed(kMediaCodecPollMs, this); | 402 codec_thread_->PostDelayed(FROM_HERE, kMediaCodecPollMs, this); |
403 | 403 |
404 return WEBRTC_VIDEO_CODEC_OK; | 404 return WEBRTC_VIDEO_CODEC_OK; |
405 } | 405 } |
406 | 406 |
407 int32_t MediaCodecVideoDecoder::ResetDecodeOnCodecThread() { | 407 int32_t MediaCodecVideoDecoder::ResetDecodeOnCodecThread() { |
408 CheckOnCodecThread(); | 408 CheckOnCodecThread(); |
409 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 409 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
410 ScopedLocalRefFrame local_ref_frame(jni); | 410 ScopedLocalRefFrame local_ref_frame(jni); |
411 ALOGD << "ResetDecodeOnCodecThread Type: " << (int)codecType_ << ". " | 411 ALOGD << "ResetDecodeOnCodecThread Type: " << (int)codecType_ << ". " |
412 << codec_.width << " x " << codec_.height; | 412 << codec_.width << " x " << codec_.height; |
(...skipping 10 matching lines...) Expand all Loading... |
423 codec_.width, | 423 codec_.width, |
424 codec_.height); | 424 codec_.height); |
425 | 425 |
426 if (CheckException(jni)) { | 426 if (CheckException(jni)) { |
427 ALOGE << "Soft reset error - fallback to SW codec."; | 427 ALOGE << "Soft reset error - fallback to SW codec."; |
428 sw_fallback_required_ = true; | 428 sw_fallback_required_ = true; |
429 return WEBRTC_VIDEO_CODEC_ERROR; | 429 return WEBRTC_VIDEO_CODEC_ERROR; |
430 } | 430 } |
431 inited_ = true; | 431 inited_ = true; |
432 | 432 |
433 codec_thread_->PostDelayed(kMediaCodecPollMs, this); | 433 codec_thread_->PostDelayed(FROM_HERE, kMediaCodecPollMs, this); |
434 | 434 |
435 return WEBRTC_VIDEO_CODEC_OK; | 435 return WEBRTC_VIDEO_CODEC_OK; |
436 } | 436 } |
437 | 437 |
438 int32_t MediaCodecVideoDecoder::Release() { | 438 int32_t MediaCodecVideoDecoder::Release() { |
439 ALOGD << "DecoderRelease request"; | 439 ALOGD << "DecoderRelease request"; |
440 return codec_thread_->Invoke<int32_t>( | 440 return codec_thread_->Invoke<int32_t>( |
441 Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this)); | 441 FROM_HERE, Bind(&MediaCodecVideoDecoder::ReleaseOnCodecThread, this)); |
442 } | 442 } |
443 | 443 |
444 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() { | 444 int32_t MediaCodecVideoDecoder::ReleaseOnCodecThread() { |
445 if (!inited_) { | 445 if (!inited_) { |
446 return WEBRTC_VIDEO_CODEC_OK; | 446 return WEBRTC_VIDEO_CODEC_OK; |
447 } | 447 } |
448 CheckOnCodecThread(); | 448 CheckOnCodecThread(); |
449 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 449 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
450 ALOGD << "DecoderReleaseOnCodecThread: Frames received: " << | 450 ALOGD << "DecoderReleaseOnCodecThread: Frames received: " << |
451 frames_received_ << ". Frames decoded: " << frames_decoded_; | 451 frames_received_ << ". Frames decoded: " << frames_decoded_; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 inputImage._encodedHeight != codec_.height)) { | 532 inputImage._encodedHeight != codec_.height)) { |
533 ALOGW << "Input resolution changed from " << | 533 ALOGW << "Input resolution changed from " << |
534 codec_.width << " x " << codec_.height << " to " << | 534 codec_.width << " x " << codec_.height << " to " << |
535 inputImage._encodedWidth << " x " << inputImage._encodedHeight; | 535 inputImage._encodedWidth << " x " << inputImage._encodedHeight; |
536 codec_.width = inputImage._encodedWidth; | 536 codec_.width = inputImage._encodedWidth; |
537 codec_.height = inputImage._encodedHeight; | 537 codec_.height = inputImage._encodedHeight; |
538 int32_t ret; | 538 int32_t ret; |
539 if (use_surface_ && | 539 if (use_surface_ && |
540 (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecH264)) { | 540 (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecH264)) { |
541 // Soft codec reset - only for surface decoding. | 541 // Soft codec reset - only for surface decoding. |
542 ret = codec_thread_->Invoke<int32_t>(Bind( | 542 ret = codec_thread_->Invoke<int32_t>( |
543 &MediaCodecVideoDecoder::ResetDecodeOnCodecThread, this)); | 543 FROM_HERE, |
| 544 Bind(&MediaCodecVideoDecoder::ResetDecodeOnCodecThread, this)); |
544 } else { | 545 } else { |
545 // Hard codec reset. | 546 // Hard codec reset. |
546 ret = InitDecode(&codec_, 1); | 547 ret = InitDecode(&codec_, 1); |
547 } | 548 } |
548 if (ret < 0) { | 549 if (ret < 0) { |
549 ALOGE << "InitDecode failure: " << ret << " - fallback to SW codec"; | 550 ALOGE << "InitDecode failure: " << ret << " - fallback to SW codec"; |
550 sw_fallback_required_ = true; | 551 sw_fallback_required_ = true; |
551 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; | 552 return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; |
552 } | 553 } |
553 } | 554 } |
554 | 555 |
555 // Always start with a complete key frame. | 556 // Always start with a complete key frame. |
556 if (key_frame_required_) { | 557 if (key_frame_required_) { |
557 if (inputImage._frameType != webrtc::kVideoFrameKey) { | 558 if (inputImage._frameType != webrtc::kVideoFrameKey) { |
558 ALOGE << "Decode() - key frame is required"; | 559 ALOGE << "Decode() - key frame is required"; |
559 return WEBRTC_VIDEO_CODEC_ERROR; | 560 return WEBRTC_VIDEO_CODEC_ERROR; |
560 } | 561 } |
561 if (!inputImage._completeFrame) { | 562 if (!inputImage._completeFrame) { |
562 ALOGE << "Decode() - complete frame is required"; | 563 ALOGE << "Decode() - complete frame is required"; |
563 return WEBRTC_VIDEO_CODEC_ERROR; | 564 return WEBRTC_VIDEO_CODEC_ERROR; |
564 } | 565 } |
565 key_frame_required_ = false; | 566 key_frame_required_ = false; |
566 } | 567 } |
567 if (inputImage._length == 0) { | 568 if (inputImage._length == 0) { |
568 return WEBRTC_VIDEO_CODEC_ERROR; | 569 return WEBRTC_VIDEO_CODEC_ERROR; |
569 } | 570 } |
570 | 571 |
571 return codec_thread_->Invoke<int32_t>(Bind( | 572 return codec_thread_->Invoke<int32_t>( |
572 &MediaCodecVideoDecoder::DecodeOnCodecThread, this, inputImage)); | 573 FROM_HERE, |
| 574 Bind(&MediaCodecVideoDecoder::DecodeOnCodecThread, this, inputImage)); |
573 } | 575 } |
574 | 576 |
575 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( | 577 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( |
576 const EncodedImage& inputImage) { | 578 const EncodedImage& inputImage) { |
577 CheckOnCodecThread(); | 579 CheckOnCodecThread(); |
578 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 580 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
579 ScopedLocalRefFrame local_ref_frame(jni); | 581 ScopedLocalRefFrame local_ref_frame(jni); |
580 | 582 |
581 // Try to drain the decoder and wait until output is not too | 583 // Try to drain the decoder and wait until output is not too |
582 // much behind the input. | 584 // much behind the input. |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 // functor), so expect no ID/data. | 892 // functor), so expect no ID/data. |
891 RTC_CHECK(!msg->message_id) << "Unexpected message!"; | 893 RTC_CHECK(!msg->message_id) << "Unexpected message!"; |
892 RTC_CHECK(!msg->pdata) << "Unexpected message!"; | 894 RTC_CHECK(!msg->pdata) << "Unexpected message!"; |
893 CheckOnCodecThread(); | 895 CheckOnCodecThread(); |
894 | 896 |
895 if (!DeliverPendingOutputs(jni, 0)) { | 897 if (!DeliverPendingOutputs(jni, 0)) { |
896 ALOGE << "OnMessage: DeliverPendingOutputs error"; | 898 ALOGE << "OnMessage: DeliverPendingOutputs error"; |
897 ProcessHWErrorOnCodecThread(); | 899 ProcessHWErrorOnCodecThread(); |
898 return; | 900 return; |
899 } | 901 } |
900 codec_thread_->PostDelayed(kMediaCodecPollMs, this); | 902 codec_thread_->PostDelayed(FROM_HERE, kMediaCodecPollMs, this); |
901 } | 903 } |
902 | 904 |
903 MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() | 905 MediaCodecVideoDecoderFactory::MediaCodecVideoDecoderFactory() |
904 : egl_context_(nullptr) { | 906 : egl_context_(nullptr) { |
905 ALOGD << "MediaCodecVideoDecoderFactory ctor"; | 907 ALOGD << "MediaCodecVideoDecoderFactory ctor"; |
906 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 908 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
907 ScopedLocalRefFrame local_ref_frame(jni); | 909 ScopedLocalRefFrame local_ref_frame(jni); |
908 jclass j_decoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoDecoder"); | 910 jclass j_decoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoDecoder"); |
909 supported_codec_types_.clear(); | 911 supported_codec_types_.clear(); |
910 | 912 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 webrtc::VideoDecoder* decoder) { | 986 webrtc::VideoDecoder* decoder) { |
985 ALOGD << "Destroy video decoder."; | 987 ALOGD << "Destroy video decoder."; |
986 delete decoder; | 988 delete decoder; |
987 } | 989 } |
988 | 990 |
989 const char* MediaCodecVideoDecoder::ImplementationName() const { | 991 const char* MediaCodecVideoDecoder::ImplementationName() const { |
990 return "MediaCodec"; | 992 return "MediaCodec"; |
991 } | 993 } |
992 | 994 |
993 } // namespace webrtc_jni | 995 } // namespace webrtc_jni |
OLD | NEW |