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