glaznev@webrtc.org | 18c9247 | 2015-02-18 18:42:55 +0000 | [diff] [blame] | 1 | /* |
kjellander | b24317b | 2016-02-10 07:54:43 -0800 | [diff] [blame] | 2 | * Copyright 2015 The WebRTC project authors. All Rights Reserved. |
glaznev@webrtc.org | 18c9247 | 2015-02-18 18:42:55 +0000 | [diff] [blame] | 3 | * |
kjellander | b24317b | 2016-02-10 07:54:43 -0800 | [diff] [blame] | 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. |
glaznev@webrtc.org | 18c9247 | 2015-02-18 18:42:55 +0000 | [diff] [blame] | 9 | */ |
| 10 | |
Magnus Jedvert | c2ac3c6 | 2017-11-14 17:08:59 +0100 | [diff] [blame] | 11 | #ifndef SDK_ANDROID_SRC_JNI_VIDEOFRAME_H_ |
| 12 | #define SDK_ANDROID_SRC_JNI_VIDEOFRAME_H_ |
glaznev@webrtc.org | 18c9247 | 2015-02-18 18:42:55 +0000 | [diff] [blame] | 13 | |
Magnus Jedvert | 6781ea4 | 2015-10-02 13:56:04 +0200 | [diff] [blame] | 14 | #include <jni.h> |
| 15 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 16 | #include "api/video/video_frame.h" |
| 17 | #include "api/video/video_frame_buffer.h" |
| 18 | #include "api/video/video_rotation.h" |
| 19 | #include "rtc_base/callback.h" |
| 20 | #include "sdk/android/src/jni/jni_helpers.h" |
magjed | 52a30e3 | 2015-10-12 06:53:20 -0700 | [diff] [blame] | 21 | |
magjed | a3d4f68 | 2017-08-28 16:24:06 -0700 | [diff] [blame] | 22 | namespace webrtc { |
| 23 | namespace jni { |
glaznev@webrtc.org | 18c9247 | 2015-02-18 18:42:55 +0000 | [diff] [blame] | 24 | |
nisse | 47ac462 | 2016-05-25 08:47:01 -0700 | [diff] [blame] | 25 | // Open gl texture matrix, in column-major order. Operations are |
| 26 | // in-place. |
| 27 | class Matrix { |
| 28 | public: |
| 29 | Matrix(JNIEnv* jni, jfloatArray a); |
| 30 | |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 31 | static Matrix fromAndroidGraphicsMatrix(JNIEnv* jni, jobject j_matrix); |
| 32 | |
| 33 | jfloatArray ToJava(JNIEnv* jni) const; |
nisse | 47ac462 | 2016-05-25 08:47:01 -0700 | [diff] [blame] | 34 | |
| 35 | // Crop arguments are relative to original size. |
| 36 | void Crop(float cropped_width, |
| 37 | float cropped_height, |
| 38 | float crop_x, |
| 39 | float crop_y); |
| 40 | |
magjed | a3d4f68 | 2017-08-28 16:24:06 -0700 | [diff] [blame] | 41 | void Rotate(VideoRotation rotation); |
nisse | 47ac462 | 2016-05-25 08:47:01 -0700 | [diff] [blame] | 42 | |
| 43 | private: |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 44 | Matrix() {} |
| 45 | |
nisse | 47ac462 | 2016-05-25 08:47:01 -0700 | [diff] [blame] | 46 | static void Multiply(const float a[16], const float b[16], float result[16]); |
| 47 | float elem_[16]; |
| 48 | }; |
| 49 | |
Per | 9b3f56e | 2015-04-09 13:44:16 +0200 | [diff] [blame] | 50 | // Wrapper for texture object. |
Per | 488e75f | 2015-11-19 10:43:36 +0100 | [diff] [blame] | 51 | struct NativeHandleImpl { |
| 52 | NativeHandleImpl(JNIEnv* jni, |
| 53 | jint j_oes_texture_id, |
| 54 | jfloatArray j_transform_matrix); |
Per | 9b3f56e | 2015-04-09 13:44:16 +0200 | [diff] [blame] | 55 | |
nisse | 47ac462 | 2016-05-25 08:47:01 -0700 | [diff] [blame] | 56 | NativeHandleImpl(int id, const Matrix& matrix); |
| 57 | |
Magnus Jedvert | 91b348c | 2015-10-07 22:57:06 +0200 | [diff] [blame] | 58 | const int oes_texture_id; |
nisse | 47ac462 | 2016-05-25 08:47:01 -0700 | [diff] [blame] | 59 | Matrix sampling_matrix; |
Peter Boström | eb66e80 | 2015-06-05 11:08:03 +0200 | [diff] [blame] | 60 | }; |
| 61 | |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 62 | // Base class to differentiate between the old texture frames and the new |
| 63 | // Java-based frames. |
| 64 | // TODO(sakal): Remove this and AndroidTextureBuffer once they are no longer |
| 65 | // needed. |
magjed | a3d4f68 | 2017-08-28 16:24:06 -0700 | [diff] [blame] | 66 | class AndroidVideoFrameBuffer : public VideoFrameBuffer { |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 67 | public: |
| 68 | enum class AndroidType { kTextureBuffer, kJavaBuffer }; |
| 69 | |
| 70 | virtual AndroidType android_type() = 0; |
| 71 | }; |
| 72 | |
| 73 | class AndroidTextureBuffer : public AndroidVideoFrameBuffer { |
magjed | 52a30e3 | 2015-10-12 06:53:20 -0700 | [diff] [blame] | 74 | public: |
| 75 | AndroidTextureBuffer(int width, |
| 76 | int height, |
Per | 488e75f | 2015-11-19 10:43:36 +0100 | [diff] [blame] | 77 | const NativeHandleImpl& native_handle, |
nisse | c490e01 | 2015-12-10 06:23:33 -0800 | [diff] [blame] | 78 | jobject surface_texture_helper, |
magjed | 52a30e3 | 2015-10-12 06:53:20 -0700 | [diff] [blame] | 79 | const rtc::Callback0<void>& no_longer_used); |
| 80 | ~AndroidTextureBuffer(); |
magjed | 52a30e3 | 2015-10-12 06:53:20 -0700 | [diff] [blame] | 81 | |
Magnus Jedvert | c276ecf | 2017-06-07 13:06:06 +0200 | [diff] [blame] | 82 | NativeHandleImpl native_handle_impl() const; |
Per | a3c20bb | 2015-11-26 13:41:44 +0100 | [diff] [blame] | 83 | |
magjed | 52a30e3 | 2015-10-12 06:53:20 -0700 | [diff] [blame] | 84 | private: |
Magnus Jedvert | c276ecf | 2017-06-07 13:06:06 +0200 | [diff] [blame] | 85 | Type type() const override; |
| 86 | int width() const override; |
| 87 | int height() const override; |
| 88 | |
magjed | a3d4f68 | 2017-08-28 16:24:06 -0700 | [diff] [blame] | 89 | rtc::scoped_refptr<I420BufferInterface> ToI420() override; |
Magnus Jedvert | c276ecf | 2017-06-07 13:06:06 +0200 | [diff] [blame] | 90 | |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 91 | AndroidType android_type() override { return AndroidType::kTextureBuffer; } |
| 92 | |
Magnus Jedvert | c276ecf | 2017-06-07 13:06:06 +0200 | [diff] [blame] | 93 | const int width_; |
| 94 | const int height_; |
Per | 488e75f | 2015-11-19 10:43:36 +0100 | [diff] [blame] | 95 | NativeHandleImpl native_handle_; |
nisse | c490e01 | 2015-12-10 06:23:33 -0800 | [diff] [blame] | 96 | // Raw object pointer, relying on the caller, i.e., |
| 97 | // AndroidVideoCapturerJni or the C++ SurfaceTextureHelper, to keep |
| 98 | // a global reference. TODO(nisse): Make this a reference to the C++ |
| 99 | // SurfaceTextureHelper instead, but that requires some refactoring |
| 100 | // of AndroidVideoCapturerJni. |
| 101 | jobject surface_texture_helper_; |
magjed | 52a30e3 | 2015-10-12 06:53:20 -0700 | [diff] [blame] | 102 | rtc::Callback0<void> no_longer_used_cb_; |
| 103 | }; |
| 104 | |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 105 | class AndroidVideoBuffer : public AndroidVideoFrameBuffer { |
| 106 | public: |
Magnus Jedvert | c2ac3c6 | 2017-11-14 17:08:59 +0100 | [diff] [blame] | 107 | // Creates a native VideoFrameBuffer from a Java VideoFrame.Buffer. |
| 108 | static rtc::scoped_refptr<AndroidVideoBuffer> Create( |
sakal | be91046 | 2017-08-11 00:26:05 -0700 | [diff] [blame] | 109 | JNIEnv* jni, |
sakal | be91046 | 2017-08-11 00:26:05 -0700 | [diff] [blame] | 110 | jobject j_video_frame_buffer); |
| 111 | |
Magnus Jedvert | c2ac3c6 | 2017-11-14 17:08:59 +0100 | [diff] [blame] | 112 | // Similar to the Create() above, but adopts and takes ownership of the Java |
| 113 | // VideoFrame.Buffer. I.e. retain() will not be called, but release() will be |
| 114 | // called when the returned AndroidVideoBuffer is destroyed. |
| 115 | static rtc::scoped_refptr<AndroidVideoBuffer> Adopt( |
| 116 | JNIEnv* jni, |
| 117 | jobject j_video_frame_buffer); |
| 118 | |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 119 | ~AndroidVideoBuffer() override; |
| 120 | |
| 121 | jobject video_frame_buffer() const; |
| 122 | |
Magnus Jedvert | 202be39 | 2017-11-18 16:09:17 +0100 | [diff] [blame^] | 123 | // Crops a region defined by |crop_x|, |crop_y|, |crop_width| and |
| 124 | // |crop_height|. Scales it to size |scale_width| x |scale_height|. |
| 125 | rtc::scoped_refptr<AndroidVideoBuffer> CropAndScale(JNIEnv* jni, |
| 126 | int crop_x, |
| 127 | int crop_y, |
| 128 | int crop_width, |
| 129 | int crop_height, |
| 130 | int scale_width, |
| 131 | int scale_height); |
| 132 | |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 133 | // Returns an instance of VideoRenderer.I420Frame (deprecated) |
sakal | 836f60c | 2017-07-28 07:12:23 -0700 | [diff] [blame] | 134 | jobject ToJavaI420Frame(JNIEnv* jni, int rotation); |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 135 | |
Magnus Jedvert | c2ac3c6 | 2017-11-14 17:08:59 +0100 | [diff] [blame] | 136 | protected: |
| 137 | // Should not be called directly. Adopts the Java VideoFrame.Buffer. Use |
| 138 | // Create() or Adopt() instead for clarity. |
| 139 | AndroidVideoBuffer(JNIEnv* jni, jobject j_video_frame_buffer); |
| 140 | |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 141 | private: |
| 142 | Type type() const override; |
| 143 | int width() const override; |
| 144 | int height() const override; |
| 145 | |
magjed | a3d4f68 | 2017-08-28 16:24:06 -0700 | [diff] [blame] | 146 | rtc::scoped_refptr<I420BufferInterface> ToI420() override; |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 147 | |
| 148 | AndroidType android_type() override { return AndroidType::kJavaBuffer; } |
| 149 | |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 150 | const int width_; |
| 151 | const int height_; |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 152 | // Holds a VideoFrame.Buffer. |
sakal | 5ca60cc | 2017-08-09 05:25:49 -0700 | [diff] [blame] | 153 | const ScopedGlobalRef<jobject> j_video_frame_buffer_; |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 154 | }; |
| 155 | |
Magnus Jedvert | c2ac3c6 | 2017-11-14 17:08:59 +0100 | [diff] [blame] | 156 | VideoFrame JavaToNativeFrame(JNIEnv* jni, |
| 157 | jobject j_video_frame, |
| 158 | uint32_t timestamp_rtp); |
Sami Kalliomäki | bc061b4 | 2017-06-16 10:08:23 +0200 | [diff] [blame] | 159 | |
Magnus Jedvert | c2ac3c6 | 2017-11-14 17:08:59 +0100 | [diff] [blame] | 160 | jobject NativeToJavaFrame(JNIEnv* jni, const VideoFrame& frame); |
sakal | b5f5bdc | 2017-08-10 04:15:42 -0700 | [diff] [blame] | 161 | |
magjed | a3d4f68 | 2017-08-28 16:24:06 -0700 | [diff] [blame] | 162 | } // namespace jni |
| 163 | } // namespace webrtc |
glaznev@webrtc.org | 18c9247 | 2015-02-18 18:42:55 +0000 | [diff] [blame] | 164 | |
Magnus Jedvert | c2ac3c6 | 2017-11-14 17:08:59 +0100 | [diff] [blame] | 165 | #endif // SDK_ANDROID_SRC_JNI_VIDEOFRAME_H_ |