• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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