Index: webrtc/sdk/android/src/jni/androidmediadecoder_jni.cc |
diff --git a/webrtc/sdk/android/src/jni/androidmediadecoder_jni.cc b/webrtc/sdk/android/src/jni/androidmediadecoder_jni.cc |
index c89f902a62a449703c396223a97a78872eeae29e..d999b01b0ac7684a957486e69949c934b0122559 100644 |
--- a/webrtc/sdk/android/src/jni/androidmediadecoder_jni.cc |
+++ b/webrtc/sdk/android/src/jni/androidmediadecoder_jni.cc |
@@ -9,6 +9,7 @@ |
*/ |
#include <algorithm> |
+#include <deque> |
#include <memory> |
#include <vector> |
@@ -19,18 +20,20 @@ |
#include "third_party/libyuv/include/libyuv/convert.h" |
#include "third_party/libyuv/include/libyuv/convert_from.h" |
#include "third_party/libyuv/include/libyuv/video_common.h" |
-#include "webrtc/sdk/android/src/jni/androidmediacodeccommon.h" |
-#include "webrtc/sdk/android/src/jni/classreferenceholder.h" |
-#include "webrtc/sdk/android/src/jni/native_handle_impl.h" |
-#include "webrtc/sdk/android/src/jni/surfacetexturehelper_jni.h" |
#include "webrtc/base/bind.h" |
#include "webrtc/base/checks.h" |
#include "webrtc/base/logging.h" |
#include "webrtc/base/scoped_ref_ptr.h" |
#include "webrtc/base/thread.h" |
#include "webrtc/base/timeutils.h" |
+#include "webrtc/common_video/h264/h264_bitstream_parser.h" |
#include "webrtc/common_video/include/i420_buffer_pool.h" |
#include "webrtc/modules/video_coding/include/video_codec_interface.h" |
+#include "webrtc/modules/video_coding/utility/vp8_header_parser.h" |
+#include "webrtc/sdk/android/src/jni/androidmediacodeccommon.h" |
+#include "webrtc/sdk/android/src/jni/classreferenceholder.h" |
+#include "webrtc/sdk/android/src/jni/native_handle_impl.h" |
+#include "webrtc/sdk/android/src/jni/surfacetexturehelper_jni.h" |
#include "webrtc/system_wrappers/include/logcat_trace_context.h" |
using rtc::Bind; |
@@ -132,6 +135,8 @@ class MediaCodecVideoDecoder : public webrtc::VideoDecoder, |
int current_decoding_time_ms_; // Overall decoding time in the current second |
int current_delay_time_ms_; // Overall delay time in the current second. |
uint32_t max_pending_frames_; // Maximum number of pending input frames. |
+ webrtc::H264BitstreamParser h264_bitstream_parser_; |
+ std::deque<rtc::Optional<uint8_t>> pending_frame_qps_; |
// State that is constant for the lifetime of this object once the ctor |
// returns. |
@@ -323,6 +328,7 @@ void MediaCodecVideoDecoder::ResetVariables() { |
current_bytes_ = 0; |
current_decoding_time_ms_ = 0; |
current_delay_time_ms_ = 0; |
+ pending_frame_qps_.clear(); |
} |
int32_t MediaCodecVideoDecoder::InitDecodeOnCodecThread() { |
@@ -653,6 +659,21 @@ int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( |
// Save input image timestamps for later output. |
frames_received_++; |
current_bytes_ += inputImage._length; |
+ rtc::Optional<uint8_t> qp; |
+ if (codecType_ == kVideoCodecVP8) { |
+ int qp_int; |
+ if (webrtc::vp8::GetQp(inputImage._buffer, inputImage._length, &qp_int)) { |
+ qp = rtc::Optional<uint8_t>(qp_int); |
+ } |
+ } else if (codecType_ == kVideoCodecH264) { |
+ h264_bitstream_parser_.ParseBitstream(inputImage._buffer, |
+ inputImage._length); |
+ int qp_int; |
+ if (h264_bitstream_parser_.GetLastSliceQp(&qp_int)) { |
+ qp = rtc::Optional<uint8_t>(qp_int); |
+ } |
+ } |
+ pending_frame_qps_.push_back(qp); |
// Feed input to decoder. |
bool success = jni->CallBooleanMethod( |
@@ -679,6 +700,7 @@ int32_t MediaCodecVideoDecoder::DecodeOnCodecThread( |
bool MediaCodecVideoDecoder::DeliverPendingOutputs( |
JNIEnv* jni, int dequeue_timeout_ms) { |
+ CheckOnCodecThread(); |
if (frames_received_ <= frames_decoded_) { |
// No need to query for output buffers - decoder is drained. |
return true; |
@@ -861,11 +883,10 @@ bool MediaCodecVideoDecoder::DeliverPendingOutputs( |
decoded_frame.set_timestamp(output_timestamps_ms); |
decoded_frame.set_ntp_time_ms(output_ntp_timestamps_ms); |
- const int32_t callback_status = |
- callback_->Decoded(decoded_frame, decode_time_ms); |
- if (callback_status > 0) { |
- ALOGE << "callback error"; |
- } |
+ rtc::Optional<uint8_t> qp = pending_frame_qps_.front(); |
+ pending_frame_qps_.pop_front(); |
+ callback_->Decoded(decoded_frame, rtc::Optional<int32_t>(decode_time_ms), |
+ qp); |
} |
return true; |
} |