Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(729)

Side by Side Diff: media/base/android/media_codec_bridge.cc

Issue 74563002: AndroidVideoEncodeAccelerator is born! (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added blacklist-based disabling Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "media/base/android/media_codec_bridge.h" 5 #include "media/base/android/media_codec_bridge.h"
6 6
7 #include <jni.h> 7 #include <jni.h>
8 #include <string> 8 #include <string>
9 9
10 #include "base/android/build_info.h" 10 #include "base/android/build_info.h"
(...skipping 10 matching lines...) Expand all
21 #include "media/base/bit_reader.h" 21 #include "media/base/bit_reader.h"
22 #include "media/base/decrypt_config.h" 22 #include "media/base/decrypt_config.h"
23 23
24 using base::android::AttachCurrentThread; 24 using base::android::AttachCurrentThread;
25 using base::android::ConvertJavaStringToUTF8; 25 using base::android::ConvertJavaStringToUTF8;
26 using base::android::ConvertUTF8ToJavaString; 26 using base::android::ConvertUTF8ToJavaString;
27 using base::android::ScopedJavaLocalRef; 27 using base::android::ScopedJavaLocalRef;
28 28
29 namespace media { 29 namespace media {
30 30
31 enum { kBufferFlagEndOfStream = 4 }; 31 enum {
32 kBufferFlagSyncFrame = 1, // BUFFER_FLAG_SYNC_FRAME
33 kBufferFlagEndOfStream = 4, // BUFFER_FLAG_END_OF_STREAM
34 kConfigureFlagEncode = 1, // CONFIGURE_FLAG_ENCODE
35 };
32 36
33 static const std::string AudioCodecToAndroidMimeType(const AudioCodec& codec) { 37 static const std::string AudioCodecToAndroidMimeType(const AudioCodec& codec) {
34 switch (codec) { 38 switch (codec) {
35 case kCodecMP3: 39 case kCodecMP3:
36 return "audio/mpeg"; 40 return "audio/mpeg";
37 case kCodecVorbis: 41 case kCodecVorbis:
38 return "audio/vorbis"; 42 return "audio/vorbis";
39 case kCodecAAC: 43 case kCodecAAC:
40 return "audio/mp4a-latm"; 44 return "audio/mp4a-latm";
41 default: 45 default:
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 return j_array; 101 return j_array;
98 } 102 }
99 103
100 // static 104 // static
101 bool MediaCodecBridge::IsAvailable() { 105 bool MediaCodecBridge::IsAvailable() {
102 // MediaCodec is only available on JB and greater. 106 // MediaCodec is only available on JB and greater.
103 return base::android::BuildInfo::GetInstance()->sdk_int() >= 16; 107 return base::android::BuildInfo::GetInstance()->sdk_int() >= 16;
104 } 108 }
105 109
106 // static 110 // static
107 void MediaCodecBridge::GetCodecsInfo( 111 bool MediaCodecBridge::SupportsSetParameters() {
108 std::vector<CodecsInfo>* codecs_info) { 112 // MediaCodec.setParameters() is only available starting with K.
113 return base::android::BuildInfo::GetInstance()->sdk_int() >= 19;
114 }
115
116 // static
117 std::vector<MediaCodecBridge::CodecsInfo> MediaCodecBridge::GetCodecsInfo() {
118 std::vector<CodecsInfo> codecs_info;
109 JNIEnv* env = AttachCurrentThread(); 119 JNIEnv* env = AttachCurrentThread();
110 if (!IsAvailable()) 120 if (!IsAvailable())
111 return; 121 return codecs_info;
112 122
113 std::string mime_type; 123 std::string mime_type;
114 std::string codec_name; 124 std::string codec_name;
115 ScopedJavaLocalRef<jobjectArray> j_codec_info_array = 125 ScopedJavaLocalRef<jobjectArray> j_codec_info_array =
116 Java_MediaCodecBridge_getCodecsInfo(env); 126 Java_MediaCodecBridge_getCodecsInfo(env);
117 jsize len = env->GetArrayLength(j_codec_info_array.obj()); 127 jsize len = env->GetArrayLength(j_codec_info_array.obj());
118 for (jsize i = 0; i < len; ++i) { 128 for (jsize i = 0; i < len; ++i) {
119 ScopedJavaLocalRef<jobject> j_info( 129 ScopedJavaLocalRef<jobject> j_info(
120 env, env->GetObjectArrayElement(j_codec_info_array.obj(), i)); 130 env, env->GetObjectArrayElement(j_codec_info_array.obj(), i));
121 ScopedJavaLocalRef<jstring> j_codec_type = 131 ScopedJavaLocalRef<jstring> j_codec_type =
122 Java_CodecInfo_codecType(env, j_info.obj()); 132 Java_CodecInfo_codecType(env, j_info.obj());
123 ConvertJavaStringToUTF8(env, j_codec_type.obj(), &mime_type); 133 ConvertJavaStringToUTF8(env, j_codec_type.obj(), &mime_type);
124 ScopedJavaLocalRef<jstring> j_codec_name = 134 ScopedJavaLocalRef<jstring> j_codec_name =
125 Java_CodecInfo_codecName(env, j_info.obj()); 135 Java_CodecInfo_codecName(env, j_info.obj());
126 CodecsInfo info; 136 CodecsInfo info;
127 info.codecs = AndroidMimeTypeToCodecType(mime_type); 137 info.codecs = AndroidMimeTypeToCodecType(mime_type);
128 ConvertJavaStringToUTF8(env, j_codec_name.obj(), &info.name); 138 ConvertJavaStringToUTF8(env, j_codec_name.obj(), &info.name);
129 codecs_info->push_back(info); 139 info.is_encoder = Java_CodecInfo_isEncoder(env, j_info.obj());
140 codecs_info.push_back(info);
130 } 141 }
142 return codecs_info;
131 } 143 }
132 144
133 // static 145 // static
134 bool MediaCodecBridge::CanDecode(const std::string& codec, bool is_secure) { 146 bool MediaCodecBridge::CanDecode(const std::string& codec, bool is_secure) {
135 JNIEnv* env = AttachCurrentThread(); 147 JNIEnv* env = AttachCurrentThread();
136 std::string mime = CodecTypeToAndroidMimeType(codec); 148 std::string mime = CodecTypeToAndroidMimeType(codec);
137 if (mime.empty()) 149 if (mime.empty())
138 return false; 150 return false;
139 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 151 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
140 ScopedJavaLocalRef<jobject> j_media_codec_bridge = 152 ScopedJavaLocalRef<jobject> j_media_codec_bridge =
141 Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure); 153 Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure, false);
142 if (!j_media_codec_bridge.is_null()) { 154 if (!j_media_codec_bridge.is_null()) {
143 Java_MediaCodecBridge_release(env, j_media_codec_bridge.obj()); 155 Java_MediaCodecBridge_release(env, j_media_codec_bridge.obj());
144 return true; 156 return true;
145 } 157 }
146 return false; 158 return false;
147 } 159 }
148 160
149 // static 161 // static
150 bool MediaCodecBridge::IsKnownUnaccelerated(const std::string& mime_type) { 162 bool MediaCodecBridge::IsKnownUnaccelerated(const std::string& mime_type,
163 bool is_encoder) {
151 std::string codec_type = AndroidMimeTypeToCodecType(mime_type); 164 std::string codec_type = AndroidMimeTypeToCodecType(mime_type);
152 std::vector<media::MediaCodecBridge::CodecsInfo> codecs_info; 165 std::vector<media::MediaCodecBridge::CodecsInfo> codecs_info =
153 media::MediaCodecBridge::GetCodecsInfo(&codecs_info); 166 MediaCodecBridge::GetCodecsInfo();
154 for (size_t i = 0; i < codecs_info.size(); ++i) { 167 for (size_t i = 0; i < codecs_info.size(); ++i) {
155 if (codecs_info[i].codecs == codec_type) { 168 if (codecs_info[i].codecs == codec_type &&
169 codecs_info[i].is_encoder == is_encoder) {
156 // It would be nice if MediaCodecInfo externalized some notion of 170 // It would be nice if MediaCodecInfo externalized some notion of
157 // HW-acceleration but it doesn't. Android Media guidance is that the 171 // HW-acceleration but it doesn't. Android Media guidance is that the
158 // prefix below is always used for SW decoders, so that's what we use. 172 // prefix below is always used for SW decoders, so that's what we use.
159 return StartsWithASCII(codecs_info[i].name, "OMX.google.", true); 173 return StartsWithASCII(codecs_info[i].name, "OMX.google.", true);
160 } 174 }
161 } 175 }
162 return true; 176 return true;
163 } 177 }
164 178
165 MediaCodecBridge::MediaCodecBridge(const std::string& mime, bool is_secure) { 179 MediaCodecBridge::MediaCodecBridge(const std::string& mime,
180 bool is_secure,
181 bool is_encoder) {
166 JNIEnv* env = AttachCurrentThread(); 182 JNIEnv* env = AttachCurrentThread();
167 CHECK(env); 183 CHECK(env);
168 DCHECK(!mime.empty()); 184 DCHECK(!mime.empty());
169 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime); 185 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
170 j_media_codec_.Reset( 186 j_media_codec_.Reset(
171 Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure)); 187 Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure, is_encoder));
172 } 188 }
173 189
174 MediaCodecBridge::~MediaCodecBridge() { 190 MediaCodecBridge::~MediaCodecBridge() {
175 JNIEnv* env = AttachCurrentThread(); 191 JNIEnv* env = AttachCurrentThread();
176 CHECK(env); 192 CHECK(env);
177 if (j_media_codec_.obj()) 193 if (j_media_codec_.obj())
178 Java_MediaCodecBridge_release(env, j_media_codec_.obj()); 194 Java_MediaCodecBridge_release(env, j_media_codec_.obj());
179 } 195 }
180 196
181 bool MediaCodecBridge::StartInternal() { 197 bool MediaCodecBridge::StartInternal() {
(...skipping 14 matching lines...) Expand all
196 } 212 }
197 213
198 void MediaCodecBridge::GetOutputFormat(int* width, int* height) { 214 void MediaCodecBridge::GetOutputFormat(int* width, int* height) {
199 JNIEnv* env = AttachCurrentThread(); 215 JNIEnv* env = AttachCurrentThread();
200 216
201 *width = Java_MediaCodecBridge_getOutputWidth(env, j_media_codec_.obj()); 217 *width = Java_MediaCodecBridge_getOutputWidth(env, j_media_codec_.obj());
202 *height = Java_MediaCodecBridge_getOutputHeight(env, j_media_codec_.obj()); 218 *height = Java_MediaCodecBridge_getOutputHeight(env, j_media_codec_.obj());
203 } 219 }
204 220
205 MediaCodecStatus MediaCodecBridge::QueueInputBuffer( 221 MediaCodecStatus MediaCodecBridge::QueueInputBuffer(
206 int index, const uint8* data, int data_size, 222 int index,
223 const uint8* data,
224 int orig_data_size,
207 const base::TimeDelta& presentation_time) { 225 const base::TimeDelta& presentation_time) {
208 if (!FillInputBuffer(index, data, data_size)) 226 DVLOG(3) << "MediaCodecBridge::QueueInputBuffer: " << index << ": "
227 << orig_data_size;
228 size_t data_size = base::checked_numeric_cast<size_t>(orig_data_size);
229 if (data && !FillInputBuffer(index, data, data_size))
209 return MEDIA_CODEC_ERROR; 230 return MEDIA_CODEC_ERROR;
210 JNIEnv* env = AttachCurrentThread(); 231 JNIEnv* env = AttachCurrentThread();
211 return static_cast<MediaCodecStatus>(Java_MediaCodecBridge_queueInputBuffer( 232 return static_cast<MediaCodecStatus>(Java_MediaCodecBridge_queueInputBuffer(
212 env, j_media_codec_.obj(), 233 env, j_media_codec_.obj(),
213 index, 0, data_size, presentation_time.InMicroseconds(), 0)); 234 index, 0, data_size, presentation_time.InMicroseconds(), 0));
214 } 235 }
215 236
216 MediaCodecStatus MediaCodecBridge::QueueSecureInputBuffer( 237 MediaCodecStatus MediaCodecBridge::QueueSecureInputBuffer(
217 int index, const uint8* data, int data_size, const uint8* key_id, 238 int index,
218 int key_id_size, const uint8* iv, int iv_size, 239 const uint8* data,
219 const SubsampleEntry* subsamples, int subsamples_size, 240 int orig_data_size,
241 const uint8* key_id,
242 int key_id_size,
243 const uint8* iv,
244 int iv_size,
245 const SubsampleEntry* subsamples,
246 int subsamples_size,
220 const base::TimeDelta& presentation_time) { 247 const base::TimeDelta& presentation_time) {
221 if (!FillInputBuffer(index, data, data_size)) 248 DVLOG(3) << "MediaCodecBridge::QueueSecureInputBuffer: " << index << ": "
249 << orig_data_size;
250 size_t data_size = base::checked_numeric_cast<size_t>(orig_data_size);
251 if (data && !FillInputBuffer(index, data, data_size))
222 return MEDIA_CODEC_ERROR; 252 return MEDIA_CODEC_ERROR;
223 253
224 JNIEnv* env = AttachCurrentThread(); 254 JNIEnv* env = AttachCurrentThread();
225 ScopedJavaLocalRef<jbyteArray> j_key_id = 255 ScopedJavaLocalRef<jbyteArray> j_key_id =
226 base::android::ToJavaByteArray(env, key_id, key_id_size); 256 base::android::ToJavaByteArray(env, key_id, key_id_size);
227 ScopedJavaLocalRef<jbyteArray> j_iv = 257 ScopedJavaLocalRef<jbyteArray> j_iv =
228 base::android::ToJavaByteArray(env, iv, iv_size); 258 base::android::ToJavaByteArray(env, iv, iv_size);
229 259
230 // MediaCodec.CryptoInfo documentations says passing NULL for |clear_array| 260 // MediaCodec.CryptoInfo documentations says passing NULL for |clear_array|
231 // to indicate that all data is encrypted. But it doesn't specify what 261 // to indicate that all data is encrypted. But it doesn't specify what
(...skipping 29 matching lines...) Expand all
261 ToJavaIntArray(env, native_cypher_array.Pass(), new_subsamples_size); 291 ToJavaIntArray(env, native_cypher_array.Pass(), new_subsamples_size);
262 292
263 return static_cast<MediaCodecStatus>( 293 return static_cast<MediaCodecStatus>(
264 Java_MediaCodecBridge_queueSecureInputBuffer( 294 Java_MediaCodecBridge_queueSecureInputBuffer(
265 env, j_media_codec_.obj(), index, 0, j_iv.obj(), j_key_id.obj(), 295 env, j_media_codec_.obj(), index, 0, j_iv.obj(), j_key_id.obj(),
266 clear_array.obj(), cypher_array.obj(), new_subsamples_size, 296 clear_array.obj(), cypher_array.obj(), new_subsamples_size,
267 presentation_time.InMicroseconds())); 297 presentation_time.InMicroseconds()));
268 } 298 }
269 299
270 void MediaCodecBridge::QueueEOS(int input_buffer_index) { 300 void MediaCodecBridge::QueueEOS(int input_buffer_index) {
301 DVLOG(3) << "MediaCodecBridge::QueueEOS: " << input_buffer_index;
271 JNIEnv* env = AttachCurrentThread(); 302 JNIEnv* env = AttachCurrentThread();
272 Java_MediaCodecBridge_queueInputBuffer( 303 Java_MediaCodecBridge_queueInputBuffer(
273 env, j_media_codec_.obj(), 304 env, j_media_codec_.obj(),
274 input_buffer_index, 0, 0, 0, kBufferFlagEndOfStream); 305 input_buffer_index, 0, 0, 0, kBufferFlagEndOfStream);
275 } 306 }
276 307
277 MediaCodecStatus MediaCodecBridge::DequeueInputBuffer( 308 MediaCodecStatus MediaCodecBridge::DequeueInputBuffer(
278 const base::TimeDelta& timeout, int* index) { 309 const base::TimeDelta& timeout, int* index) {
279 JNIEnv* env = AttachCurrentThread(); 310 JNIEnv* env = AttachCurrentThread();
280 ScopedJavaLocalRef<jobject> result = Java_MediaCodecBridge_dequeueInputBuffer( 311 ScopedJavaLocalRef<jobject> result = Java_MediaCodecBridge_dequeueInputBuffer(
281 env, j_media_codec_.obj(), timeout.InMicroseconds()); 312 env, j_media_codec_.obj(), timeout.InMicroseconds());
282 *index = Java_DequeueInputResult_index(env, result.obj()); 313 *index = Java_DequeueInputResult_index(env, result.obj());
283 return static_cast<MediaCodecStatus>( 314 MediaCodecStatus status = static_cast<MediaCodecStatus>(
284 Java_DequeueInputResult_status(env, result.obj())); 315 Java_DequeueInputResult_status(env, result.obj()));
316 DVLOG(3) << "MediaCodecBridge::DequeueInputBuffer: status: " << status
317 << ", index: " << *index;
318 return status;
285 } 319 }
286 320
287 MediaCodecStatus MediaCodecBridge::DequeueOutputBuffer( 321 MediaCodecStatus MediaCodecBridge::DequeueOutputBuffer(
288 const base::TimeDelta& timeout, int* index, size_t* offset, size_t* size, 322 const base::TimeDelta& timeout,
289 base::TimeDelta* presentation_time, bool* end_of_stream) { 323 int* index,
324 size_t* offset,
325 size_t* size,
326 base::TimeDelta* presentation_time,
327 bool* end_of_stream,
328 bool* key_frame) {
290 JNIEnv* env = AttachCurrentThread(); 329 JNIEnv* env = AttachCurrentThread();
291 ScopedJavaLocalRef<jobject> result = 330 ScopedJavaLocalRef<jobject> result =
292 Java_MediaCodecBridge_dequeueOutputBuffer(env, j_media_codec_.obj(), 331 Java_MediaCodecBridge_dequeueOutputBuffer(env, j_media_codec_.obj(),
293 timeout.InMicroseconds()); 332 timeout.InMicroseconds());
294 *index = Java_DequeueOutputResult_index(env, result.obj());; 333 *index = Java_DequeueOutputResult_index(env, result.obj());;
295 *offset = base::checked_numeric_cast<size_t>( 334 *offset = base::checked_numeric_cast<size_t>(
296 Java_DequeueOutputResult_offset(env, result.obj())); 335 Java_DequeueOutputResult_offset(env, result.obj()));
297 *size = base::checked_numeric_cast<size_t>( 336 *size = base::checked_numeric_cast<size_t>(
298 Java_DequeueOutputResult_numBytes(env, result.obj())); 337 Java_DequeueOutputResult_numBytes(env, result.obj()));
299 *presentation_time = base::TimeDelta::FromMicroseconds( 338 if (presentation_time) {
300 Java_DequeueOutputResult_presentationTimeMicroseconds(env, result.obj())); 339 *presentation_time = base::TimeDelta::FromMicroseconds(
340 Java_DequeueOutputResult_presentationTimeMicroseconds(env,
341 result.obj()));
342 }
301 int flags = Java_DequeueOutputResult_flags(env, result.obj()); 343 int flags = Java_DequeueOutputResult_flags(env, result.obj());
302 *end_of_stream = flags & kBufferFlagEndOfStream; 344 if (end_of_stream)
303 return static_cast<MediaCodecStatus>( 345 *end_of_stream = flags & kBufferFlagEndOfStream;
346 if (key_frame)
347 *key_frame = flags & kBufferFlagSyncFrame;
348 MediaCodecStatus status = static_cast<MediaCodecStatus>(
304 Java_DequeueOutputResult_status(env, result.obj())); 349 Java_DequeueOutputResult_status(env, result.obj()));
350 DVLOG(3) << "MediaCodecBridge::DequeueOutputBuffer: status: " << status
351 << ", index: " << *index << ", offset: " << *offset
352 << ", size: " << *size << ", flags: " << flags;
353 return status;
305 } 354 }
306 355
307 void MediaCodecBridge::ReleaseOutputBuffer(int index, bool render) { 356 void MediaCodecBridge::ReleaseOutputBuffer(int index, bool render) {
357 DVLOG(3) << "MediaCodecBridge::ReleaseOutputBuffer: " << index;
308 JNIEnv* env = AttachCurrentThread(); 358 JNIEnv* env = AttachCurrentThread();
309 CHECK(env); 359 CHECK(env);
310 360
311 Java_MediaCodecBridge_releaseOutputBuffer( 361 Java_MediaCodecBridge_releaseOutputBuffer(
312 env, j_media_codec_.obj(), index, render); 362 env, j_media_codec_.obj(), index, render);
313 } 363 }
314 364
365 int MediaCodecBridge::GetInputBuffersCount() {
366 JNIEnv* env = AttachCurrentThread();
367 return Java_MediaCodecBridge_getInputBuffersCount(env, j_media_codec_.obj());
368 }
369
370 int MediaCodecBridge::GetOutputBuffersCount() {
371 JNIEnv* env = AttachCurrentThread();
372 return Java_MediaCodecBridge_getOutputBuffersCount(env, j_media_codec_.obj());
373 }
374
375 size_t MediaCodecBridge::GetOutputBuffersCapacity() {
376 JNIEnv* env = AttachCurrentThread();
377 return Java_MediaCodecBridge_getOutputBuffersCapacity(env,
378 j_media_codec_.obj());
379 }
380
315 bool MediaCodecBridge::GetOutputBuffers() { 381 bool MediaCodecBridge::GetOutputBuffers() {
316 JNIEnv* env = AttachCurrentThread(); 382 JNIEnv* env = AttachCurrentThread();
317 return Java_MediaCodecBridge_getOutputBuffers(env, j_media_codec_.obj()); 383 return Java_MediaCodecBridge_getOutputBuffers(env, j_media_codec_.obj());
318 } 384 }
319 385
320 bool MediaCodecBridge::FillInputBuffer(int index, const uint8* data, int size) { 386 void MediaCodecBridge::GetInputBuffer(int input_buffer_index,
387 uint8** data,
388 size_t* capacity) {
321 JNIEnv* env = AttachCurrentThread(); 389 JNIEnv* env = AttachCurrentThread();
390 ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer(
391 env, j_media_codec_.obj(), input_buffer_index));
392 *data = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj()));
393 *capacity = base::checked_numeric_cast<size_t>(
394 env->GetDirectBufferCapacity(j_buffer.obj()));
395 }
322 396
397 bool MediaCodecBridge::CopyFromOutputBuffer(int index,
398 size_t offset,
399 void* dst,
400 int dst_size) {
401 JNIEnv* env = AttachCurrentThread();
323 ScopedJavaLocalRef<jobject> j_buffer( 402 ScopedJavaLocalRef<jobject> j_buffer(
324 Java_MediaCodecBridge_getInputBuffer(env, j_media_codec_.obj(), index)); 403 Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_.obj(), index));
325 jlong capacity = env->GetDirectBufferCapacity(j_buffer.obj()); 404 void* src_data =
405 reinterpret_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj())) +
406 offset;
407 int src_capacity = env->GetDirectBufferCapacity(j_buffer.obj()) - offset;
408 if (src_capacity < dst_size)
409 return false;
410 memcpy(dst, src_data, dst_size);
411 return true;
412 }
413
414 bool MediaCodecBridge::FillInputBuffer(int index,
415 const uint8* data,
416 size_t size) {
417 uint8* dst = NULL;
418 size_t capacity = 0;
419 GetInputBuffer(index, &dst, &capacity);
420 CHECK(dst);
421
326 if (size > capacity) { 422 if (size > capacity) {
327 LOG(ERROR) << "Input buffer size " << size 423 LOG(ERROR) << "Input buffer size " << size
328 << " exceeds MediaCodec input buffer capacity: " << capacity; 424 << " exceeds MediaCodec input buffer capacity: " << capacity;
329 return false; 425 return false;
330 } 426 }
331 427
332 uint8* direct_buffer = 428 memcpy(dst, data, size);
333 static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj()));
334 memcpy(direct_buffer, data, size);
335 return true; 429 return true;
336 } 430 }
337 431
338 AudioCodecBridge::AudioCodecBridge(const std::string& mime) 432 AudioCodecBridge::AudioCodecBridge(const std::string& mime)
339 // Audio codec doesn't care about security level. 433 // Audio codec doesn't care about security level and there is no need for
340 : MediaCodecBridge(mime, false) { 434 // audio encoding yet.
341 } 435 : MediaCodecBridge(mime, false, false) {}
342 436
343 bool AudioCodecBridge::Start( 437 bool AudioCodecBridge::Start(
344 const AudioCodec& codec, int sample_rate, int channel_count, 438 const AudioCodec& codec, int sample_rate, int channel_count,
345 const uint8* extra_data, size_t extra_data_size, bool play_audio, 439 const uint8* extra_data, size_t extra_data_size, bool play_audio,
346 jobject media_crypto) { 440 jobject media_crypto) {
347 JNIEnv* env = AttachCurrentThread(); 441 JNIEnv* env = AttachCurrentThread();
348 442
349 if (!media_codec()) 443 if (!media_codec())
350 return false; 444 return false;
351 445
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 base::android::ToJavaByteArray(env, buffer, numBytes); 581 base::android::ToJavaByteArray(env, buffer, numBytes);
488 Java_MediaCodecBridge_playOutputBuffer( 582 Java_MediaCodecBridge_playOutputBuffer(
489 env, media_codec(), byte_array.obj()); 583 env, media_codec(), byte_array.obj());
490 } 584 }
491 585
492 void AudioCodecBridge::SetVolume(double volume) { 586 void AudioCodecBridge::SetVolume(double volume) {
493 JNIEnv* env = AttachCurrentThread(); 587 JNIEnv* env = AttachCurrentThread();
494 Java_MediaCodecBridge_setVolume(env, media_codec(), volume); 588 Java_MediaCodecBridge_setVolume(env, media_codec(), volume);
495 } 589 }
496 590
497 VideoCodecBridge::VideoCodecBridge(const std::string& mime, bool is_secure)
498 : MediaCodecBridge(mime, is_secure) {
499 }
500
501 bool VideoCodecBridge::Start(
502 const VideoCodec& codec, const gfx::Size& size, jobject surface,
503 jobject media_crypto) {
504 JNIEnv* env = AttachCurrentThread();
505
506 if (!media_codec())
507 return false;
508
509 std::string codec_string = VideoCodecToAndroidMimeType(codec);
510 if (codec_string.empty())
511 return false;
512
513 ScopedJavaLocalRef<jstring> j_mime =
514 ConvertUTF8ToJavaString(env, codec_string);
515 ScopedJavaLocalRef<jobject> j_format(
516 Java_MediaCodecBridge_createVideoFormat(
517 env, j_mime.obj(), size.width(), size.height()));
518 DCHECK(!j_format.is_null());
519 if (!Java_MediaCodecBridge_configureVideo(
520 env, media_codec(), j_format.obj(), surface, media_crypto, 0)) {
521 return false;
522 }
523
524 return StartInternal();
525 }
526
527 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) { 591 AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) {
528 const std::string mime = AudioCodecToAndroidMimeType(codec); 592 const std::string mime = AudioCodecToAndroidMimeType(codec);
529 return mime.empty() ? NULL : new AudioCodecBridge(mime); 593 return mime.empty() ? NULL : new AudioCodecBridge(mime);
530 } 594 }
531 595
532 // static 596 // static
533 bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) { 597 bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) {
534 return MediaCodecBridge::IsKnownUnaccelerated( 598 return MediaCodecBridge::IsKnownUnaccelerated(
535 AudioCodecToAndroidMimeType(codec)); 599 AudioCodecToAndroidMimeType(codec), false);
536 }
537
538 VideoCodecBridge* VideoCodecBridge::Create(const VideoCodec& codec,
539 bool is_secure) {
540 const std::string mime = VideoCodecToAndroidMimeType(codec);
541 return mime.empty() ? NULL : new VideoCodecBridge(mime, is_secure);
542 } 600 }
543 601
544 // static 602 // static
545 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec) { 603 bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec,
604 bool is_encoder) {
546 return MediaCodecBridge::IsKnownUnaccelerated( 605 return MediaCodecBridge::IsKnownUnaccelerated(
547 VideoCodecToAndroidMimeType(codec)); 606 VideoCodecToAndroidMimeType(codec), is_encoder);
607 }
608
609 VideoCodecBridge* VideoCodecBridge::CreateDecoder(const VideoCodec& codec,
610 bool is_secure,
611 const gfx::Size& size,
612 jobject surface,
613 jobject media_crypto) {
614 JNIEnv* env = AttachCurrentThread();
615 const std::string mime = VideoCodecToAndroidMimeType(codec);
616 if (mime.empty())
617 return NULL;
618
619 scoped_ptr<VideoCodecBridge> bridge(
620 new VideoCodecBridge(mime, is_secure, false));
621
622 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
623 ScopedJavaLocalRef<jobject> j_format(
624 Java_MediaCodecBridge_createVideoDecoderFormat(
625 env, j_mime.obj(), size.width(), size.height()));
626 DCHECK(!j_format.is_null());
627 if (!Java_MediaCodecBridge_configureVideo(env,
628 bridge->media_codec(),
629 j_format.obj(),
630 surface,
631 media_crypto,
632 0)) {
633 return NULL;
634 }
635
636 return bridge->StartInternal() ? bridge.release() : NULL;
637 }
638
639 VideoCodecBridge* VideoCodecBridge::CreateEncoder(const VideoCodec& codec,
640 const gfx::Size& size,
641 int bit_rate,
642 int frame_rate,
643 int i_frame_interval,
644 int color_format) {
645 JNIEnv* env = AttachCurrentThread();
646 const std::string mime = VideoCodecToAndroidMimeType(codec);
647 if (mime.empty())
648 return NULL;
649
650 scoped_ptr<VideoCodecBridge> bridge(new VideoCodecBridge(mime, false, true));
651
652 ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
653 ScopedJavaLocalRef<jobject> j_format(
654 Java_MediaCodecBridge_createVideoEncoderFormat(env,
655 j_mime.obj(),
656 size.width(),
657 size.height(),
658 bit_rate,
659 frame_rate,
660 i_frame_interval,
661 color_format));
662 DCHECK(!j_format.is_null());
663 if (!Java_MediaCodecBridge_configureVideo(env,
664 bridge->media_codec(),
665 j_format.obj(),
666 NULL,
667 NULL,
668 kConfigureFlagEncode)) {
669 return NULL;
670 }
671
672 return bridge->StartInternal() ? bridge.release() : NULL;
673 }
674
675 VideoCodecBridge::VideoCodecBridge(const std::string& mime,
676 bool is_secure,
677 bool is_encoder)
678 : MediaCodecBridge(mime, is_secure, is_encoder) {}
679
680 void VideoCodecBridge::SetVideoBitrate(int bps) {
681 JNIEnv* env = AttachCurrentThread();
682 Java_MediaCodecBridge_setVideoBitrate(env, media_codec(), bps);
683 }
684
685 void VideoCodecBridge::RequestKeyFrameSoon() {
686 JNIEnv* env = AttachCurrentThread();
687 Java_MediaCodecBridge_requestKeyFrameSoon(env, media_codec());
548 } 688 }
549 689
550 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { 690 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) {
551 return RegisterNativesImpl(env); 691 return RegisterNativesImpl(env);
552 } 692 }
553 693
554 } // namespace media 694 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698