1 /* 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef SDK_ANDROID_SRC_JNI_VIDEO_DECODER_WRAPPER_H_ 12 #define SDK_ANDROID_SRC_JNI_VIDEO_DECODER_WRAPPER_H_ 13 14 #include <jni.h> 15 16 #include <atomic> 17 #include <deque> 18 19 #include "api/video_codecs/video_decoder.h" 20 #include "common_video/h264/h264_bitstream_parser.h" 21 #include "rtc_base/race_checker.h" 22 #include "rtc_base/synchronization/mutex.h" 23 #include "rtc_base/thread_checker.h" 24 #include "sdk/android/src/jni/jni_helpers.h" 25 26 namespace webrtc { 27 namespace jni { 28 29 // Wraps a Java decoder and delegates all calls to it. 30 class VideoDecoderWrapper : public VideoDecoder { 31 public: 32 VideoDecoderWrapper(JNIEnv* jni, const JavaRef<jobject>& decoder); 33 ~VideoDecoderWrapper() override; 34 35 int32_t InitDecode(const VideoCodec* codec_settings, 36 int32_t number_of_cores) override; 37 38 int32_t Decode(const EncodedImage& input_image, 39 bool missing_frames, 40 int64_t render_time_ms) override; 41 42 int32_t RegisterDecodeCompleteCallback( 43 DecodedImageCallback* callback) override; 44 45 // TODO(sakal): This is not always called on the correct thread. It is called 46 // from VCMGenericDecoder destructor which is on a different thread but is 47 // still safe and synchronous. 48 int32_t Release() override RTC_NO_THREAD_SAFETY_ANALYSIS; 49 50 // Returns true if the decoder prefer to decode frames late. 51 // That is, it can not decode infinite number of frames before the decoded 52 // frame is consumed. 53 bool PrefersLateDecoding() const override; 54 55 const char* ImplementationName() const override; 56 57 // Wraps the frame to a AndroidVideoBuffer and passes it to the callback. 58 void OnDecodedFrame(JNIEnv* env, 59 const JavaRef<jobject>& j_frame, 60 const JavaRef<jobject>& j_decode_time_ms, 61 const JavaRef<jobject>& j_qp); 62 63 private: 64 struct FrameExtraInfo { 65 int64_t timestamp_ns; // Used as an identifier of the frame. 66 67 uint32_t timestamp_rtp; 68 int64_t timestamp_ntp; 69 absl::optional<uint8_t> qp; 70 71 FrameExtraInfo(); 72 FrameExtraInfo(const FrameExtraInfo&); 73 ~FrameExtraInfo(); 74 }; 75 76 int32_t InitDecodeInternal(JNIEnv* jni) RTC_RUN_ON(decoder_thread_checker_); 77 78 // Takes Java VideoCodecStatus, handles it and returns WEBRTC_VIDEO_CODEC_* 79 // status code. 80 int32_t HandleReturnCode(JNIEnv* jni, 81 const JavaRef<jobject>& j_value, 82 const char* method_name) 83 RTC_RUN_ON(decoder_thread_checker_); 84 85 absl::optional<uint8_t> ParseQP(const EncodedImage& input_image) 86 RTC_RUN_ON(decoder_thread_checker_); 87 88 const ScopedJavaGlobalRef<jobject> decoder_; 89 const std::string implementation_name_; 90 91 rtc::ThreadChecker decoder_thread_checker_; 92 // Callbacks must be executed sequentially on an arbitrary thread. We do not 93 // own this thread so a thread checker cannot be used. 94 rtc::RaceChecker callback_race_checker_; 95 96 // Initialized on InitDecode and immutable after that. 97 VideoCodec codec_settings_ RTC_GUARDED_BY(decoder_thread_checker_); 98 int32_t number_of_cores_ RTC_GUARDED_BY(decoder_thread_checker_); 99 100 bool initialized_ RTC_GUARDED_BY(decoder_thread_checker_); 101 H264BitstreamParser h264_bitstream_parser_ 102 RTC_GUARDED_BY(decoder_thread_checker_); 103 104 DecodedImageCallback* callback_ RTC_GUARDED_BY(callback_race_checker_); 105 106 // Accessed both on the decoder thread and the callback thread. 107 std::atomic<bool> qp_parsing_enabled_; 108 Mutex frame_extra_infos_lock_; 109 std::deque<FrameExtraInfo> frame_extra_infos_ 110 RTC_GUARDED_BY(frame_extra_infos_lock_); 111 }; 112 113 /* If the j_decoder is a wrapped native decoder, unwrap it. If it is not, 114 * wrap it in a VideoDecoderWrapper. 115 */ 116 std::unique_ptr<VideoDecoder> JavaToNativeVideoDecoder( 117 JNIEnv* jni, 118 const JavaRef<jobject>& j_decoder); 119 120 } // namespace jni 121 } // namespace webrtc 122 123 #endif // SDK_ANDROID_SRC_JNI_VIDEO_DECODER_WRAPPER_H_ 124