MediaCodec.java revision 9b8e496f4d143280deff137c5f30ca8907bc28db
1/*
2 * Copyright (C) 2012 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
17package android.media;
18
19import android.view.Surface;
20import java.nio.ByteBuffer;
21import java.util.Map;
22
23/**
24 * MediaCodec class can be used to access low-level media codec, i.e.
25 * encoder/decoder components.
26 * @hide
27*/
28public class MediaCodec
29{
30    /** Per buffer metadata includes an offset and size specifying
31        the range of valid data in the associated codec buffer.
32    */
33    public final static class BufferInfo {
34        public void set(
35                int offset, int size, long timeUs, int flags) {
36            mOffset = offset;
37            mSize = size;
38            mPresentationTimeUs = timeUs;
39            mFlags = flags;
40        }
41
42        public int mOffset;
43        public int mSize;
44        public long mPresentationTimeUs;
45        public int mFlags;
46    };
47
48    public static int FLAG_SYNCFRAME   = 1;
49    public static int FLAG_CODECCONFIG = 2;
50    public static int FLAG_EOS         = 4;
51    public static int FLAG_ENCRYPTED   = 8;
52
53    /** Instantiate a codec component by mime type. For decoder components
54        this is the mime type of media that this decoder should be able to
55        decoder, for encoder components it's the type of media this encoder
56        should encode _to_.
57    */
58    public static MediaCodec CreateByType(String type, boolean encoder) {
59        return new MediaCodec(type, true /* nameIsType */, encoder);
60    }
61
62    /** If you know the exact name of the component you want to instantiate
63        use this method to instantiate it. Use with caution.
64    */
65    public static MediaCodec CreateByComponentName(String name) {
66        return new MediaCodec(
67                name, false /* nameIsType */, false /* unused */);
68    }
69
70    private MediaCodec(
71            String name, boolean nameIsType, boolean encoder) {
72        native_setup(name, nameIsType, encoder);
73    }
74
75    @Override
76    protected void finalize() {
77        native_finalize();
78    }
79
80    // Make sure you call this when you're done to free up any opened
81    // component instance instead of relying on the garbage collector
82    // to do this for you at some point in the future.
83    public native final void release();
84
85    public static int CONFIGURE_FLAG_ENCODE = 1;
86    public static int CONFIGURE_FLAG_SECURE = 2;
87
88    /** Configures a component.
89     *  @param format A map of string/value pairs describing the input format
90     *                (decoder) or the desired output format.
91     *
92     *                Video formats have the following fields:
93     *                  "mime"          - String
94     *                  "width"         - Integer
95     *                  "height"        - Integer
96     *                  optional "max-input-size"       - Integer
97     *
98     *                Audio formats have the following fields:
99     *                  "mime"          - String
100     *                  "channel-count" - Integer
101     *                  "sample-rate"   - Integer
102     *                  optional "max-input-size"       - Integer
103     *
104     *                If the format is used to configure an encoder, additional
105     *                fields must be included:
106     *                  "bitrate" - Integer (in bits/sec)
107     *
108     *                for video formats:
109     *                  "color-format"          - Integer
110     *                  "frame-rate"            - Integer or Float
111     *                  "i-frame-interval"      - Integer
112     *                  optional "stride"       - Integer, defaults to "width"
113     *                  optional "slice-height" - Integer, defaults to "height"
114     *
115     *  @param surface Specify a surface on which to render the output of this
116     *                 decoder.
117     *  @param flags   Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
118     *                 component as an encoder.
119    */
120    public void configure(
121            Map<String, Object> format, Surface surface, int flags) {
122        String[] keys = null;
123        Object[] values = null;
124
125        if (format != null) {
126            keys = new String[format.size()];
127            values = new Object[format.size()];
128
129            int i = 0;
130            for (Map.Entry<String, Object> entry: format.entrySet()) {
131                keys[i] = entry.getKey();
132                values[i] = entry.getValue();
133                ++i;
134            }
135        }
136
137        native_configure(keys, values, surface, flags);
138    }
139
140    private native final void native_configure(
141            String[] keys, Object[] values, Surface surface, int flags);
142
143    /** After successfully configuring the component, call start. On return
144     *  you can query the component for its input/output buffers.
145    */
146    public native final void start();
147
148    public native final void stop();
149
150    /** Flush both input and output ports of the component, all indices
151     *  previously returned in calls to dequeueInputBuffer and
152     *  dequeueOutputBuffer become invalid.
153    */
154    public native final void flush();
155
156    /** After filling a range of the input buffer at the specified index
157     *  submit it to the component.
158     *
159     *  Many decoders require the actual compressed data stream to be
160     *  preceded by "codec specific data", i.e. setup data used to initialize
161     *  the codec such as PPS/SPS in the case of AVC video or code tables
162     *  in the case of vorbis audio.
163     *  The class MediaExtractor provides codec specific data as part of
164     *  the returned track format in entries named "csd-0", "csd-1" ...
165     *
166     *  These buffers should be submitted using the flag {@link #FLAG_CODECCONFIG}.
167     *
168     *  To indicate that this is the final piece of input data (or rather that
169     *  no more input data follows unless the decoder is subsequently flushed)
170     *  specify the flag {@link FLAG_EOS}.
171    */
172    public native final void queueInputBuffer(
173            int index,
174            int offset, int size, long presentationTimeUs, int flags);
175
176    // Returns the index of an input buffer to be filled with valid data
177    // or -1 if no such buffer is currently available.
178    // This method will return immediately if timeoutUs == 0, wait indefinitely
179    // for the availability of an input buffer if timeoutUs < 0 or wait up
180    // to "timeoutUs" microseconds if timeoutUs > 0.
181    public native final int dequeueInputBuffer(long timeoutUs);
182
183    // Returns the index of an output buffer that has been successfully
184    // decoded or one of the INFO_* constants below.
185    // The provided "info" will be filled with buffer meta data.
186    public static final int INFO_TRY_AGAIN_LATER        = -1;
187    public static final int INFO_OUTPUT_FORMAT_CHANGED  = -2;
188    public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3;
189
190    /** Dequeue an output buffer, block at most "timeoutUs" microseconds. */
191    public native final int dequeueOutputBuffer(
192            BufferInfo info, long timeoutUs);
193
194    // If you are done with a buffer, use this call to return the buffer to
195    // the codec. If you previously specified a surface when configuring this
196    // video decoder you can optionally render the buffer.
197    public native final void releaseOutputBuffer(int index, boolean render);
198
199    /** Call this after dequeueOutputBuffer signals a format change by returning
200     *  {@link #INFO_OUTPUT_FORMAT_CHANGED}
201     */
202    public native final Map<String, Object> getOutputFormat();
203
204    /** Call this after start() returns.
205     */
206    public ByteBuffer[] getInputBuffers() {
207        return getBuffers(true /* input */);
208    }
209
210    /** Call this after start() returns and whenever dequeueOutputBuffer
211     *  signals an output buffer change by returning
212     *  {@link #INFO_OUTPUT_BUFFERS_CHANGED}
213     */
214    public ByteBuffer[] getOutputBuffers() {
215        return getBuffers(false /* input */);
216    }
217
218    private native final ByteBuffer[] getBuffers(boolean input);
219
220    private static native final void native_init();
221
222    private native final void native_setup(
223            String name, boolean nameIsType, boolean encoder);
224
225    private native final void native_finalize();
226
227    static {
228        System.loadLibrary("media_jni");
229        native_init();
230    }
231
232    private int mNativeContext;
233}
234