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 com.google.android.exoplayer2.transformer; 18 19 import android.media.MediaCodec.BufferInfo; 20 import android.view.Surface; 21 import androidx.annotation.Nullable; 22 import com.google.android.exoplayer2.C; 23 import com.google.android.exoplayer2.Format; 24 import com.google.android.exoplayer2.decoder.DecoderInputBuffer; 25 import com.google.android.exoplayer2.util.MimeTypes; 26 import java.nio.ByteBuffer; 27 import java.util.List; 28 29 /** 30 * Provides a layer of abstraction for interacting with decoders and encoders. 31 * 32 * <p>{@link DecoderInputBuffer DecoderInputBuffers} are used as both decoders' and encoders' input 33 * buffers. 34 */ 35 public interface Codec { 36 37 /** A factory for {@linkplain Codec decoder} instances. */ 38 interface DecoderFactory { 39 40 /** A default {@code DecoderFactory} implementation. */ 41 DecoderFactory DEFAULT = new DefaultDecoderFactory(); 42 43 /** 44 * Returns a {@link Codec} for audio decoding. 45 * 46 * @param format The {@link Format} (of the input data) used to determine the underlying decoder 47 * and its configuration values. 48 * @return A {@link Codec} for audio decoding. 49 * @throws TransformationException If no suitable {@link Codec} can be created. 50 */ createForAudioDecoding(Format format)51 Codec createForAudioDecoding(Format format) throws TransformationException; 52 53 /** 54 * Returns a {@link Codec} for video decoding. 55 * 56 * @param format The {@link Format} (of the input data) used to determine the underlying decoder 57 * and its configuration values. 58 * @param outputSurface The {@link Surface} to which the decoder output is rendered. 59 * @param enableRequestSdrToneMapping Whether to request tone-mapping to SDR. 60 * @return A {@link Codec} for video decoding. 61 * @throws TransformationException If no suitable {@link Codec} can be created. 62 */ createForVideoDecoding( Format format, Surface outputSurface, boolean enableRequestSdrToneMapping)63 Codec createForVideoDecoding( 64 Format format, Surface outputSurface, boolean enableRequestSdrToneMapping) 65 throws TransformationException; 66 } 67 68 /** A factory for {@linkplain Codec encoder} instances. */ 69 interface EncoderFactory { 70 71 /** A default {@code EncoderFactory} implementation. */ 72 EncoderFactory DEFAULT = new DefaultEncoderFactory(); 73 74 /** 75 * Returns a {@link Codec} for audio encoding. 76 * 77 * <p>This method must validate that the {@link Codec} is configured to produce one of the 78 * {@code allowedMimeTypes}. The {@linkplain Format#sampleMimeType sample MIME type} given in 79 * {@code format} is not necessarily allowed. 80 * 81 * @param format The {@link Format} (of the output data) used to determine the underlying 82 * encoder and its configuration values. 83 * @param allowedMimeTypes The non-empty list of allowed output sample {@linkplain MimeTypes 84 * MIME types}. 85 * @return A {@link Codec} for audio encoding. 86 * @throws TransformationException If no suitable {@link Codec} can be created. 87 */ createForAudioEncoding(Format format, List<String> allowedMimeTypes)88 Codec createForAudioEncoding(Format format, List<String> allowedMimeTypes) 89 throws TransformationException; 90 91 /** 92 * Returns a {@link Codec} for video encoding. 93 * 94 * <p>This method must validate that the {@link Codec} is configured to produce one of the 95 * {@code allowedMimeTypes}. The {@linkplain Format#sampleMimeType sample MIME type} given in 96 * {@code format} is not necessarily allowed. 97 * 98 * @param format The {@link Format} (of the output data) used to determine the underlying 99 * encoder and its configuration values. {@link Format#sampleMimeType}, {@link Format#width} 100 * and {@link Format#height} are set to those of the desired output video format. {@link 101 * Format#rotationDegrees} is 0 and {@link Format#width} {@code >=} {@link Format#height}, 102 * therefore the video is always in landscape orientation. {@link Format#frameRate} is set 103 * to the output video's frame rate, if available. 104 * @param allowedMimeTypes The non-empty list of allowed output sample {@linkplain MimeTypes 105 * MIME types}. 106 * @return A {@link Codec} for video encoding. 107 * @throws TransformationException If no suitable {@link Codec} can be created. 108 */ createForVideoEncoding(Format format, List<String> allowedMimeTypes)109 Codec createForVideoEncoding(Format format, List<String> allowedMimeTypes) 110 throws TransformationException; 111 112 /** Returns whether the audio needs to be encoded because of encoder specific configuration. */ audioNeedsEncoding()113 default boolean audioNeedsEncoding() { 114 return false; 115 } 116 117 /** Returns whether the video needs to be encoded because of encoder specific configuration. */ videoNeedsEncoding()118 default boolean videoNeedsEncoding() { 119 return false; 120 } 121 } 122 123 /** 124 * Returns the {@link Format} used for configuring the {@code Codec}. 125 * 126 * <p>The configuration {@link Format} is the input {@link Format} used by the {@link 127 * DecoderFactory} or output {@link Format} used by the {@link EncoderFactory} for selecting and 128 * configuring the underlying decoder or encoder. 129 */ getConfigurationFormat()130 Format getConfigurationFormat(); 131 132 /** 133 * Returns the input {@link Surface} of an underlying video encoder. 134 * 135 * <p>This method must only be called on video encoders because audio/video decoders and audio 136 * encoders don't use a {@link Surface} as input. 137 */ getInputSurface()138 Surface getInputSurface(); 139 140 /** 141 * Dequeues a writable input buffer, if available. 142 * 143 * <p>This method must not be called from video encoders because they must use a {@link Surface} 144 * to receive input. 145 * 146 * @param inputBuffer The buffer where the dequeued buffer data is stored, at {@link 147 * DecoderInputBuffer#data inputBuffer.data}. 148 * @return Whether an input buffer is ready to be used. 149 * @throws TransformationException If the underlying decoder or encoder encounters a problem. 150 */ maybeDequeueInputBuffer(DecoderInputBuffer inputBuffer)151 boolean maybeDequeueInputBuffer(DecoderInputBuffer inputBuffer) throws TransformationException; 152 153 /** 154 * Queues an input buffer to the {@code Codec}. No buffers may be queued after {@linkplain 155 * DecoderInputBuffer#isEndOfStream() end of stream} buffer has been queued. 156 * 157 * <p>This method must not be called from video encoders because they must use a {@link Surface} 158 * to receive input. 159 * 160 * @param inputBuffer The {@linkplain DecoderInputBuffer input buffer}. 161 * @throws TransformationException If the underlying decoder or encoder encounters a problem. 162 */ queueInputBuffer(DecoderInputBuffer inputBuffer)163 void queueInputBuffer(DecoderInputBuffer inputBuffer) throws TransformationException; 164 165 /** 166 * Signals end-of-stream on input to a video encoder. 167 * 168 * <p>This method must only be called on video encoders because they must use a {@link Surface} as 169 * input. For audio/video decoders or audio encoders, the {@link C#BUFFER_FLAG_END_OF_STREAM} flag 170 * should be set on the last input buffer {@linkplain #queueInputBuffer(DecoderInputBuffer) 171 * queued}. 172 * 173 * @throws TransformationException If the underlying video encoder encounters a problem. 174 */ signalEndOfInputStream()175 void signalEndOfInputStream() throws TransformationException; 176 177 /** 178 * Returns the current output format, or {@code null} if unavailable. 179 * 180 * @throws TransformationException If the underlying decoder or encoder encounters a problem. 181 */ 182 @Nullable getOutputFormat()183 Format getOutputFormat() throws TransformationException; 184 185 /** 186 * Returns the current output {@link ByteBuffer}, or {@code null} if unavailable. 187 * 188 * <p>This method must not be called on video decoders because they must output to a {@link 189 * Surface}. 190 * 191 * @throws TransformationException If the underlying decoder or encoder encounters a problem. 192 */ 193 @Nullable getOutputBuffer()194 ByteBuffer getOutputBuffer() throws TransformationException; 195 196 /** 197 * Returns the {@link BufferInfo} associated with the current output buffer, or {@code null} if 198 * there is no output buffer available. 199 * 200 * <p>This method returns {@code null} if and only if {@link #getOutputBuffer()} returns null. 201 * 202 * @throws TransformationException If the underlying decoder or encoder encounters a problem. 203 */ 204 @Nullable getOutputBufferInfo()205 BufferInfo getOutputBufferInfo() throws TransformationException; 206 207 /** 208 * Releases the current output buffer. 209 * 210 * <p>Only set {@code render} to {@code true} when the {@code Codec} is a video decoder. Setting 211 * {@code render} to {@code true} will first render the buffer to the output surface. In this 212 * case, the surface will release the buffer back to the {@code Codec} once it is no longer 213 * used/displayed. 214 * 215 * <p>This should be called after the buffer has been processed. The next output buffer will not 216 * be available until the current output buffer has been released. 217 * 218 * @param render Whether the buffer needs to be rendered to the output {@link Surface}. 219 * @throws TransformationException If the underlying decoder or encoder encounters a problem. 220 */ releaseOutputBuffer(boolean render)221 void releaseOutputBuffer(boolean render) throws TransformationException; 222 223 /** 224 * Returns whether the {@code Codec}'s output stream has ended, and no more data can be dequeued. 225 */ isEnded()226 boolean isEnded(); 227 228 /** Releases the {@code Codec}. */ release()229 void release(); 230 } 231