1 /* 2 * Copyright 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.camera.video; 18 19 import android.view.Surface; 20 21 import androidx.annotation.RestrictTo; 22 import androidx.camera.core.SurfaceRequest; 23 import androidx.camera.core.impl.ConstantObservable; 24 import androidx.camera.core.impl.Observable; 25 26 import com.google.auto.value.AutoValue; 27 28 import org.jspecify.annotations.NonNull; 29 import org.jspecify.annotations.Nullable; 30 31 import java.util.Arrays; 32 import java.util.Collections; 33 import java.util.HashSet; 34 import java.util.Set; 35 36 /** 37 * A class that contains the information of an video output stream. 38 * 39 */ 40 @RestrictTo(RestrictTo.Scope.LIBRARY) 41 @AutoValue 42 public abstract class StreamInfo { 43 44 /** The stream hasn't been setup. */ 45 static final int STREAM_ID_ANY = 0; 46 47 /** The stream setup fails. */ 48 static final int STREAM_ID_ERROR = -1; 49 50 static final StreamInfo STREAM_INFO_ANY_INACTIVE = StreamInfo.of(STREAM_ID_ANY, 51 StreamState.INACTIVE); 52 53 static final Set<Integer> NON_SURFACE_STREAM_ID = Collections.unmodifiableSet( 54 new HashSet<>(Arrays.asList(STREAM_ID_ANY, STREAM_ID_ERROR))); 55 56 static final Observable<StreamInfo> ALWAYS_ACTIVE_OBSERVABLE = 57 ConstantObservable.withValue(StreamInfo.of(STREAM_ID_ANY, StreamState.ACTIVE)); 58 /** 59 * A state which represents whether the video output is ready for frame streaming. 60 * 61 * <p>This is used in the observable returned by {@link #getStreamState()} to inform 62 * producers that they can start or stop producing frames. 63 */ 64 @RestrictTo(RestrictTo.Scope.LIBRARY) 65 enum StreamState { 66 /** The video output is active and ready to receive frames. */ 67 ACTIVE, 68 /** The video output is inactive and any frames sent will be discarded. */ 69 INACTIVE; 70 } 71 StreamInfo()72 StreamInfo() { 73 74 } 75 of(int id, @NonNull StreamState streamState)76 static @NonNull StreamInfo of(int id, @NonNull StreamState streamState) { 77 return new AutoValue_StreamInfo(id, streamState, null); 78 } 79 of(int id, @NonNull StreamState streamState, SurfaceRequest.@Nullable TransformationInfo inProgressTransformationInfo)80 static @NonNull StreamInfo of(int id, @NonNull StreamState streamState, 81 SurfaceRequest.@Nullable TransformationInfo inProgressTransformationInfo) { 82 return new AutoValue_StreamInfo(id, streamState, inProgressTransformationInfo); 83 } 84 85 /** 86 * Gets the ID of the video output stream. 87 * 88 * <p>The ID will be changed if the {@link Surface} provided to 89 * {@link VideoOutput#onSurfaceRequested} becomes invalid by the {@link VideoOutput}. A new 90 * {@link SurfaceRequest} has to be issued in order to obtain a new {@link Surface} to 91 * continue drawing frames to the {@link VideoOutput}. 92 * 93 * <p>The ID will be {@link #STREAM_ID_ANY} if the stream hasn't been setup and the ID will be 94 * {@link #STREAM_ID_ERROR} if the stream setup fails. 95 */ getId()96 public abstract int getId(); 97 98 /** 99 * Gets the stream state which can be used to determine if the video output is ready for 100 * streaming. 101 * 102 * <p>When the StreamState is ACTIVE, the {@link Surface} provided to 103 * {@link VideoOutput#onSurfaceRequested} should be ready to consume frames. 104 * 105 * <p>When the StreamState is INACTIVE, any frames drawn to the {@link Surface} may be 106 * discarded. 107 * 108 * <p>This can be used by video producers to determine when frames should be drawn to the 109 * {@link Surface} to ensure they are not doing excess work. 110 * 111 * <p>Implementers of the VideoOutput interface should consider overriding this method 112 * as a performance improvement. The default implementation returns an {@link Observable} 113 * which is always {@link StreamState#ACTIVE}. 114 */ getStreamState()115 public abstract @NonNull StreamState getStreamState(); 116 117 /** 118 * Returns the existing transformation information if there's an in-processing surface. 119 * 120 * @return the in-progress transformation information, or {@code null} if there's no 121 * in-processing surface. 122 */ getInProgressTransformationInfo()123 public abstract SurfaceRequest.@Nullable TransformationInfo getInProgressTransformationInfo(); 124 } 125