• 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/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