1 /* 2 * Copyright (c) 2019 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 package org.webrtc; 12 13 import android.support.annotation.Nullable; 14 import org.webrtc.VideoFrame; 15 import org.webrtc.VideoProcessor; 16 17 /** 18 * This class is meant to be a simple layer that only handles the JNI wrapping of a C++ 19 * AndroidVideoTrackSource, that can easily be mocked out in Java unit tests. Refrain from adding 20 * any unnecessary logic to this class. 21 * This class is thred safe and methods can be called from any thread, but if frames A, B, ..., are 22 * sent to adaptFrame(), the adapted frames adaptedA, adaptedB, ..., needs to be passed in the same 23 * order to onFrameCaptured(). 24 */ 25 class NativeAndroidVideoTrackSource { 26 // Pointer to webrtc::jni::AndroidVideoTrackSource. 27 private final long nativeAndroidVideoTrackSource; 28 NativeAndroidVideoTrackSource(long nativeAndroidVideoTrackSource)29 public NativeAndroidVideoTrackSource(long nativeAndroidVideoTrackSource) { 30 this.nativeAndroidVideoTrackSource = nativeAndroidVideoTrackSource; 31 } 32 33 /** 34 * Set the state for the native MediaSourceInterface. Maps boolean to either 35 * SourceState::kLive or SourceState::kEnded. 36 */ setState(boolean isLive)37 public void setState(boolean isLive) { 38 nativeSetState(nativeAndroidVideoTrackSource, isLive); 39 } 40 41 /** 42 * This function should be called before delivering any frame to determine if the frame should be 43 * dropped or what the cropping and scaling parameters should be. If the return value is null, the 44 * frame should be dropped, otherwise the frame should be adapted in accordance to the frame 45 * adaptation parameters before calling onFrameCaptured(). 46 */ 47 @Nullable adaptFrame(VideoFrame frame)48 public VideoProcessor.FrameAdaptationParameters adaptFrame(VideoFrame frame) { 49 return nativeAdaptFrame(nativeAndroidVideoTrackSource, frame.getBuffer().getWidth(), 50 frame.getBuffer().getHeight(), frame.getRotation(), frame.getTimestampNs()); 51 } 52 53 /** 54 * Pass an adapted frame to the native AndroidVideoTrackSource. Note that adaptFrame() is 55 * expected to be called first and that the passed frame conforms to those parameters. 56 */ onFrameCaptured(VideoFrame frame)57 public void onFrameCaptured(VideoFrame frame) { 58 nativeOnFrameCaptured(nativeAndroidVideoTrackSource, frame.getRotation(), 59 frame.getTimestampNs(), frame.getBuffer()); 60 } 61 62 /** 63 * Calling this function will cause frames to be scaled down to the requested resolution. Also, 64 * frames will be cropped to match the requested aspect ratio, and frames will be dropped to match 65 * the requested fps. 66 */ adaptOutputFormat(VideoSource.AspectRatio targetLandscapeAspectRatio, @Nullable Integer maxLandscapePixelCount, VideoSource.AspectRatio targetPortraitAspectRatio, @Nullable Integer maxPortraitPixelCount, @Nullable Integer maxFps)67 public void adaptOutputFormat(VideoSource.AspectRatio targetLandscapeAspectRatio, 68 @Nullable Integer maxLandscapePixelCount, VideoSource.AspectRatio targetPortraitAspectRatio, 69 @Nullable Integer maxPortraitPixelCount, @Nullable Integer maxFps) { 70 nativeAdaptOutputFormat(nativeAndroidVideoTrackSource, targetLandscapeAspectRatio.width, 71 targetLandscapeAspectRatio.height, maxLandscapePixelCount, targetPortraitAspectRatio.width, 72 targetPortraitAspectRatio.height, maxPortraitPixelCount, maxFps); 73 } 74 setIsScreencast(boolean isScreencast)75 public void setIsScreencast(boolean isScreencast) { 76 nativeSetIsScreencast(nativeAndroidVideoTrackSource, isScreencast); 77 } 78 79 @CalledByNative createFrameAdaptationParameters(int cropX, int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight, long timestampNs, boolean drop)80 static VideoProcessor.FrameAdaptationParameters createFrameAdaptationParameters(int cropX, 81 int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight, long timestampNs, 82 boolean drop) { 83 return new VideoProcessor.FrameAdaptationParameters( 84 cropX, cropY, cropWidth, cropHeight, scaleWidth, scaleHeight, timestampNs, drop); 85 } 86 nativeSetIsScreencast( long nativeAndroidVideoTrackSource, boolean isScreencast)87 private static native void nativeSetIsScreencast( 88 long nativeAndroidVideoTrackSource, boolean isScreencast); nativeSetState(long nativeAndroidVideoTrackSource, boolean isLive)89 private static native void nativeSetState(long nativeAndroidVideoTrackSource, boolean isLive); nativeAdaptOutputFormat(long nativeAndroidVideoTrackSource, int landscapeWidth, int landscapeHeight, @Nullable Integer maxLandscapePixelCount, int portraitWidth, int portraitHeight, @Nullable Integer maxPortraitPixelCount, @Nullable Integer maxFps)90 private static native void nativeAdaptOutputFormat(long nativeAndroidVideoTrackSource, 91 int landscapeWidth, int landscapeHeight, @Nullable Integer maxLandscapePixelCount, 92 int portraitWidth, int portraitHeight, @Nullable Integer maxPortraitPixelCount, 93 @Nullable Integer maxFps); 94 @Nullable nativeAdaptFrame( long nativeAndroidVideoTrackSource, int width, int height, int rotation, long timestampNs)95 private static native VideoProcessor.FrameAdaptationParameters nativeAdaptFrame( 96 long nativeAndroidVideoTrackSource, int width, int height, int rotation, long timestampNs); nativeOnFrameCaptured( long nativeAndroidVideoTrackSource, int rotation, long timestampNs, VideoFrame.Buffer buffer)97 private static native void nativeOnFrameCaptured( 98 long nativeAndroidVideoTrackSource, int rotation, long timestampNs, VideoFrame.Buffer buffer); 99 } 100