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