| /* |
| * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| package org.webrtc; |
| |
| import androidx.annotation.Nullable; |
| import org.jni_zero.NativeMethods; |
| |
| /** |
| * This class is meant to be a simple layer that only handles the JNI wrapping of a C++ |
| * AndroidVideoTrackSource, that can easily be mocked out in Java unit tests. Refrain from adding |
| * any unnecessary logic to this class. This class is thread safe and methods can be called from any |
| * thread, but if frames A, B, ..., are sent to adaptFrame(), the adapted frames adaptedA, adaptedB, |
| * ..., needs to be passed in the same order to onFrameCaptured(). |
| */ |
| |
| class NativeAndroidVideoTrackSource { |
| // Pointer to webrtc::jni::AndroidVideoTrackSource. |
| private final long nativeAndroidVideoTrackSource; |
| |
| public NativeAndroidVideoTrackSource(long nativeAndroidVideoTrackSource) { |
| this.nativeAndroidVideoTrackSource = nativeAndroidVideoTrackSource; |
| } |
| |
| /** |
| * Set the state for the native MediaSourceInterface. Maps boolean to either |
| * SourceState::kLive or SourceState::kEnded. |
| */ |
| public void setState(boolean isLive) { |
| NativeAndroidVideoTrackSourceJni.get().setState(nativeAndroidVideoTrackSource, isLive); |
| } |
| |
| /** |
| * This function should be called before delivering any frame to determine if the frame should be |
| * dropped or what the cropping and scaling parameters should be. If the return value is null, the |
| * frame should be dropped, otherwise the frame should be adapted in accordance to the frame |
| * adaptation parameters before calling onFrameCaptured(). |
| */ |
| @Nullable |
| public VideoProcessor.FrameAdaptationParameters adaptFrame(VideoFrame frame) { |
| return NativeAndroidVideoTrackSourceJni.get() |
| .adaptFrame( |
| nativeAndroidVideoTrackSource, |
| frame.getBuffer().getWidth(), |
| frame.getBuffer().getHeight(), |
| frame.getRotation(), |
| frame.getTimestampNs()); |
| } |
| |
| /** |
| * Pass an adapted frame to the native AndroidVideoTrackSource. Note that adaptFrame() is |
| * expected to be called first and that the passed frame conforms to those parameters. |
| */ |
| public void onFrameCaptured(VideoFrame frame) { |
| NativeAndroidVideoTrackSourceJni.get() |
| .onFrameCaptured( |
| nativeAndroidVideoTrackSource, |
| frame.getRotation(), |
| frame.getTimestampNs(), |
| frame.getBuffer()); |
| } |
| |
| /** |
| * Calling this function will cause frames to be scaled down to the requested resolution. Also, |
| * frames will be cropped to match the requested aspect ratio, and frames will be dropped to match |
| * the requested fps. |
| */ |
| public void adaptOutputFormat(VideoSource.AspectRatio targetLandscapeAspectRatio, |
| @Nullable Integer maxLandscapePixelCount, VideoSource.AspectRatio targetPortraitAspectRatio, |
| @Nullable Integer maxPortraitPixelCount, @Nullable Integer maxFps) { |
| NativeAndroidVideoTrackSourceJni.get() |
| .adaptOutputFormat( |
| nativeAndroidVideoTrackSource, |
| targetLandscapeAspectRatio.width, |
| targetLandscapeAspectRatio.height, |
| maxLandscapePixelCount, |
| targetPortraitAspectRatio.width, |
| targetPortraitAspectRatio.height, |
| maxPortraitPixelCount, |
| maxFps); |
| } |
| |
| public void setIsScreencast(boolean isScreencast) { |
| NativeAndroidVideoTrackSourceJni.get() |
| .setIsScreencast(nativeAndroidVideoTrackSource, isScreencast); |
| } |
| |
| @CalledByNative |
| static VideoProcessor.FrameAdaptationParameters createFrameAdaptationParameters(int cropX, |
| int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight, long timestampNs, |
| boolean drop) { |
| return new VideoProcessor.FrameAdaptationParameters( |
| cropX, cropY, cropWidth, cropHeight, scaleWidth, scaleHeight, timestampNs, drop); |
| } |
| |
| @NativeMethods |
| interface Natives { |
| void setIsScreencast(long nativeAndroidVideoTrackSource, boolean isScreencast); |
| |
| void setState(long nativeAndroidVideoTrackSource, boolean isLive); |
| |
| void adaptOutputFormat( |
| long nativeAndroidVideoTrackSource, |
| int landscapeWidth, |
| int landscapeHeight, |
| @Nullable Integer maxLandscapePixelCount, |
| int portraitWidth, |
| int portraitHeight, |
| @Nullable Integer maxPortraitPixelCount, |
| @Nullable Integer maxFps); |
| |
| @Nullable |
| VideoProcessor.FrameAdaptationParameters adaptFrame( |
| long nativeAndroidVideoTrackSource, int width, int height, int rotation, long timestampNs); |
| |
| void onFrameCaptured( |
| long nativeAndroidVideoTrackSource, |
| int rotation, |
| long timestampNs, |
| VideoFrame.Buffer buffer); |
| } |
| } |
| |