public interface

VideoOutput

 androidx.camera.video.VideoOutput

Subclasses:

Recorder

Gradle dependencies

compile group: 'androidx.camera', name: 'camera-video', version: '1.5.0-alpha01'

  • groupId: androidx.camera
  • artifactId: camera-video
  • version: 1.5.0-alpha01

Artifact androidx.camera:camera-video:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

A class that will produce video data from a .

Implementations will provide a to a video frame producer via the SurfaceRequest sent to VideoOutput.onSurfaceRequested(SurfaceRequest).

The type of video data produced by a video output and API for saving or communicating that data is left to the implementation. An implementation commonly used for local video saving is Recorder. This interface is usually only needs to be implemented by applications for advanced use cases.

Summary

Methods
public VideoCapabilitiesgetMediaCapabilities(CameraInfo cameraInfo)

Returns the VideoCapabilities information of the VideoOutput.

public Observable<MediaSpec>getMediaSpec()

Returns an observable MediaSpec which contains hints about what kind of input the VideoOutput is expecting.

public Observable<StreamInfo>getStreamInfo()

Returns an observable StreamInfo which contains the information of the VideoOutput.

public Observable<java.lang.Boolean>isSourceStreamRequired()

Returns an observable to know if the streaming from a video frame producer is required.

public voidonSourceStateChanged(VideoOutput.SourceState sourceState)

Called when the state of the video frame producer is changed.

public voidonSurfaceRequested(SurfaceRequest request)

Called when a new has been requested by a video frame producer.

public voidonSurfaceRequested(SurfaceRequest request, Timebase timebase)

Called when a new has been requested by a video frame producer.

Methods

public void onSurfaceRequested(SurfaceRequest request)

Called when a new has been requested by a video frame producer.

Users of this class should not call this method directly. It will be called by the video frame producer. Implementors of this class should be aware that this method is called when a video frame producer is ready to receive a surface that it can use to send video frames to the video output. The video frame producer may repeatedly request a surface more than once, but only the latest SurfaceRequest should be considered active. All previous surface requests will complete by sending a SurfaceRequest.Result to the consumer passed to SurfaceRequest.provideSurface(Surface, Executor, Consumer).

A request is considered active until it is fulfilled, marked as 'will not complete', or cancelled by the video frame producer. After one of these conditions occurs, a request is considered completed.

Once a request is successfully completed, it is guaranteed that if a new request is made, the used to fulfill the previous request will be detached from the video frame producer and the resultListener provided in SurfaceRequest.provideSurface(Surface, Executor, Consumer) will be invoked with a SurfaceRequest.Result containing SurfaceRequest.Result.RESULT_SURFACE_USED_SUCCESSFULLY.

Parameters:

request: the request for a surface which contains the requirements of the surface and methods for completing the request.

public void onSurfaceRequested(SurfaceRequest request, Timebase timebase)

Called when a new has been requested by a video frame producer.

Parameters:

timebase: the video source timebase

public Observable<StreamInfo> getStreamInfo()

Returns an observable StreamInfo which contains the information of the VideoOutput.

public Observable<MediaSpec> getMediaSpec()

Returns an observable MediaSpec which contains hints about what kind of input the VideoOutput is expecting.

All values contained in the media specification are considered hints and may be ignored by the video frame producer. The VideoOutput should always respect the surface requirements given in the SurfaceRequest in VideoOutput.onSurfaceRequested(SurfaceRequest), or the video frame producer may not be able to produce frames.

Implementations should be careful about updating the MediaSpec too often, as changes may not come for free and may require the video frame producer to re-initialize, which could cause a new SurfaceRequest to be sent to VideoOutput.onSurfaceRequested(SurfaceRequest).

public Observable<java.lang.Boolean> isSourceStreamRequired()

Returns an observable to know if the streaming from a video frame producer is required.

This should be true for cases like when user is starting a video recording or streaming and false when user has decided to stop the recording/streaming. The video frame producer will use this information to do know whether it's now safe to do operations which may disrupt video quality/consistency (e.g. AE precapture).

public void onSourceStateChanged(VideoOutput.SourceState sourceState)

Called when the state of the video frame producer is changed.

public VideoCapabilities getMediaCapabilities(CameraInfo cameraInfo)

Returns the VideoCapabilities information of the VideoOutput.

Source

/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.camera.video;

import android.view.Surface;

import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
import androidx.camera.core.CameraInfo;
import androidx.camera.core.SurfaceRequest;
import androidx.camera.core.impl.ConstantObservable;
import androidx.camera.core.impl.Observable;
import androidx.camera.core.impl.Timebase;
import androidx.core.util.Consumer;

import java.util.concurrent.Executor;

/**
 * A class that will produce video data from a {@link Surface}.
 *
 * <p>Implementations will provide a {@link Surface} to a video frame producer via the
 * {@link SurfaceRequest} sent to {@link #onSurfaceRequested(SurfaceRequest)}.
 *
 * <p>The type of video data produced by a video output and API for saving or communicating that
 * data is left to the implementation. An implementation commonly used for local video saving is
 * {@link Recorder}. This interface is usually only needs to be implemented by applications for
 * advanced use cases.
 */
public interface VideoOutput {
    /**
     * A state which represents whether the video frame producer is producing frames to the
     * provided {@link Surface}.
     */
    @RestrictTo(Scope.LIBRARY)
    enum SourceState {
        /** The video frame producer is active and is producing frames. */
        ACTIVE_STREAMING,
        /** The video frame producer is active but is not producing frames. */
        ACTIVE_NON_STREAMING,
        /** The video frame producer is inactive. */
        INACTIVE
    }

    /**
     * Called when a new {@link Surface} has been requested by a video frame producer.
     *
     * <p>Users of this class should not call this method directly. It will be called by the
     * video frame producer. Implementors of this class should be aware that this method is
     * called when a video frame producer is ready to receive a surface that it can use to send
     * video frames to the video output. The video frame producer may repeatedly request a
     * surface more than once, but only the latest {@link SurfaceRequest} should be considered
     * active. All previous surface requests will complete by sending a
     * {@link androidx.camera.core.SurfaceRequest.Result} to the consumer passed to
     * {@link SurfaceRequest#provideSurface(Surface, Executor, Consumer)}.
     *
     * <p>A request is considered active until it is
     * {@linkplain SurfaceRequest#provideSurface(Surface, Executor, androidx.core.util.Consumer)
     * fulfilled}, {@linkplain SurfaceRequest#willNotProvideSurface() marked as 'will not
     * complete'}, or
     * {@linkplain SurfaceRequest#addRequestCancellationListener(Executor, Runnable) cancelled
     * by the video frame producer}. After one of these conditions occurs, a request is considered
     * completed.
     *
     * <p>Once a request is successfully completed, it is guaranteed that if a new request is
     * made, the {@link Surface} used to fulfill the previous request will be detached from the
     * video frame producer and the {@code resultListener} provided in
     * {@link SurfaceRequest#provideSurface(Surface, Executor, Consumer)}
     * will be invoked with a {@link androidx.camera.core.SurfaceRequest.Result} containing
     * {@link androidx.camera.core.SurfaceRequest.Result#RESULT_SURFACE_USED_SUCCESSFULLY}.
     *
     * @param request the request for a surface which contains the requirements of the
     *                surface and methods for completing the request.
     */
    void onSurfaceRequested(@NonNull SurfaceRequest request);

    /**
     * Called when a new {@link Surface} has been requested by a video frame producer.
     *
     * @param timebase the video source timebase
     */
    @RestrictTo(Scope.LIBRARY)
    default void onSurfaceRequested(@NonNull SurfaceRequest request, @NonNull Timebase timebase) {
        onSurfaceRequested(request);
    }

    /**
     * Returns an observable {@link StreamInfo} which contains the information of the
     * {@link VideoOutput}.
     */
    @NonNull
    @RestrictTo(Scope.LIBRARY)
    default Observable<StreamInfo> getStreamInfo() {
        return StreamInfo.ALWAYS_ACTIVE_OBSERVABLE;
    }

    /**
     * Returns an observable {@link MediaSpec} which contains hints about what kind of input the
     * {@link VideoOutput} is expecting.
     *
     * <p>All values contained in the media specification are considered hints and may be ignored
     * by the video frame producer. The {@link VideoOutput} should always respect the surface
     * requirements given in the {@link SurfaceRequest} in
     * {@link #onSurfaceRequested(SurfaceRequest)}, or the video frame producer may not be able
     * to produce frames.
     *
     * <p>Implementations should be careful about updating the {@link MediaSpec} too often, as
     * changes may not come for free and may require the video frame producer to re-initialize,
     * which could cause a new {@link SurfaceRequest} to be sent to
     * {@link #onSurfaceRequested(SurfaceRequest)}.
     */
    @RestrictTo(Scope.LIBRARY)
    @NonNull
    default Observable<MediaSpec> getMediaSpec() {
        return ConstantObservable.withValue(null);
    }

    /**
     * Returns an observable to know if the streaming from a video frame producer is required.
     *
     * <p> This should be true for cases like when user is starting a video recording or streaming
     * and false when user has decided to stop the recording/streaming. The video frame producer
     * will use this information to do know whether it's now safe to do operations which may disrupt
     * video quality/consistency (e.g. AE precapture).
     */
    @RestrictTo(Scope.LIBRARY)
    @NonNull
    default Observable<Boolean> isSourceStreamRequired() {
        return ConstantObservable.withValue(false);
    }

    /**
     * Called when the state of the video frame producer is changed.
     */
    @RestrictTo(Scope.LIBRARY)
    default void onSourceStateChanged(@NonNull SourceState sourceState) {

    }

    // TODO(b/278170231): wraps getMediaSpec and getMediaCapabilities for increased scalability and
    //  easier retrieval of initial specs and capabilities.
    /**
     * Returns the {@link VideoCapabilities} information of the {@link VideoOutput}.
     */
    @RestrictTo(Scope.LIBRARY)
    @NonNull
    default VideoCapabilities getMediaCapabilities(@NonNull CameraInfo cameraInfo) {
        return VideoCapabilities.EMPTY;
    }
}