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/sequence_checker.h" 20 #include "api/video_codecs/video_decoder.h" 21 #include "common_video/h264/h264_bitstream_parser.h" 22 #include "rtc_base/race_checker.h" 23 #include "rtc_base/synchronization/mutex.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 bool Configure(const Settings& settings) override; 36 37 int32_t Decode(const EncodedImage& input_image, 38 bool missing_frames, 39 int64_t render_time_ms) override; 40 41 int32_t RegisterDecodeCompleteCallback( 42 DecodedImageCallback* callback) override; 43 44 // TODO(sakal): This is not always called on the correct thread. It is called 45 // from VCMGenericDecoder destructor which is on a different thread but is 46 // still safe and synchronous. 47 int32_t Release() override RTC_NO_THREAD_SAFETY_ANALYSIS; 48 49 const char* ImplementationName() const override; 50 51 // Wraps the frame to a AndroidVideoBuffer and passes it to the callback. 52 void OnDecodedFrame(JNIEnv* env, 53 const JavaRef<jobject>& j_frame, 54 const JavaRef<jobject>& j_decode_time_ms, 55 const JavaRef<jobject>& j_qp); 56 57 private: 58 struct FrameExtraInfo { 59 int64_t timestamp_ns; // Used as an identifier of the frame. 60 61 uint32_t timestamp_rtp; 62 int64_t timestamp_ntp; 63 absl::optional<uint8_t> qp; 64 65 FrameExtraInfo(); 66 FrameExtraInfo(const FrameExtraInfo&); 67 ~FrameExtraInfo(); 68 }; 69 70 bool ConfigureInternal(JNIEnv* jni) RTC_RUN_ON(decoder_thread_checker_); 71 72 // Takes Java VideoCodecStatus, handles it and returns WEBRTC_VIDEO_CODEC_* 73 // status code. 74 int32_t HandleReturnCode(JNIEnv* jni, 75 const JavaRef<jobject>& j_value, 76 const char* method_name) 77 RTC_RUN_ON(decoder_thread_checker_); 78 79 absl::optional<uint8_t> ParseQP(const EncodedImage& input_image) 80 RTC_RUN_ON(decoder_thread_checker_); 81 82 const ScopedJavaGlobalRef<jobject> decoder_; 83 const std::string implementation_name_; 84 85 SequenceChecker decoder_thread_checker_; 86 // Callbacks must be executed sequentially on an arbitrary thread. We do not 87 // own this thread so a thread checker cannot be used. 88 rtc::RaceChecker callback_race_checker_; 89 90 // Initialized on Configure and immutable after that. 91 VideoDecoder::Settings decoder_settings_ 92 RTC_GUARDED_BY(decoder_thread_checker_); 93 94 bool initialized_ RTC_GUARDED_BY(decoder_thread_checker_); 95 H264BitstreamParser h264_bitstream_parser_ 96 RTC_GUARDED_BY(decoder_thread_checker_); 97 98 DecodedImageCallback* callback_ RTC_GUARDED_BY(callback_race_checker_); 99 100 // Accessed both on the decoder thread and the callback thread. 101 std::atomic<bool> qp_parsing_enabled_; 102 Mutex frame_extra_infos_lock_; 103 std::deque<FrameExtraInfo> frame_extra_infos_ 104 RTC_GUARDED_BY(frame_extra_infos_lock_); 105 }; 106 107 /* If the j_decoder is a wrapped native decoder, unwrap it. If it is not, 108 * wrap it in a VideoDecoderWrapper. 109 */ 110 std::unique_ptr<VideoDecoder> JavaToNativeVideoDecoder( 111 JNIEnv* jni, 112 const JavaRef<jobject>& j_decoder); 113 114 } // namespace jni 115 } // namespace webrtc 116 117 #endif // SDK_ANDROID_SRC_JNI_VIDEO_DECODER_WRAPPER_H_ 118