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