1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_ 6#define MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_ 7 8#include <jni.h> 9#include <string> 10 11#include "base/android/scoped_java_ref.h" 12#include "base/time/time.h" 13#include "media/base/audio_decoder_config.h" 14#include "media/base/video_decoder_config.h" 15#include "ui/gfx/size.h" 16 17namespace media { 18 19struct SubsampleEntry; 20 21// These must be in sync with MediaCodecBridge.MEDIA_CODEC_XXX constants in 22// MediaCodecBridge.java. 23enum MediaCodecStatus { 24 MEDIA_CODEC_OK, 25 MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER, 26 MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER, 27 MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED, 28 MEDIA_CODEC_OUTPUT_FORMAT_CHANGED, 29 MEDIA_CODEC_INPUT_END_OF_STREAM, 30 MEDIA_CODEC_OUTPUT_END_OF_STREAM, 31 MEDIA_CODEC_NO_KEY, 32 MEDIA_CODEC_STOPPED, 33 MEDIA_CODEC_ERROR 34}; 35 36// Codec direction. Keep this in sync with MediaCodecBridge.java. 37enum MediaCodecDirection { 38 MEDIA_CODEC_DECODER, 39 MEDIA_CODEC_ENCODER, 40}; 41 42// This class serves as a bridge for native code to call java functions inside 43// Android MediaCodec class. For more information on Android MediaCodec, check 44// http://developer.android.com/reference/android/media/MediaCodec.html 45// Note: MediaCodec is only available on JB and greater. 46// Use AudioCodecBridge or VideoCodecBridge to create an instance of this 47// object. 48// 49// TODO(fischman,xhwang): replace this (and the enums that go with it) with 50// chromium's JNI auto-generation hotness. 51class MEDIA_EXPORT MediaCodecBridge { 52 public: 53 // Returns true if MediaCodec is available on the device. 54 // All other static methods check IsAvailable() internally. There's no need 55 // to check IsAvailable() explicitly before calling them. 56 static bool IsAvailable(); 57 58 // Returns true if MediaCodec.setParameters() is available on the device. 59 static bool SupportsSetParameters(); 60 61 // Returns true if MediaCodec.getName() is available on the device. 62 static bool SupportsGetName(); 63 64 // Returns whether MediaCodecBridge has a decoder that |is_secure| and can 65 // decode |codec| type. 66 static bool CanDecode(const std::string& codec, bool is_secure); 67 68 // Represents supported codecs on android. 69 // TODO(qinmin): Currently the codecs string only contains one codec. Do we 70 // need to support codecs separated by comma. (e.g. "vp8" -> "vp8, vp8.0")? 71 struct CodecsInfo { 72 std::string codecs; // E.g. "vp8" or "avc1". 73 std::string name; // E.g. "OMX.google.vp8.decoder". 74 MediaCodecDirection direction; 75 }; 76 77 // Get a list of supported codecs. 78 static std::vector<CodecsInfo> GetCodecsInfo(); 79 80 // Get default codec name for |mime_type|. 81 static std::string GetDefaultCodecName(const std::string& mime_type, 82 MediaCodecDirection direction); 83 84 virtual ~MediaCodecBridge(); 85 86 // Resets both input and output, all indices previously returned in calls to 87 // DequeueInputBuffer() and DequeueOutputBuffer() become invalid. 88 // Please note that this clears all the inputs in the media codec. In other 89 // words, there will be no outputs until new input is provided. 90 // Returns MEDIA_CODEC_ERROR if an unexpected error happens, or Media_CODEC_OK 91 // otherwise. 92 MediaCodecStatus Reset(); 93 94 // Finishes the decode/encode session. The instance remains active 95 // and ready to be StartAudio/Video()ed again. HOWEVER, due to the buggy 96 // vendor's implementation , b/8125974, Stop() -> StartAudio/Video() may not 97 // work on some devices. For reliability, Stop() -> delete and recreate new 98 // instance -> StartAudio/Video() is recommended. 99 void Stop(); 100 101 // Used for getting output format. This is valid after DequeueInputBuffer() 102 // returns a format change by returning INFO_OUTPUT_FORMAT_CHANGED 103 void GetOutputFormat(int* width, int* height); 104 105 // Returns the number of input buffers used by the codec. 106 int GetInputBuffersCount(); 107 108 // Submits a byte array to the given input buffer. Call this after getting an 109 // available buffer from DequeueInputBuffer(). If |data| is NULL, assume the 110 // input buffer has already been populated (but still obey |size|). 111 // |data_size| must be less than kint32max (because Java). 112 MediaCodecStatus QueueInputBuffer(int index, 113 const uint8* data, 114 size_t data_size, 115 const base::TimeDelta& presentation_time); 116 117 // Similar to the above call, but submits a buffer that is encrypted. Note: 118 // NULL |subsamples| indicates the whole buffer is encrypted. If |data| is 119 // NULL, assume the input buffer has already been populated (but still obey 120 // |data_size|). |data_size| must be less than kint32max (because Java). 121 MediaCodecStatus QueueSecureInputBuffer( 122 int index, 123 const uint8* data, 124 size_t data_size, 125 const uint8* key_id, 126 int key_id_size, 127 const uint8* iv, 128 int iv_size, 129 const SubsampleEntry* subsamples, 130 int subsamples_size, 131 const base::TimeDelta& presentation_time); 132 133 // Submits an empty buffer with a EOS (END OF STREAM) flag. 134 void QueueEOS(int input_buffer_index); 135 136 // Returns: 137 // MEDIA_CODEC_OK if an input buffer is ready to be filled with valid data, 138 // MEDIA_CODEC_ENQUEUE_INPUT_AGAIN_LATER if no such buffer is available, or 139 // MEDIA_CODEC_ERROR if unexpected error happens. 140 // Note: Never use infinite timeout as this would block the decoder thread and 141 // prevent the decoder job from being released. 142 MediaCodecStatus DequeueInputBuffer(const base::TimeDelta& timeout, 143 int* index); 144 145 // Dequeues an output buffer, block at most timeout_us microseconds. 146 // Returns the status of this operation. If OK is returned, the output 147 // parameters should be populated. Otherwise, the values of output parameters 148 // should not be used. Output parameters other than index/offset/size are 149 // optional and only set if not NULL. 150 // Note: Never use infinite timeout as this would block the decoder thread and 151 // prevent the decoder job from being released. 152 // TODO(xhwang): Can we drop |end_of_stream| and return 153 // MEDIA_CODEC_OUTPUT_END_OF_STREAM? 154 MediaCodecStatus DequeueOutputBuffer(const base::TimeDelta& timeout, 155 int* index, 156 size_t* offset, 157 size_t* size, 158 base::TimeDelta* presentation_time, 159 bool* end_of_stream, 160 bool* key_frame); 161 162 // Returns the buffer to the codec. If you previously specified a surface when 163 // configuring this video decoder you can optionally render the buffer. 164 void ReleaseOutputBuffer(int index, bool render); 165 166 // Returns the number of output buffers used by the codec. 167 int GetOutputBuffersCount(); 168 169 // Returns the capacity of each output buffer used by the codec. 170 size_t GetOutputBuffersCapacity(); 171 172 // Gets output buffers from media codec and keeps them inside the java class. 173 // To access them, use DequeueOutputBuffer(). Returns whether output buffers 174 // were successfully obtained. 175 bool GetOutputBuffers() WARN_UNUSED_RESULT; 176 177 // Returns an input buffer's base pointer and capacity. 178 void GetInputBuffer(int input_buffer_index, uint8** data, size_t* capacity); 179 180 // Copy |dst_size| bytes from output buffer |index|'s |offset| onwards into 181 // |*dst|. 182 bool CopyFromOutputBuffer(int index, size_t offset, void* dst, int dst_size); 183 184 static bool RegisterMediaCodecBridge(JNIEnv* env); 185 186 protected: 187 // Returns true if |mime_type| is known to be unaccelerated (i.e. backed by a 188 // software codec instead of a hardware one). 189 static bool IsKnownUnaccelerated(const std::string& mime_type, 190 MediaCodecDirection direction); 191 192 MediaCodecBridge(const std::string& mime, 193 bool is_secure, 194 MediaCodecDirection direction); 195 196 // Calls start() against the media codec instance. Used in StartXXX() after 197 // configuring media codec. Returns whether media codec was successfully 198 // started. 199 bool StartInternal() WARN_UNUSED_RESULT; 200 201 jobject media_codec() { return j_media_codec_.obj(); } 202 MediaCodecDirection direction_; 203 204 private: 205 // Fills a particular input buffer; returns false if |data_size| exceeds the 206 // input buffer's capacity (and doesn't touch the input buffer in that case). 207 bool FillInputBuffer(int index, 208 const uint8* data, 209 size_t data_size) WARN_UNUSED_RESULT; 210 211 // Java MediaCodec instance. 212 base::android::ScopedJavaGlobalRef<jobject> j_media_codec_; 213 214 DISALLOW_COPY_AND_ASSIGN(MediaCodecBridge); 215}; 216 217class AudioCodecBridge : public MediaCodecBridge { 218 public: 219 // Returns an AudioCodecBridge instance if |codec| is supported, or a NULL 220 // pointer otherwise. 221 static AudioCodecBridge* Create(const AudioCodec& codec); 222 223 // See MediaCodecBridge::IsKnownUnaccelerated(). 224 static bool IsKnownUnaccelerated(const AudioCodec& codec); 225 226 // Start the audio codec bridge. 227 bool Start(const AudioCodec& codec, int sample_rate, int channel_count, 228 const uint8* extra_data, size_t extra_data_size, 229 bool play_audio, jobject media_crypto) WARN_UNUSED_RESULT; 230 231 // Play the output buffer. This call must be called after 232 // DequeueOutputBuffer() and before ReleaseOutputBuffer. Returns the playback 233 // head position expressed in frames. 234 int64 PlayOutputBuffer(int index, size_t size); 235 236 // Set the volume of the audio output. 237 void SetVolume(double volume); 238 239 private: 240 explicit AudioCodecBridge(const std::string& mime); 241 242 // Configure the java MediaFormat object with the extra codec data passed in. 243 bool ConfigureMediaFormat(jobject j_format, const AudioCodec& codec, 244 const uint8* extra_data, size_t extra_data_size); 245}; 246 247class MEDIA_EXPORT VideoCodecBridge : public MediaCodecBridge { 248 public: 249 // See MediaCodecBridge::IsKnownUnaccelerated(). 250 static bool IsKnownUnaccelerated(const VideoCodec& codec, 251 MediaCodecDirection direction); 252 253 // Create, start, and return a VideoCodecBridge decoder or NULL on failure. 254 static VideoCodecBridge* CreateDecoder( 255 const VideoCodec& codec, // e.g. media::kCodecVP8 256 bool is_secure, 257 const gfx::Size& size, // Output frame size. 258 jobject surface, // Output surface, optional. 259 jobject media_crypto); // MediaCrypto object, optional. 260 261 // Create, start, and return a VideoCodecBridge encoder or NULL on failure. 262 static VideoCodecBridge* CreateEncoder( 263 const VideoCodec& codec, // e.g. media::kCodecVP8 264 const gfx::Size& size, // input frame size 265 int bit_rate, // bits/second 266 int frame_rate, // frames/second 267 int i_frame_interval, // count 268 int color_format); // MediaCodecInfo.CodecCapabilities. 269 270 void SetVideoBitrate(int bps); 271 void RequestKeyFrameSoon(); 272 273 // Returns whether adaptive playback is supported for this object given 274 // the new size. 275 bool IsAdaptivePlaybackSupported(int width, int height); 276 277 // Test-only method to set the return value of IsAdaptivePlaybackSupported(). 278 // Without this function, the return value of that function will be device 279 // dependent. If |adaptive_playback_supported| is equal to 0, the return value 280 // will be false. If |adaptive_playback_supported| is larger than 0, the 281 // return value will be true. 282 void set_adaptive_playback_supported_for_testing( 283 int adaptive_playback_supported) { 284 adaptive_playback_supported_for_testing_ = adaptive_playback_supported; 285 } 286 287 private: 288 VideoCodecBridge(const std::string& mime, 289 bool is_secure, 290 MediaCodecDirection direction); 291 292 int adaptive_playback_supported_for_testing_; 293}; 294 295} // namespace media 296 297#endif // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_ 298