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 17 namespace media { 18 19 struct SubsampleEntry; 20 21 // This class serves as a bridge for native code to call java functions inside 22 // Android MediaCodec class. For more information on Android MediaCodec, check 23 // http://developer.android.com/reference/android/media/MediaCodec.html 24 // Note: MediaCodec is only available on JB and greater. 25 // Use AudioCodecBridge or VideoCodecBridge to create an instance of this 26 // object. 27 class MEDIA_EXPORT MediaCodecBridge { 28 public: 29 enum DequeueBufferInfo { 30 INFO_OUTPUT_BUFFERS_CHANGED = -3, 31 INFO_OUTPUT_FORMAT_CHANGED = -2, 32 INFO_TRY_AGAIN_LATER = -1, 33 INFO_MEDIA_CODEC_ERROR = -1000, 34 }; 35 36 static const base::TimeDelta kTimeOutInfinity; 37 static const base::TimeDelta kTimeOutNoWait; 38 39 // Returns true if MediaCodec is available on the device. 40 static bool IsAvailable(); 41 42 virtual ~MediaCodecBridge(); 43 44 // Resets both input and output, all indices previously returned in calls to 45 // DequeueInputBuffer() and DequeueOutputBuffer() become invalid. 46 // Please note that this clears all the inputs in the media codec. In other 47 // words, there will be no outputs until new input is provided. 48 // Returns MEDIA_CODEC_ERROR if an unexpected error happens, or Media_CODEC_OK 49 // otherwise. 50 int Reset(); 51 52 // Finishes the decode/encode session. The instance remains active 53 // and ready to be StartAudio/Video()ed again. HOWEVER, due to the buggy 54 // vendor's implementation , b/8125974, Stop() -> StartAudio/Video() may not 55 // work on some devices. For reliability, Stop() -> delete and recreate new 56 // instance -> StartAudio/Video() is recommended. 57 void Stop(); 58 59 // Used for getting output format. This is valid after DequeueInputBuffer() 60 // returns a format change by returning INFO_OUTPUT_FORMAT_CHANGED 61 void GetOutputFormat(int* width, int* height); 62 63 // Submits a byte array to the given input buffer. Call this after getting an 64 // available buffer from DequeueInputBuffer(). Returns the number of bytes 65 // put to the input buffer. 66 size_t QueueInputBuffer(int index, const uint8* data, int size, 67 const base::TimeDelta& presentation_time); 68 69 // Similar to the above call, but submits a buffer that is encrypted. 70 size_t QueueSecureInputBuffer( 71 int index, const uint8* data, int data_size, 72 const uint8* key_id, int key_id_size, 73 const uint8* iv, int iv_size, 74 const SubsampleEntry* subsamples, int subsamples_size, 75 const base::TimeDelta& presentation_time); 76 77 // Submits an empty buffer with a EOS (END OF STREAM) flag. 78 void QueueEOS(int input_buffer_index); 79 80 // Returns an index (>=0) of an input buffer to be filled with valid data, 81 // INFO_TRY_AGAIN_LATER if no such buffer is currently available, or 82 // INFO_MEDIA_CODEC_ERROR if unexpected error happens. 83 // Use kTimeOutInfinity for infinite timeout. 84 int DequeueInputBuffer(base::TimeDelta timeout); 85 86 // Dequeues an output buffer, block at most timeout_us microseconds. 87 // Returns the index of an output buffer that has been successfully decoded 88 // or one of DequeueBufferInfo above. 89 // Use kTimeOutInfinity for infinite timeout. 90 int DequeueOutputBuffer( 91 base::TimeDelta timeout, size_t* offset, size_t* size, 92 base::TimeDelta* presentation_time, bool* end_of_stream); 93 94 // Returns the buffer to the codec. If you previously specified a surface 95 // when configuring this video decoder you can optionally render the buffer. 96 void ReleaseOutputBuffer(int index, bool render); 97 98 // Gets output buffers from media codec and keeps them inside the java class. 99 // To access them, use DequeueOutputBuffer(). 100 void GetOutputBuffers(); 101 102 static bool RegisterMediaCodecBridge(JNIEnv* env); 103 104 protected: 105 explicit MediaCodecBridge(const char* mime); 106 107 // Calls start() against the media codec instance. Used in StartXXX() after 108 // configuring media codec. 109 void StartInternal(); 110 111 jobject media_codec() { return j_media_codec_.obj(); } 112 113 private: 114 // Fills a particular input buffer and returns the size of copied data. 115 size_t FillInputBuffer(int index, const uint8* data, int data_size); 116 117 // Java MediaCodec instance. 118 base::android::ScopedJavaGlobalRef<jobject> j_media_codec_; 119 120 DISALLOW_COPY_AND_ASSIGN(MediaCodecBridge); 121 }; 122 123 class AudioCodecBridge : public MediaCodecBridge { 124 public: 125 // Returns an AudioCodecBridge instance if |codec| is supported, or a NULL 126 // pointer otherwise. 127 static AudioCodecBridge* Create(const AudioCodec codec); 128 129 // Start the audio codec bridge. 130 bool Start(const AudioCodec codec, int sample_rate, int channel_count, 131 const uint8* extra_data, size_t extra_data_size, 132 bool play_audio, jobject media_crypto); 133 134 // Play the output buffer. This call must be called after 135 // DequeueOutputBuffer() and before ReleaseOutputBuffer. 136 void PlayOutputBuffer(int index, size_t size); 137 138 // Set the volume of the audio output. 139 void SetVolume(double volume); 140 141 private: 142 explicit AudioCodecBridge(const char* mime); 143 144 // Configure the java MediaFormat object with the extra codec data passed in. 145 bool ConfigureMediaFormat(jobject j_format, const AudioCodec codec, 146 const uint8* extra_data, size_t extra_data_size); 147 }; 148 149 class MEDIA_EXPORT VideoCodecBridge : public MediaCodecBridge { 150 public: 151 // Returns an VideoCodecBridge instance if |codec| is supported, or a NULL 152 // pointer otherwise. 153 static VideoCodecBridge* Create(const VideoCodec codec); 154 155 // Start the video codec bridge. 156 // TODO(qinmin): Pass codec specific data if available. 157 bool Start(const VideoCodec codec, const gfx::Size& size, jobject surface, 158 jobject media_crypto); 159 160 private: 161 explicit VideoCodecBridge(const char* mime); 162 }; 163 164 } // namespace media 165 166 #endif // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_ 167 168