• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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