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.
5 #ifndef MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
6 #define MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
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"
19 struct SubsampleEntry;
21 // These must be in sync with MediaCodecBridge.MEDIA_CODEC_XXX constants in
22 // MediaCodecBridge.java.
23 enum MediaCodecStatus {
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,
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
38 // http://developer.android.com/reference/android/media/MediaCodec.html
39 // Note: MediaCodec is only available on JB and greater.
40 // Use AudioCodecBridge or VideoCodecBridge to create an instance of this
42 class MEDIA_EXPORT MediaCodecBridge {
44 // Returns true if MediaCodec is available on the device.
45 static bool IsAvailable();
47 // Returns whether MediaCodecBridge has a decoder that |is_secure| and can
48 // decode |codec| type.
49 static bool CanDecode(const std::string& codec, bool is_secure);
51 // Represents supported codecs on android. |secure_decoder_supported| is true
52 // if secure decoder is available for the codec type.
53 // TODO(qinmin): Curretly the codecs string only contains one codec, do we
54 // need more specific codecs separated by comma. (e.g. "vp8" -> "vp8, vp8.0")
58 bool secure_decoder_supported;
61 // Get a list of supported codecs.
62 static void GetCodecsInfo(std::vector<CodecsInfo>* codecs_info);
64 virtual ~MediaCodecBridge();
66 // Resets both input and output, all indices previously returned in calls to
67 // DequeueInputBuffer() and DequeueOutputBuffer() become invalid.
68 // Please note that this clears all the inputs in the media codec. In other
69 // words, there will be no outputs until new input is provided.
70 // Returns MEDIA_CODEC_ERROR if an unexpected error happens, or Media_CODEC_OK
72 MediaCodecStatus Reset();
74 // Finishes the decode/encode session. The instance remains active
75 // and ready to be StartAudio/Video()ed again. HOWEVER, due to the buggy
76 // vendor's implementation , b/8125974, Stop() -> StartAudio/Video() may not
77 // work on some devices. For reliability, Stop() -> delete and recreate new
78 // instance -> StartAudio/Video() is recommended.
81 // Used for getting output format. This is valid after DequeueInputBuffer()
82 // returns a format change by returning INFO_OUTPUT_FORMAT_CHANGED
83 void GetOutputFormat(int* width, int* height);
85 // Submits a byte array to the given input buffer. Call this after getting an
86 // available buffer from DequeueInputBuffer().
87 MediaCodecStatus QueueInputBuffer(int index,
90 const base::TimeDelta& presentation_time);
92 // Similar to the above call, but submits a buffer that is encrypted.
93 // Note: NULL |subsamples| indicates the whole buffer is encrypted.
94 MediaCodecStatus QueueSecureInputBuffer(
96 const uint8* data, int data_size,
97 const uint8* key_id, int key_id_size,
98 const uint8* iv, int iv_size,
99 const SubsampleEntry* subsamples, int subsamples_size,
100 const base::TimeDelta& presentation_time);
102 // Submits an empty buffer with a EOS (END OF STREAM) flag.
103 void QueueEOS(int input_buffer_index);
106 // MEDIA_CODEC_OK if an input buffer is ready to be filled with valid data,
107 // MEDIA_CODEC_ENQUEUE_INPUT_AGAIN_LATER if no such buffer is available, or
108 // MEDIA_CODEC_ERROR if unexpected error happens.
109 // Note: Never use infinite timeout as this would block the decoder thread and
110 // prevent the decoder job from being released.
111 MediaCodecStatus DequeueInputBuffer(const base::TimeDelta& timeout,
114 // Dequeues an output buffer, block at most timeout_us microseconds.
115 // Returns the status of this operation. If OK is returned, the output
116 // parameters should be populated. Otherwise, the values of output parameters
117 // should not be used.
118 // Note: Never use infinite timeout as this would block the decoder thread and
119 // prevent the decoder job from being released.
120 // TODO(xhwang): Can we drop |end_of_stream| and return
121 // MEDIA_CODEC_OUTPUT_END_OF_STREAM?
122 MediaCodecStatus DequeueOutputBuffer(const base::TimeDelta& timeout,
126 base::TimeDelta* presentation_time,
127 bool* end_of_stream);
129 // Returns the buffer to the codec. If you previously specified a surface
130 // when configuring this video decoder you can optionally render the buffer.
131 void ReleaseOutputBuffer(int index, bool render);
133 // Gets output buffers from media codec and keeps them inside the java class.
134 // To access them, use DequeueOutputBuffer(). Returns whether output buffers
135 // were successfully obtained.
136 bool GetOutputBuffers() WARN_UNUSED_RESULT;
138 static bool RegisterMediaCodecBridge(JNIEnv* env);
141 // Returns true if |mime_type| is known to be unaccelerated (i.e. backed by a
142 // software codec instead of a hardware one).
143 static bool IsKnownUnaccelerated(const std::string& mime_type);
145 MediaCodecBridge(const std::string& mime, bool is_secure);
147 // Calls start() against the media codec instance. Used in StartXXX() after
148 // configuring media codec. Returns whether media codec was successfully
150 bool StartInternal() WARN_UNUSED_RESULT;
152 jobject media_codec() { return j_media_codec_.obj(); }
155 // Fills a particular input buffer; returns false if |data_size| exceeds the
156 // input buffer's capacity (and doesn't touch the input buffer in that case).
157 bool FillInputBuffer(int index,
159 int data_size) WARN_UNUSED_RESULT;
161 // Java MediaCodec instance.
162 base::android::ScopedJavaGlobalRef<jobject> j_media_codec_;
164 DISALLOW_COPY_AND_ASSIGN(MediaCodecBridge);
167 class AudioCodecBridge : public MediaCodecBridge {
169 // Returns an AudioCodecBridge instance if |codec| is supported, or a NULL
170 // pointer otherwise.
171 static AudioCodecBridge* Create(const AudioCodec& codec);
173 // See MediaCodecBridge::IsKnownUnaccelerated().
174 static bool IsKnownUnaccelerated(const AudioCodec& codec);
176 // Start the audio codec bridge.
177 bool Start(const AudioCodec& codec, int sample_rate, int channel_count,
178 const uint8* extra_data, size_t extra_data_size,
179 bool play_audio, jobject media_crypto) WARN_UNUSED_RESULT;
181 // Play the output buffer. This call must be called after
182 // DequeueOutputBuffer() and before ReleaseOutputBuffer.
183 void PlayOutputBuffer(int index, size_t size);
185 // Set the volume of the audio output.
186 void SetVolume(double volume);
189 explicit AudioCodecBridge(const std::string& mime);
191 // Configure the java MediaFormat object with the extra codec data passed in.
192 bool ConfigureMediaFormat(jobject j_format, const AudioCodec& codec,
193 const uint8* extra_data, size_t extra_data_size);
196 class MEDIA_EXPORT VideoCodecBridge : public MediaCodecBridge {
198 // Returns an VideoCodecBridge instance if |codec| is supported, or a NULL
199 // pointer otherwise.
200 static VideoCodecBridge* Create(const VideoCodec& codec, bool is_secure);
202 // See MediaCodecBridge::IsKnownUnaccelerated().
203 static bool IsKnownUnaccelerated(const VideoCodec& codec);
205 // Start the video codec bridge.
206 // TODO(qinmin): Pass codec specific data if available.
207 bool Start(const VideoCodec& codec, const gfx::Size& size, jobject surface,
208 jobject media_crypto);
211 VideoCodecBridge(const std::string& mime, bool is_secure);
216 #endif // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_