OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 #ifdef TRACK_BUFFER_TIMING | 72 #ifdef TRACK_BUFFER_TIMING |
73 #define ALOGV(...) | 73 #define ALOGV(...) |
74 __android_log_print(ANDROID_LOG_VERBOSE, TAG_DECODER, __VA_ARGS__) | 74 __android_log_print(ANDROID_LOG_VERBOSE, TAG_DECODER, __VA_ARGS__) |
75 #else | 75 #else |
76 #define ALOGV(...) | 76 #define ALOGV(...) |
77 #endif | 77 #endif |
78 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_DECODER) | 78 #define ALOGD LOG_TAG(rtc::LS_INFO, TAG_DECODER) |
79 #define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_DECODER) | 79 #define ALOGW LOG_TAG(rtc::LS_WARNING, TAG_DECODER) |
80 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_DECODER) | 80 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG_DECODER) |
81 | 81 |
| 82 enum { kMaxWarningLogFrames = 2 }; |
| 83 |
82 class MediaCodecVideoDecoder : public webrtc::VideoDecoder, | 84 class MediaCodecVideoDecoder : public webrtc::VideoDecoder, |
83 public rtc::MessageHandler { | 85 public rtc::MessageHandler { |
84 public: | 86 public: |
85 explicit MediaCodecVideoDecoder( | 87 explicit MediaCodecVideoDecoder( |
86 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context); | 88 JNIEnv* jni, VideoCodecType codecType, jobject render_egl_context); |
87 virtual ~MediaCodecVideoDecoder(); | 89 virtual ~MediaCodecVideoDecoder(); |
88 | 90 |
89 int32_t InitDecode(const VideoCodec* codecSettings, int32_t numberOfCores) | 91 int32_t InitDecode(const VideoCodec* codecSettings, int32_t numberOfCores) |
90 override; | 92 override; |
91 | 93 |
(...skipping 19 matching lines...) Expand all Loading... |
111 // CHECK-fail if not running on |codec_thread_|. | 113 // CHECK-fail if not running on |codec_thread_|. |
112 void CheckOnCodecThread(); | 114 void CheckOnCodecThread(); |
113 | 115 |
114 int32_t InitDecodeOnCodecThread(); | 116 int32_t InitDecodeOnCodecThread(); |
115 int32_t ReleaseOnCodecThread(); | 117 int32_t ReleaseOnCodecThread(); |
116 int32_t DecodeOnCodecThread(const EncodedImage& inputImage); | 118 int32_t DecodeOnCodecThread(const EncodedImage& inputImage); |
117 // Deliver any outputs pending in the MediaCodec to our |callback_| and return | 119 // Deliver any outputs pending in the MediaCodec to our |callback_| and return |
118 // true on success. | 120 // true on success. |
119 bool DeliverPendingOutputs(JNIEnv* jni, int dequeue_timeout_us); | 121 bool DeliverPendingOutputs(JNIEnv* jni, int dequeue_timeout_us); |
120 int32_t ProcessHWErrorOnCodecThread(); | 122 int32_t ProcessHWErrorOnCodecThread(); |
| 123 void EnableFrameLogOnWarning(); |
121 | 124 |
122 // Type of video codec. | 125 // Type of video codec. |
123 VideoCodecType codecType_; | 126 VideoCodecType codecType_; |
124 | 127 |
125 // Render EGL context - owned by factory, should not be allocated/destroyed | 128 // Render EGL context - owned by factory, should not be allocated/destroyed |
126 // by VideoDecoder. | 129 // by VideoDecoder. |
127 jobject render_egl_context_; | 130 jobject render_egl_context_; |
128 | 131 |
129 bool key_frame_required_; | 132 bool key_frame_required_; |
130 bool inited_; | 133 bool inited_; |
131 bool sw_fallback_required_; | 134 bool sw_fallback_required_; |
132 bool use_surface_; | 135 bool use_surface_; |
133 VideoCodec codec_; | 136 VideoCodec codec_; |
134 webrtc::I420BufferPool decoded_frame_pool_; | 137 webrtc::I420BufferPool decoded_frame_pool_; |
135 rtc::scoped_refptr<SurfaceTextureHelper> surface_texture_helper_; | 138 rtc::scoped_refptr<SurfaceTextureHelper> surface_texture_helper_; |
136 DecodedImageCallback* callback_; | 139 DecodedImageCallback* callback_; |
137 int frames_received_; // Number of frames received by decoder. | 140 int frames_received_; // Number of frames received by decoder. |
138 int frames_decoded_; // Number of frames decoded by decoder. | 141 int frames_decoded_; // Number of frames decoded by decoder. |
| 142 // Number of decoded frames for which log information is displayed. |
| 143 int frames_decoded_logged_; |
139 int64_t start_time_ms_; // Start time for statistics. | 144 int64_t start_time_ms_; // Start time for statistics. |
140 int current_frames_; // Number of frames in the current statistics interval. | 145 int current_frames_; // Number of frames in the current statistics interval. |
141 int current_bytes_; // Encoded bytes in the current statistics interval. | 146 int current_bytes_; // Encoded bytes in the current statistics interval. |
142 int current_decoding_time_ms_; // Overall decoding time in the current second | 147 int current_decoding_time_ms_; // Overall decoding time in the current second |
143 uint32_t max_pending_frames_; // Maximum number of pending input frames | 148 uint32_t max_pending_frames_; // Maximum number of pending input frames |
144 | 149 |
145 // State that is constant for the lifetime of this object once the ctor | 150 // State that is constant for the lifetime of this object once the ctor |
146 // returns. | 151 // returns. |
147 scoped_ptr<Thread> codec_thread_; // Thread on which to operate MediaCodec. | 152 scoped_ptr<Thread> codec_thread_; // Thread on which to operate MediaCodec. |
148 ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_; | 153 ScopedGlobalRef<jclass> j_media_codec_video_decoder_class_; |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 if (ret_val < 0) { | 333 if (ret_val < 0) { |
329 ALOGE << "Release failure: " << ret_val << " - fallback to SW codec"; | 334 ALOGE << "Release failure: " << ret_val << " - fallback to SW codec"; |
330 sw_fallback_required_ = true; | 335 sw_fallback_required_ = true; |
331 return WEBRTC_VIDEO_CODEC_ERROR; | 336 return WEBRTC_VIDEO_CODEC_ERROR; |
332 } | 337 } |
333 | 338 |
334 // Always start with a complete key frame. | 339 // Always start with a complete key frame. |
335 key_frame_required_ = true; | 340 key_frame_required_ = true; |
336 frames_received_ = 0; | 341 frames_received_ = 0; |
337 frames_decoded_ = 0; | 342 frames_decoded_ = 0; |
| 343 frames_decoded_logged_ = kMaxDecodedLogFrames; |
338 | 344 |
339 jobject java_surface_texture_helper_ = nullptr; | 345 jobject java_surface_texture_helper_ = nullptr; |
340 if (use_surface_) { | 346 if (use_surface_) { |
341 java_surface_texture_helper_ = jni->CallStaticObjectMethod( | 347 java_surface_texture_helper_ = jni->CallStaticObjectMethod( |
342 FindClass(jni, "org/webrtc/SurfaceTextureHelper"), | 348 FindClass(jni, "org/webrtc/SurfaceTextureHelper"), |
343 GetStaticMethodID(jni, | 349 GetStaticMethodID(jni, |
344 FindClass(jni, "org/webrtc/SurfaceTextureHelper"), | 350 FindClass(jni, "org/webrtc/SurfaceTextureHelper"), |
345 "create", | 351 "create", |
346 "(Lorg/webrtc/EglBase$Context;)" | 352 "(Lorg/webrtc/EglBase$Context;)" |
347 "Lorg/webrtc/SurfaceTextureHelper;"), | 353 "Lorg/webrtc/SurfaceTextureHelper;"), |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 } | 440 } |
435 ALOGD << "DecoderReleaseOnCodecThread done"; | 441 ALOGD << "DecoderReleaseOnCodecThread done"; |
436 return WEBRTC_VIDEO_CODEC_OK; | 442 return WEBRTC_VIDEO_CODEC_OK; |
437 } | 443 } |
438 | 444 |
439 void MediaCodecVideoDecoder::CheckOnCodecThread() { | 445 void MediaCodecVideoDecoder::CheckOnCodecThread() { |
440 RTC_CHECK(codec_thread_ == ThreadManager::Instance()->CurrentThread()) | 446 RTC_CHECK(codec_thread_ == ThreadManager::Instance()->CurrentThread()) |
441 << "Running on wrong thread!"; | 447 << "Running on wrong thread!"; |
442 } | 448 } |
443 | 449 |
| 450 void MediaCodecVideoDecoder::EnableFrameLogOnWarning() { |
| 451 // Log next 2 output frames. |
| 452 frames_decoded_logged_ = std::max( |
| 453 frames_decoded_logged_, frames_decoded_ + kMaxWarningLogFrames); |
| 454 } |
| 455 |
444 int32_t MediaCodecVideoDecoder::ProcessHWErrorOnCodecThread() { | 456 int32_t MediaCodecVideoDecoder::ProcessHWErrorOnCodecThread() { |
445 CheckOnCodecThread(); | 457 CheckOnCodecThread(); |
446 int ret_val = ReleaseOnCodecThread(); | 458 int ret_val = ReleaseOnCodecThread(); |
447 if (ret_val < 0) { | 459 if (ret_val < 0) { |
448 ALOGE << "ProcessHWError: Release failure"; | 460 ALOGE << "ProcessHWError: Release failure"; |
449 } | 461 } |
450 if (codecType_ == kVideoCodecH264) { | 462 if (codecType_ == kVideoCodecH264) { |
451 // For now there is no SW H.264 which can be used as fallback codec. | 463 // For now there is no SW H.264 which can be used as fallback codec. |
452 // So try to restart hw codec for now. | 464 // So try to restart hw codec for now. |
453 ret_val = InitDecodeOnCodecThread(); | 465 ret_val = InitDecodeOnCodecThread(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } | 537 } |
526 | 538 |
527 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( | 539 int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( |
528 const EncodedImage& inputImage) { | 540 const EncodedImage& inputImage) { |
529 CheckOnCodecThread(); | 541 CheckOnCodecThread(); |
530 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 542 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
531 ScopedLocalRefFrame local_ref_frame(jni); | 543 ScopedLocalRefFrame local_ref_frame(jni); |
532 | 544 |
533 // Try to drain the decoder and wait until output is not too | 545 // Try to drain the decoder and wait until output is not too |
534 // much behind the input. | 546 // much behind the input. |
| 547 if (frames_received_ > frames_decoded_ + max_pending_frames_) { |
| 548 ALOGW << "Decoder is too far behind. Try to drain. Received: " << |
| 549 frames_received_ << ". Decoded: " << frames_decoded_; |
| 550 EnableFrameLogOnWarning(); |
| 551 } |
535 const int64 drain_start = GetCurrentTimeMs(); | 552 const int64 drain_start = GetCurrentTimeMs(); |
536 while ((frames_received_ > frames_decoded_ + max_pending_frames_) && | 553 while ((frames_received_ > frames_decoded_ + max_pending_frames_) && |
537 (GetCurrentTimeMs() - drain_start) < kMediaCodecTimeoutMs) { | 554 (GetCurrentTimeMs() - drain_start) < kMediaCodecTimeoutMs) { |
538 ALOGV("Received: %d. Decoded: %d. Wait for output...", | |
539 frames_received_, frames_decoded_); | |
540 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs)) { | 555 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs)) { |
541 ALOGE << "DeliverPendingOutputs error. Frames received: " << | 556 ALOGE << "DeliverPendingOutputs error. Frames received: " << |
542 frames_received_ << ". Frames decoded: " << frames_decoded_; | 557 frames_received_ << ". Frames decoded: " << frames_decoded_; |
543 return ProcessHWErrorOnCodecThread(); | 558 return ProcessHWErrorOnCodecThread(); |
544 } | 559 } |
545 } | 560 } |
546 if (frames_received_ > frames_decoded_ + max_pending_frames_) { | 561 if (frames_received_ > frames_decoded_ + max_pending_frames_) { |
547 ALOGE << "Output buffer dequeue timeout. Frames received: " << | 562 ALOGE << "Output buffer dequeue timeout. Frames received: " << |
548 frames_received_ << ". Frames decoded: " << frames_decoded_; | 563 frames_received_ << ". Frames decoded: " << frames_decoded_; |
549 return ProcessHWErrorOnCodecThread(); | 564 return ProcessHWErrorOnCodecThread(); |
550 } | 565 } |
551 | 566 |
552 // Get input buffer. | 567 // Get input buffer. |
553 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_decoder_, | 568 int j_input_buffer_index = jni->CallIntMethod( |
554 j_dequeue_input_buffer_method_); | 569 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_); |
555 if (CheckException(jni) || j_input_buffer_index < 0) { | 570 if (CheckException(jni) || j_input_buffer_index < 0) { |
556 ALOGE << "dequeueInputBuffer error"; | 571 ALOGE << "dequeueInputBuffer error: " << j_input_buffer_index << |
557 return ProcessHWErrorOnCodecThread(); | 572 ". Retry DeliverPendingOutputs."; |
| 573 EnableFrameLogOnWarning(); |
| 574 // Try to drain the decoder. |
| 575 if (!DeliverPendingOutputs(jni, kMediaCodecPollMs)) { |
| 576 ALOGE << "DeliverPendingOutputs error. Frames received: " << |
| 577 frames_received_ << ". Frames decoded: " << frames_decoded_; |
| 578 return ProcessHWErrorOnCodecThread(); |
| 579 } |
| 580 // Try dequeue input buffer one last time. |
| 581 j_input_buffer_index = jni->CallIntMethod( |
| 582 *j_media_codec_video_decoder_, j_dequeue_input_buffer_method_); |
| 583 if (CheckException(jni) || j_input_buffer_index < 0) { |
| 584 ALOGE << "dequeueInputBuffer critical error: " << j_input_buffer_index; |
| 585 return ProcessHWErrorOnCodecThread(); |
| 586 } |
558 } | 587 } |
559 | 588 |
560 // Copy encoded data to Java ByteBuffer. | 589 // Copy encoded data to Java ByteBuffer. |
561 jobject j_input_buffer = input_buffers_[j_input_buffer_index]; | 590 jobject j_input_buffer = input_buffers_[j_input_buffer_index]; |
562 uint8_t* buffer = | 591 uint8_t* buffer = |
563 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer)); | 592 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_input_buffer)); |
564 RTC_CHECK(buffer) << "Indirect buffer??"; | 593 RTC_CHECK(buffer) << "Indirect buffer??"; |
565 int64_t buffer_capacity = jni->GetDirectBufferCapacity(j_input_buffer); | 594 int64_t buffer_capacity = jni->GetDirectBufferCapacity(j_input_buffer); |
566 if (CheckException(jni) || buffer_capacity < inputImage._length) { | 595 if (CheckException(jni) || buffer_capacity < inputImage._length) { |
567 ALOGE << "Input frame size "<< inputImage._length << | 596 ALOGE << "Input frame size "<< inputImage._length << |
568 " is bigger than buffer size " << buffer_capacity; | 597 " is bigger than buffer size " << buffer_capacity; |
569 return ProcessHWErrorOnCodecThread(); | 598 return ProcessHWErrorOnCodecThread(); |
570 } | 599 } |
571 jlong presentation_timestamp_us = | 600 jlong presentation_timestamp_us = static_cast<jlong>( |
572 (frames_received_ * 1000000) / codec_.maxFramerate; | 601 static_cast<int64_t>(frames_received_) * 1000000 / codec_.maxFramerate); |
573 memcpy(buffer, inputImage._buffer, inputImage._length); | 602 memcpy(buffer, inputImage._buffer, inputImage._length); |
574 | 603 |
575 if (frames_decoded_ < kMaxDecodedLogFrames) { | 604 if (frames_decoded_ < frames_decoded_logged_) { |
576 ALOGD << "Decoder frame in # " << frames_received_ << | 605 ALOGD << "Decoder frame in # " << frames_received_ << |
577 ". Type: " << inputImage._frameType << | 606 ". Type: " << inputImage._frameType << |
578 ". Buffer # " << j_input_buffer_index << | 607 ". Buffer # " << j_input_buffer_index << |
579 ". TS: " << (int)(presentation_timestamp_us / 1000) << | 608 ". TS: " << presentation_timestamp_us / 1000 << |
580 ". Size: " << inputImage._length; | 609 ". Size: " << inputImage._length; |
581 } | 610 } |
582 | 611 |
583 // Save input image timestamps for later output. | 612 // Save input image timestamps for later output. |
584 frames_received_++; | 613 frames_received_++; |
585 current_bytes_ += inputImage._length; | 614 current_bytes_ += inputImage._length; |
586 | 615 |
587 // Feed input to decoder. | 616 // Feed input to decoder. |
588 bool success = jni->CallBooleanMethod( | 617 bool success = jni->CallBooleanMethod( |
589 *j_media_codec_video_decoder_, | 618 *j_media_codec_video_decoder_, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 j_slice_height_field_); | 668 j_slice_height_field_); |
640 | 669 |
641 rtc::scoped_refptr<webrtc::VideoFrameBuffer> frame_buffer; | 670 rtc::scoped_refptr<webrtc::VideoFrameBuffer> frame_buffer; |
642 int64_t presentation_timestamps_ms = 0; | 671 int64_t presentation_timestamps_ms = 0; |
643 int64_t output_timestamps_ms = 0; | 672 int64_t output_timestamps_ms = 0; |
644 int64_t output_ntp_timestamps_ms = 0; | 673 int64_t output_ntp_timestamps_ms = 0; |
645 int decode_time_ms = 0; | 674 int decode_time_ms = 0; |
646 int64_t frame_delayed_ms = 0; | 675 int64_t frame_delayed_ms = 0; |
647 if (use_surface_) { | 676 if (use_surface_) { |
648 // Extract data from Java DecodedTextureBuffer. | 677 // Extract data from Java DecodedTextureBuffer. |
| 678 presentation_timestamps_ms = GetLongField( |
| 679 jni, j_decoder_output_buffer, |
| 680 j_texture_presentation_timestamp_ms_field_); |
| 681 output_timestamps_ms = GetLongField( |
| 682 jni, j_decoder_output_buffer, j_texture_timestamp_ms_field_); |
| 683 output_ntp_timestamps_ms = GetLongField( |
| 684 jni, j_decoder_output_buffer, j_texture_ntp_timestamp_ms_field_); |
| 685 decode_time_ms = GetLongField( |
| 686 jni, j_decoder_output_buffer, j_texture_decode_time_ms_field_); |
| 687 |
649 const int texture_id = | 688 const int texture_id = |
650 GetIntField(jni, j_decoder_output_buffer, j_texture_id_field_); | 689 GetIntField(jni, j_decoder_output_buffer, j_texture_id_field_); |
651 if (texture_id != 0) { // |texture_id| == 0 represents a dropped frame. | 690 if (texture_id != 0) { // |texture_id| == 0 represents a dropped frame. |
652 const jfloatArray j_transform_matrix = | 691 const jfloatArray j_transform_matrix = |
653 reinterpret_cast<jfloatArray>(GetObjectField( | 692 reinterpret_cast<jfloatArray>(GetObjectField( |
654 jni, j_decoder_output_buffer, j_transform_matrix_field_)); | 693 jni, j_decoder_output_buffer, j_transform_matrix_field_)); |
655 const int64_t timestamp_us = GetLongField( | |
656 jni, j_decoder_output_buffer, j_texture_timestamp_ms_field_); | |
657 presentation_timestamps_ms = GetLongField( | |
658 jni, j_decoder_output_buffer, | |
659 j_texture_presentation_timestamp_ms_field_); | |
660 output_timestamps_ms = GetLongField( | |
661 jni, j_decoder_output_buffer, j_texture_timestamp_ms_field_); | |
662 output_ntp_timestamps_ms = GetLongField( | |
663 jni, j_decoder_output_buffer, j_texture_ntp_timestamp_ms_field_); | |
664 decode_time_ms = GetLongField( | |
665 jni, j_decoder_output_buffer, j_texture_decode_time_ms_field_); | |
666 frame_delayed_ms = GetLongField( | 694 frame_delayed_ms = GetLongField( |
667 jni, j_decoder_output_buffer, j_texture_frame_delay_ms_field_); | 695 jni, j_decoder_output_buffer, j_texture_frame_delay_ms_field_); |
668 | 696 |
669 // Create webrtc::VideoFrameBuffer with native texture handle. | 697 // Create webrtc::VideoFrameBuffer with native texture handle. |
670 frame_buffer = surface_texture_helper_->CreateTextureFrame( | 698 frame_buffer = surface_texture_helper_->CreateTextureFrame( |
671 width, height, NativeHandleImpl(jni, texture_id, j_transform_matrix)); | 699 width, height, NativeHandleImpl(jni, texture_id, j_transform_matrix)); |
| 700 } else { |
| 701 EnableFrameLogOnWarning(); |
672 } | 702 } |
673 } else { | 703 } else { |
674 // Extract data from Java ByteBuffer and create output yuv420 frame - | 704 // Extract data from Java ByteBuffer and create output yuv420 frame - |
675 // for non surface decoding only. | 705 // for non surface decoding only. |
676 const int output_buffer_index = GetIntField( | 706 const int output_buffer_index = GetIntField( |
677 jni, j_decoder_output_buffer, j_info_index_field_); | 707 jni, j_decoder_output_buffer, j_info_index_field_); |
678 const int output_buffer_offset = GetIntField( | 708 const int output_buffer_offset = GetIntField( |
679 jni, j_decoder_output_buffer, j_info_offset_field_); | 709 jni, j_decoder_output_buffer, j_info_offset_field_); |
680 const int output_buffer_size = GetIntField( | 710 const int output_buffer_size = GetIntField( |
681 jni, j_decoder_output_buffer, j_info_size_field_); | 711 jni, j_decoder_output_buffer, j_info_size_field_); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 output_buffer_index); | 776 output_buffer_index); |
747 if (CheckException(jni)) { | 777 if (CheckException(jni)) { |
748 ALOGE << "returnDecodedOutputBuffer error"; | 778 ALOGE << "returnDecodedOutputBuffer error"; |
749 return false; | 779 return false; |
750 } | 780 } |
751 } | 781 } |
752 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0); | 782 VideoFrame decoded_frame(frame_buffer, 0, 0, webrtc::kVideoRotation_0); |
753 decoded_frame.set_timestamp(output_timestamps_ms); | 783 decoded_frame.set_timestamp(output_timestamps_ms); |
754 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); | 784 decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); |
755 | 785 |
756 if (frames_decoded_ < kMaxDecodedLogFrames) { | 786 if (frames_decoded_ < frames_decoded_logged_) { |
757 ALOGD << "Decoder frame out # " << frames_decoded_ << | 787 ALOGD << "Decoder frame out # " << frames_decoded_ << |
758 ". " << width << " x " << height << | 788 ". " << width << " x " << height << |
759 ". " << stride << " x " << slice_height << | 789 ". " << stride << " x " << slice_height << |
760 ". Color: " << color_format << | 790 ". Color: " << color_format << |
761 ". TS: " << presentation_timestamps_ms << | 791 ". TS: " << presentation_timestamps_ms << |
762 ". DecTime: " << (int)decode_time_ms << | 792 ". DecTime: " << (int)decode_time_ms << |
763 ". DelayTime: " << (int)frame_delayed_ms; | 793 ". DelayTime: " << (int)frame_delayed_ms; |
764 } | 794 } |
765 | 795 |
766 // Calculate and print decoding statistics - every 3 seconds. | 796 // Calculate and print decoding statistics - every 3 seconds. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 ALOGD << "Destroy video decoder."; | 928 ALOGD << "Destroy video decoder."; |
899 delete decoder; | 929 delete decoder; |
900 } | 930 } |
901 | 931 |
902 const char* MediaCodecVideoDecoder::ImplementationName() const { | 932 const char* MediaCodecVideoDecoder::ImplementationName() const { |
903 return "MediaCodec"; | 933 return "MediaCodec"; |
904 } | 934 } |
905 | 935 |
906 } // namespace webrtc_jni | 936 } // namespace webrtc_jni |
907 | 937 |
OLD | NEW |