blob: 67a4c2d3e2cdfd90e3c9507365d02a65186a3d8c [file]
/*
* 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);
}
}