2019-02-05 16:39:41 +01:00
|
|
|
/*
|
|
|
|
|
* 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 android.support.annotation.Nullable;
|
|
|
|
|
import org.webrtc.VideoFrame;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
2019-02-06 14:48:57 +01:00
|
|
|
* This class is thred 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().
|
2019-02-05 16:39:41 +01:00
|
|
|
*/
|
|
|
|
|
class NativeAndroidVideoTrackSource {
|
|
|
|
|
// Pointer to webrtc::jni::AndroidVideoTrackSource.
|
|
|
|
|
private final long nativeAndroidVideoTrackSource;
|
|
|
|
|
|
2019-02-06 14:48:57 +01:00
|
|
|
public static class FrameAdaptationParameters {
|
|
|
|
|
public final int cropX;
|
|
|
|
|
public final int cropY;
|
|
|
|
|
public final int cropWidth;
|
|
|
|
|
public final int cropHeight;
|
|
|
|
|
public final int scaleWidth;
|
|
|
|
|
public final int scaleHeight;
|
|
|
|
|
public final long timestampNs;
|
|
|
|
|
|
|
|
|
|
@CalledByNative("FrameAdaptationParameters")
|
|
|
|
|
FrameAdaptationParameters(int cropX, int cropY, int cropWidth, int cropHeight, int scaleWidth,
|
|
|
|
|
int scaleHeight, long timestampNs) {
|
|
|
|
|
this.cropX = cropX;
|
|
|
|
|
this.cropY = cropY;
|
|
|
|
|
this.cropWidth = cropWidth;
|
|
|
|
|
this.cropHeight = cropHeight;
|
|
|
|
|
this.scaleWidth = scaleWidth;
|
|
|
|
|
this.scaleHeight = scaleHeight;
|
|
|
|
|
this.timestampNs = timestampNs;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-05 16:39:41 +01:00
|
|
|
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) {
|
|
|
|
|
nativeSetState(nativeAndroidVideoTrackSource, isLive);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 14:48:57 +01:00
|
|
|
/**
|
|
|
|
|
* 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 FrameAdaptationParameters adaptFrame(VideoFrame frame) {
|
|
|
|
|
return nativeAdaptFrame(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.
|
|
|
|
|
*/
|
2019-02-05 16:39:41 +01:00
|
|
|
public void onFrameCaptured(VideoFrame frame) {
|
2019-02-06 14:48:57 +01:00
|
|
|
nativeOnFrameCaptured(nativeAndroidVideoTrackSource, frame.getRotation(),
|
|
|
|
|
frame.getTimestampNs(), frame.getBuffer());
|
2019-02-05 16:39:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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) {
|
|
|
|
|
nativeAdaptOutputFormat(nativeAndroidVideoTrackSource, targetLandscapeAspectRatio.width,
|
|
|
|
|
targetLandscapeAspectRatio.height, maxLandscapePixelCount, targetPortraitAspectRatio.width,
|
|
|
|
|
targetPortraitAspectRatio.height, maxPortraitPixelCount, maxFps);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static native void nativeSetState(long nativeAndroidVideoTrackSource, boolean isLive);
|
|
|
|
|
private static native void nativeAdaptOutputFormat(long nativeAndroidVideoTrackSource,
|
|
|
|
|
int landscapeWidth, int landscapeHeight, @Nullable Integer maxLandscapePixelCount,
|
|
|
|
|
int portraitWidth, int portraitHeight, @Nullable Integer maxPortraitPixelCount,
|
|
|
|
|
@Nullable Integer maxFps);
|
2019-02-06 14:48:57 +01:00
|
|
|
@Nullable
|
|
|
|
|
private static native FrameAdaptationParameters nativeAdaptFrame(
|
|
|
|
|
long nativeAndroidVideoTrackSource, int width, int height, int rotation, long timestampNs);
|
|
|
|
|
private static native void nativeOnFrameCaptured(
|
|
|
|
|
long nativeAndroidVideoTrackSource, int rotation, long timestampNs, VideoFrame.Buffer buffer);
|
2019-02-05 16:39:41 +01:00
|
|
|
}
|