blob: 2da68925253ec6ae751f19122da9f45f123cc1f1 [file] [log] [blame]
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +02001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef SDK_ANDROID_SRC_JNI_VIDEODECODERWRAPPER_H_
12#define SDK_ANDROID_SRC_JNI_VIDEODECODERWRAPPER_H_
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020013
14#include <jni.h>
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020015#include <deque>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/video_codecs/video_decoder.h"
18#include "common_video/h264/h264_bitstream_parser.h"
19#include "sdk/android/src/jni/jni_helpers.h"
20#include "sdk/android/src/jni/native_handle_impl.h"
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020021
magjeda3d4f682017-08-28 16:24:06 -070022namespace webrtc {
23namespace jni {
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020024
25// Wraps a Java decoder and delegates all calls to it. Passes
26// VideoDecoderWrapperCallback to the decoder on InitDecode. Wraps the received
27// frames to AndroidVideoBuffer.
magjeda3d4f682017-08-28 16:24:06 -070028class VideoDecoderWrapper : public VideoDecoder {
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020029 public:
30 VideoDecoderWrapper(JNIEnv* jni, jobject decoder);
31
magjeda3d4f682017-08-28 16:24:06 -070032 int32_t InitDecode(const VideoCodec* codec_settings,
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020033 int32_t number_of_cores) override;
34
magjeda3d4f682017-08-28 16:24:06 -070035 int32_t Decode(const EncodedImage& input_image,
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020036 bool missing_frames,
magjeda3d4f682017-08-28 16:24:06 -070037 const RTPFragmentationHeader* fragmentation,
38 const CodecSpecificInfo* codec_specific_info,
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020039 int64_t render_time_ms) override;
40
41 int32_t RegisterDecodeCompleteCallback(
magjeda3d4f682017-08-28 16:24:06 -070042 DecodedImageCallback* callback) override;
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020043
44 int32_t Release() override;
45
46 // Returns true if the decoder prefer to decode frames late.
47 // That is, it can not decode infinite number of frames before the decoded
48 // frame is consumed.
49 bool PrefersLateDecoding() const override;
50
51 const char* ImplementationName() const override;
52
53 // Wraps the frame to a AndroidVideoBuffer and passes it to the callback.
54 void OnDecodedFrame(JNIEnv* jni,
55 jobject jframe,
56 jobject jdecode_time_ms,
57 jobject jqp);
58
59 private:
60 struct FrameExtraInfo {
sakale172d892017-08-31 02:37:28 -070061 uint64_t capture_time_ns; // Used as an identifier of the frame.
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020062
63 uint32_t timestamp_rtp;
sakal4dee3442017-08-17 02:18:04 -070064 rtc::Optional<uint8_t> qp;
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020065 };
66
67 int32_t InitDecodeInternal(JNIEnv* jni);
68
69 // Takes Java VideoCodecStatus, handles it and returns WEBRTC_VIDEO_CODEC_*
70 // status code.
71 int32_t HandleReturnCode(JNIEnv* jni, jobject code);
72
magjeda3d4f682017-08-28 16:24:06 -070073 rtc::Optional<uint8_t> ParseQP(const EncodedImage& input_image);
sakal4dee3442017-08-17 02:18:04 -070074
magjeda3d4f682017-08-28 16:24:06 -070075 VideoCodec codec_settings_;
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020076 int32_t number_of_cores_;
77
78 bool initialized_;
79 AndroidVideoBufferFactory android_video_buffer_factory_;
80 std::deque<FrameExtraInfo> frame_extra_infos_;
sakal4dee3442017-08-17 02:18:04 -070081 bool qp_parsing_enabled_;
magjeda3d4f682017-08-28 16:24:06 -070082 H264BitstreamParser h264_bitstream_parser_;
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020083
magjeda3d4f682017-08-28 16:24:06 -070084 DecodedImageCallback* callback_;
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +020085
86 const ScopedGlobalRef<jobject> decoder_;
87 const ScopedGlobalRef<jclass> encoded_image_class_;
88 const ScopedGlobalRef<jclass> frame_type_class_;
89 const ScopedGlobalRef<jclass> settings_class_;
90 const ScopedGlobalRef<jclass> video_frame_class_;
91 const ScopedGlobalRef<jclass> video_codec_status_class_;
92 const ScopedGlobalRef<jclass> integer_class_;
93
94 jmethodID encoded_image_constructor_;
95 jmethodID settings_constructor_;
96
97 jfieldID empty_frame_field_;
98 jfieldID video_frame_key_field_;
99 jfieldID video_frame_delta_field_;
100
101 jmethodID video_frame_get_timestamp_ns_method_;
102
103 jmethodID init_decode_method_;
104 jmethodID release_method_;
105 jmethodID decode_method_;
106 jmethodID get_prefers_late_decoding_method_;
107 jmethodID get_implementation_name_method_;
108
109 jmethodID get_number_method_;
110
111 jmethodID integer_constructor_;
112 jmethodID int_value_method_;
113
magjeda3d4f682017-08-28 16:24:06 -0700114 jobject ConvertEncodedImageToJavaEncodedImage(JNIEnv* jni,
115 const EncodedImage& image);
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +0200116};
117
magjeda3d4f682017-08-28 16:24:06 -0700118} // namespace jni
119} // namespace webrtc
Sami Kalliomäki93ad1f72017-06-27 10:03:49 +0200120
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200121#endif // SDK_ANDROID_SRC_JNI_VIDEODECODERWRAPPER_H_