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