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 #include "media/base/android/sdk_media_codec_bridge.h" | 5 #include "media/base/android/sdk_media_codec_bridge.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> |
8 | 9 |
9 #include "base/android/build_info.h" | 10 #include "base/android/build_info.h" |
10 #include "base/android/jni_android.h" | 11 #include "base/android/jni_android.h" |
11 #include "base/android/jni_array.h" | 12 #include "base/android/jni_array.h" |
12 #include "base/android/jni_string.h" | 13 #include "base/android/jni_string.h" |
13 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "base/numerics/safe_conversions.h" | 16 #include "base/numerics/safe_conversions.h" |
16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
17 #include "jni/MediaCodecBridge_jni.h" | 18 #include "jni/MediaCodecBridge_jni.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 } | 120 } |
120 | 121 |
121 int SdkMediaCodecBridge::GetOutputSamplingRate() { | 122 int SdkMediaCodecBridge::GetOutputSamplingRate() { |
122 JNIEnv* env = AttachCurrentThread(); | 123 JNIEnv* env = AttachCurrentThread(); |
123 | 124 |
124 return Java_MediaCodecBridge_getOutputSamplingRate(env, j_media_codec_.obj()); | 125 return Java_MediaCodecBridge_getOutputSamplingRate(env, j_media_codec_.obj()); |
125 } | 126 } |
126 | 127 |
127 MediaCodecStatus SdkMediaCodecBridge::QueueInputBuffer( | 128 MediaCodecStatus SdkMediaCodecBridge::QueueInputBuffer( |
128 int index, | 129 int index, |
129 const uint8* data, | 130 const uint8_t* data, |
130 size_t data_size, | 131 size_t data_size, |
131 const base::TimeDelta& presentation_time) { | 132 const base::TimeDelta& presentation_time) { |
132 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; | 133 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; |
133 if (data_size > base::checked_cast<size_t>(kint32max)) | 134 if (data_size > |
| 135 base::checked_cast<size_t>(std::numeric_limits<int32_t>::max())) { |
134 return MEDIA_CODEC_ERROR; | 136 return MEDIA_CODEC_ERROR; |
| 137 } |
135 if (data && !FillInputBuffer(index, data, data_size)) | 138 if (data && !FillInputBuffer(index, data, data_size)) |
136 return MEDIA_CODEC_ERROR; | 139 return MEDIA_CODEC_ERROR; |
137 JNIEnv* env = AttachCurrentThread(); | 140 JNIEnv* env = AttachCurrentThread(); |
138 return static_cast<MediaCodecStatus>(Java_MediaCodecBridge_queueInputBuffer( | 141 return static_cast<MediaCodecStatus>(Java_MediaCodecBridge_queueInputBuffer( |
139 env, j_media_codec_.obj(), index, 0, data_size, | 142 env, j_media_codec_.obj(), index, 0, data_size, |
140 presentation_time.InMicroseconds(), 0)); | 143 presentation_time.InMicroseconds(), 0)); |
141 } | 144 } |
142 | 145 |
143 // TODO(timav): Combine this and above methods together keeping only the first | 146 // TODO(timav): Combine this and above methods together keeping only the first |
144 // interface after we switch to Spitzer pipeline. | 147 // interface after we switch to Spitzer pipeline. |
145 MediaCodecStatus SdkMediaCodecBridge::QueueSecureInputBuffer( | 148 MediaCodecStatus SdkMediaCodecBridge::QueueSecureInputBuffer( |
146 int index, | 149 int index, |
147 const uint8* data, | 150 const uint8_t* data, |
148 size_t data_size, | 151 size_t data_size, |
149 const std::vector<char>& key_id, | 152 const std::vector<char>& key_id, |
150 const std::vector<char>& iv, | 153 const std::vector<char>& iv, |
151 const SubsampleEntry* subsamples, | 154 const SubsampleEntry* subsamples, |
152 int subsamples_size, | 155 int subsamples_size, |
153 const base::TimeDelta& presentation_time) { | 156 const base::TimeDelta& presentation_time) { |
154 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; | 157 DVLOG(3) << __PRETTY_FUNCTION__ << index << ": " << data_size; |
155 if (data_size > base::checked_cast<size_t>(kint32max)) | 158 if (data_size > |
| 159 base::checked_cast<size_t>(std::numeric_limits<int32_t>::max())) { |
156 return MEDIA_CODEC_ERROR; | 160 return MEDIA_CODEC_ERROR; |
| 161 } |
157 if (data && !FillInputBuffer(index, data, data_size)) | 162 if (data && !FillInputBuffer(index, data, data_size)) |
158 return MEDIA_CODEC_ERROR; | 163 return MEDIA_CODEC_ERROR; |
159 | 164 |
160 JNIEnv* env = AttachCurrentThread(); | 165 JNIEnv* env = AttachCurrentThread(); |
161 ScopedJavaLocalRef<jbyteArray> j_key_id = base::android::ToJavaByteArray( | 166 ScopedJavaLocalRef<jbyteArray> j_key_id = base::android::ToJavaByteArray( |
162 env, reinterpret_cast<const uint8*>(key_id.data()), key_id.size()); | 167 env, reinterpret_cast<const uint8_t*>(key_id.data()), key_id.size()); |
163 ScopedJavaLocalRef<jbyteArray> j_iv = base::android::ToJavaByteArray( | 168 ScopedJavaLocalRef<jbyteArray> j_iv = base::android::ToJavaByteArray( |
164 env, reinterpret_cast<const uint8*>(iv.data()), iv.size()); | 169 env, reinterpret_cast<const uint8_t*>(iv.data()), iv.size()); |
165 | 170 |
166 // MediaCodec.CryptoInfo documentations says passing NULL for |clear_array| | 171 // MediaCodec.CryptoInfo documentations says passing NULL for |clear_array| |
167 // to indicate that all data is encrypted. But it doesn't specify what | 172 // to indicate that all data is encrypted. But it doesn't specify what |
168 // |cypher_array| and |subsamples_size| should be in that case. Passing | 173 // |cypher_array| and |subsamples_size| should be in that case. Passing |
169 // one subsample here just to be on the safe side. | 174 // one subsample here just to be on the safe side. |
170 int new_subsamples_size = subsamples_size == 0 ? 1 : subsamples_size; | 175 int new_subsamples_size = subsamples_size == 0 ? 1 : subsamples_size; |
171 | 176 |
172 scoped_ptr<jint[]> native_clear_array(new jint[new_subsamples_size]); | 177 scoped_ptr<jint[]> native_clear_array(new jint[new_subsamples_size]); |
173 scoped_ptr<jint[]> native_cypher_array(new jint[new_subsamples_size]); | 178 scoped_ptr<jint[]> native_cypher_array(new jint[new_subsamples_size]); |
174 | 179 |
175 if (subsamples_size == 0) { | 180 if (subsamples_size == 0) { |
176 DCHECK(!subsamples); | 181 DCHECK(!subsamples); |
177 native_clear_array[0] = 0; | 182 native_clear_array[0] = 0; |
178 native_cypher_array[0] = data_size; | 183 native_cypher_array[0] = data_size; |
179 } else { | 184 } else { |
180 DCHECK_GT(subsamples_size, 0); | 185 DCHECK_GT(subsamples_size, 0); |
181 DCHECK(subsamples); | 186 DCHECK(subsamples); |
182 for (int i = 0; i < subsamples_size; ++i) { | 187 for (int i = 0; i < subsamples_size; ++i) { |
183 DCHECK(subsamples[i].clear_bytes <= std::numeric_limits<uint16>::max()); | 188 DCHECK(subsamples[i].clear_bytes <= std::numeric_limits<uint16_t>::max()); |
184 if (subsamples[i].cypher_bytes > | 189 if (subsamples[i].cypher_bytes > |
185 static_cast<uint32>(std::numeric_limits<jint>::max())) { | 190 static_cast<uint32_t>(std::numeric_limits<jint>::max())) { |
186 return MEDIA_CODEC_ERROR; | 191 return MEDIA_CODEC_ERROR; |
187 } | 192 } |
188 | 193 |
189 native_clear_array[i] = subsamples[i].clear_bytes; | 194 native_clear_array[i] = subsamples[i].clear_bytes; |
190 native_cypher_array[i] = subsamples[i].cypher_bytes; | 195 native_cypher_array[i] = subsamples[i].cypher_bytes; |
191 } | 196 } |
192 } | 197 } |
193 | 198 |
194 ScopedJavaLocalRef<jintArray> clear_array = | 199 ScopedJavaLocalRef<jintArray> clear_array = |
195 ToJavaIntArray(env, native_clear_array.Pass(), new_subsamples_size); | 200 ToJavaIntArray(env, native_clear_array.Pass(), new_subsamples_size); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 return Java_MediaCodecBridge_getOutputBuffersCount(env, j_media_codec_.obj()); | 279 return Java_MediaCodecBridge_getOutputBuffersCount(env, j_media_codec_.obj()); |
275 } | 280 } |
276 | 281 |
277 size_t SdkMediaCodecBridge::GetOutputBuffersCapacity() { | 282 size_t SdkMediaCodecBridge::GetOutputBuffersCapacity() { |
278 JNIEnv* env = AttachCurrentThread(); | 283 JNIEnv* env = AttachCurrentThread(); |
279 return Java_MediaCodecBridge_getOutputBuffersCapacity(env, | 284 return Java_MediaCodecBridge_getOutputBuffersCapacity(env, |
280 j_media_codec_.obj()); | 285 j_media_codec_.obj()); |
281 } | 286 } |
282 | 287 |
283 void SdkMediaCodecBridge::GetInputBuffer(int input_buffer_index, | 288 void SdkMediaCodecBridge::GetInputBuffer(int input_buffer_index, |
284 uint8** data, | 289 uint8_t** data, |
285 size_t* capacity) { | 290 size_t* capacity) { |
286 JNIEnv* env = AttachCurrentThread(); | 291 JNIEnv* env = AttachCurrentThread(); |
287 ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer( | 292 ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer( |
288 env, j_media_codec_.obj(), input_buffer_index)); | 293 env, j_media_codec_.obj(), input_buffer_index)); |
289 *data = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj())); | 294 *data = static_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj())); |
290 *capacity = | 295 *capacity = |
291 base::checked_cast<size_t>(env->GetDirectBufferCapacity(j_buffer.obj())); | 296 base::checked_cast<size_t>(env->GetDirectBufferCapacity(j_buffer.obj())); |
292 } | 297 } |
293 | 298 |
294 bool SdkMediaCodecBridge::CopyFromOutputBuffer(int index, | 299 bool SdkMediaCodecBridge::CopyFromOutputBuffer(int index, |
295 size_t offset, | 300 size_t offset, |
296 void* dst, | 301 void* dst, |
297 int dst_size) { | 302 int dst_size) { |
298 void* src_data = nullptr; | 303 void* src_data = nullptr; |
299 size_t src_capacity = GetOutputBufferAddress(index, offset, &src_data); | 304 size_t src_capacity = GetOutputBufferAddress(index, offset, &src_data); |
300 if (src_capacity < offset || | 305 if (src_capacity < offset || |
301 src_capacity - offset < static_cast<size_t>(dst_size)) { | 306 src_capacity - offset < static_cast<size_t>(dst_size)) { |
302 return false; | 307 return false; |
303 } | 308 } |
304 memcpy(dst, static_cast<uint8*>(src_data) + offset, dst_size); | 309 memcpy(dst, static_cast<uint8_t*>(src_data) + offset, dst_size); |
305 return true; | 310 return true; |
306 } | 311 } |
307 | 312 |
308 int SdkMediaCodecBridge::GetOutputBufferAddress(int index, | 313 int SdkMediaCodecBridge::GetOutputBufferAddress(int index, |
309 size_t offset, | 314 size_t offset, |
310 void** addr) { | 315 void** addr) { |
311 JNIEnv* env = AttachCurrentThread(); | 316 JNIEnv* env = AttachCurrentThread(); |
312 ScopedJavaLocalRef<jobject> j_buffer( | 317 ScopedJavaLocalRef<jobject> j_buffer( |
313 Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_.obj(), index)); | 318 Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_.obj(), index)); |
314 *addr = | 319 *addr = |
315 reinterpret_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj())) + | 320 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(j_buffer.obj())) + |
316 offset; | 321 offset; |
317 return env->GetDirectBufferCapacity(j_buffer.obj()) - offset; | 322 return env->GetDirectBufferCapacity(j_buffer.obj()) - offset; |
318 } | 323 } |
319 | 324 |
320 // static | 325 // static |
321 bool SdkMediaCodecBridge::RegisterSdkMediaCodecBridge(JNIEnv* env) { | 326 bool SdkMediaCodecBridge::RegisterSdkMediaCodecBridge(JNIEnv* env) { |
322 return RegisterNativesImpl(env); | 327 return RegisterNativesImpl(env); |
323 } | 328 } |
324 | 329 |
325 // static | 330 // static |
(...skipping 12 matching lines...) Expand all Loading... |
338 } | 343 } |
339 | 344 |
340 AudioCodecBridge::AudioCodecBridge(const std::string& mime) | 345 AudioCodecBridge::AudioCodecBridge(const std::string& mime) |
341 // Audio codec doesn't care about security level and there is no need for | 346 // Audio codec doesn't care about security level and there is no need for |
342 // audio encoding yet. | 347 // audio encoding yet. |
343 : SdkMediaCodecBridge(mime, false, MEDIA_CODEC_DECODER) {} | 348 : SdkMediaCodecBridge(mime, false, MEDIA_CODEC_DECODER) {} |
344 | 349 |
345 bool AudioCodecBridge::ConfigureAndStart(const AudioCodec& codec, | 350 bool AudioCodecBridge::ConfigureAndStart(const AudioCodec& codec, |
346 int sample_rate, | 351 int sample_rate, |
347 int channel_count, | 352 int channel_count, |
348 const uint8* extra_data, | 353 const uint8_t* extra_data, |
349 size_t extra_data_size, | 354 size_t extra_data_size, |
350 int64 codec_delay_ns, | 355 int64_t codec_delay_ns, |
351 int64 seek_preroll_ns, | 356 int64_t seek_preroll_ns, |
352 bool play_audio, | 357 bool play_audio, |
353 jobject media_crypto) { | 358 jobject media_crypto) { |
354 JNIEnv* env = AttachCurrentThread(); | 359 JNIEnv* env = AttachCurrentThread(); |
355 | 360 |
356 if (!media_codec()) | 361 if (!media_codec()) |
357 return false; | 362 return false; |
358 | 363 |
359 std::string codec_string = AudioCodecToAndroidMimeType(codec); | 364 std::string codec_string = AudioCodecToAndroidMimeType(codec); |
360 if (codec_string.empty()) | 365 if (codec_string.empty()) |
361 return false; | 366 return false; |
(...skipping 12 matching lines...) Expand all Loading... |
374 if (!Java_MediaCodecBridge_configureAudio(env, media_codec(), j_format.obj(), | 379 if (!Java_MediaCodecBridge_configureAudio(env, media_codec(), j_format.obj(), |
375 media_crypto, 0, play_audio)) { | 380 media_crypto, 0, play_audio)) { |
376 return false; | 381 return false; |
377 } | 382 } |
378 | 383 |
379 return Start(); | 384 return Start(); |
380 } | 385 } |
381 | 386 |
382 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format, | 387 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format, |
383 const AudioCodec& codec, | 388 const AudioCodec& codec, |
384 const uint8* extra_data, | 389 const uint8_t* extra_data, |
385 size_t extra_data_size, | 390 size_t extra_data_size, |
386 int64 codec_delay_ns, | 391 int64_t codec_delay_ns, |
387 int64 seek_preroll_ns) { | 392 int64_t seek_preroll_ns) { |
388 if (extra_data_size == 0 && codec != kCodecOpus) | 393 if (extra_data_size == 0 && codec != kCodecOpus) |
389 return true; | 394 return true; |
390 | 395 |
391 JNIEnv* env = AttachCurrentThread(); | 396 JNIEnv* env = AttachCurrentThread(); |
392 switch (codec) { | 397 switch (codec) { |
393 case kCodecVorbis: { | 398 case kCodecVorbis: { |
394 if (extra_data[0] != 2) { | 399 if (extra_data[0] != 2) { |
395 LOG(ERROR) << "Invalid number of vorbis headers before the codec " | 400 LOG(ERROR) << "Invalid number of vorbis headers before the codec " |
396 << "header: " << extra_data[0]; | 401 << "header: " << extra_data[0]; |
397 return false; | 402 return false; |
398 } | 403 } |
399 | 404 |
400 size_t header_length[2]; | 405 size_t header_length[2]; |
401 // |total_length| keeps track of the total number of bytes before the last | 406 // |total_length| keeps track of the total number of bytes before the last |
402 // header. | 407 // header. |
403 size_t total_length = 1; | 408 size_t total_length = 1; |
404 const uint8* current_pos = extra_data; | 409 const uint8_t* current_pos = extra_data; |
405 // Calculate the length of the first 2 headers. | 410 // Calculate the length of the first 2 headers. |
406 for (int i = 0; i < 2; ++i) { | 411 for (int i = 0; i < 2; ++i) { |
407 header_length[i] = 0; | 412 header_length[i] = 0; |
408 while (total_length < extra_data_size) { | 413 while (total_length < extra_data_size) { |
409 size_t size = *(++current_pos); | 414 size_t size = *(++current_pos); |
410 total_length += 1 + size; | 415 total_length += 1 + size; |
411 if (total_length > 0x80000000) { | 416 if (total_length > 0x80000000) { |
412 LOG(ERROR) << "Vorbis header size too large"; | 417 LOG(ERROR) << "Vorbis header size too large"; |
413 return false; | 418 return false; |
414 } | 419 } |
(...skipping 18 matching lines...) Expand all Loading... |
433 extra_data_size - total_length); | 438 extra_data_size - total_length); |
434 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, | 439 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, |
435 last_header.obj()); | 440 last_header.obj()); |
436 break; | 441 break; |
437 } | 442 } |
438 case kCodecAAC: { | 443 case kCodecAAC: { |
439 media::BitReader reader(extra_data, extra_data_size); | 444 media::BitReader reader(extra_data, extra_data_size); |
440 | 445 |
441 // The following code is copied from aac.cc | 446 // The following code is copied from aac.cc |
442 // TODO(qinmin): refactor the code in aac.cc to make it more reusable. | 447 // TODO(qinmin): refactor the code in aac.cc to make it more reusable. |
443 uint8 profile = 0; | 448 uint8_t profile = 0; |
444 uint8 frequency_index = 0; | 449 uint8_t frequency_index = 0; |
445 uint8 channel_config = 0; | 450 uint8_t channel_config = 0; |
446 RETURN_ON_ERROR(reader.ReadBits(5, &profile)); | 451 RETURN_ON_ERROR(reader.ReadBits(5, &profile)); |
447 RETURN_ON_ERROR(reader.ReadBits(4, &frequency_index)); | 452 RETURN_ON_ERROR(reader.ReadBits(4, &frequency_index)); |
448 | 453 |
449 if (0xf == frequency_index) | 454 if (0xf == frequency_index) |
450 RETURN_ON_ERROR(reader.SkipBits(24)); | 455 RETURN_ON_ERROR(reader.SkipBits(24)); |
451 RETURN_ON_ERROR(reader.ReadBits(4, &channel_config)); | 456 RETURN_ON_ERROR(reader.ReadBits(4, &channel_config)); |
452 | 457 |
453 if (profile == 5 || profile == 29) { | 458 if (profile == 5 || profile == 29) { |
454 // Read extension config. | 459 // Read extension config. |
455 RETURN_ON_ERROR(reader.ReadBits(4, &frequency_index)); | 460 RETURN_ON_ERROR(reader.ReadBits(4, &frequency_index)); |
456 if (frequency_index == 0xf) | 461 if (frequency_index == 0xf) |
457 RETURN_ON_ERROR(reader.SkipBits(24)); | 462 RETURN_ON_ERROR(reader.SkipBits(24)); |
458 RETURN_ON_ERROR(reader.ReadBits(5, &profile)); | 463 RETURN_ON_ERROR(reader.ReadBits(5, &profile)); |
459 } | 464 } |
460 | 465 |
461 if (profile < 1 || profile > 4 || frequency_index == 0xf || | 466 if (profile < 1 || profile > 4 || frequency_index == 0xf || |
462 channel_config > 7) { | 467 channel_config > 7) { |
463 LOG(ERROR) << "Invalid AAC header"; | 468 LOG(ERROR) << "Invalid AAC header"; |
464 return false; | 469 return false; |
465 } | 470 } |
466 const size_t kCsdLength = 2; | 471 const size_t kCsdLength = 2; |
467 uint8 csd[kCsdLength]; | 472 uint8_t csd[kCsdLength]; |
468 csd[0] = profile << 3 | frequency_index >> 1; | 473 csd[0] = profile << 3 | frequency_index >> 1; |
469 csd[1] = (frequency_index & 0x01) << 7 | channel_config << 3; | 474 csd[1] = (frequency_index & 0x01) << 7 | channel_config << 3; |
470 ScopedJavaLocalRef<jbyteArray> byte_array = | 475 ScopedJavaLocalRef<jbyteArray> byte_array = |
471 base::android::ToJavaByteArray(env, csd, kCsdLength); | 476 base::android::ToJavaByteArray(env, csd, kCsdLength); |
472 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, | 477 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, |
473 byte_array.obj()); | 478 byte_array.obj()); |
474 | 479 |
475 // TODO(qinmin): pass an extra variable to this function to determine | 480 // TODO(qinmin): pass an extra variable to this function to determine |
476 // whether we need to call this. | 481 // whether we need to call this. |
477 Java_MediaCodecBridge_setFrameHasADTSHeader(env, j_format); | 482 Java_MediaCodecBridge_setFrameHasADTSHeader(env, j_format); |
478 break; | 483 break; |
479 } | 484 } |
480 case kCodecOpus: { | 485 case kCodecOpus: { |
481 if (!extra_data || extra_data_size == 0 || codec_delay_ns < 0 || | 486 if (!extra_data || extra_data_size == 0 || codec_delay_ns < 0 || |
482 seek_preroll_ns < 0) { | 487 seek_preroll_ns < 0) { |
483 LOG(ERROR) << "Invalid Opus Header"; | 488 LOG(ERROR) << "Invalid Opus Header"; |
484 return false; | 489 return false; |
485 } | 490 } |
486 | 491 |
487 // csd0 - Opus Header | 492 // csd0 - Opus Header |
488 ScopedJavaLocalRef<jbyteArray> csd0 = | 493 ScopedJavaLocalRef<jbyteArray> csd0 = |
489 base::android::ToJavaByteArray(env, extra_data, extra_data_size); | 494 base::android::ToJavaByteArray(env, extra_data, extra_data_size); |
490 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, csd0.obj()); | 495 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, csd0.obj()); |
491 | 496 |
492 // csd1 - Codec Delay | 497 // csd1 - Codec Delay |
493 ScopedJavaLocalRef<jbyteArray> csd1 = base::android::ToJavaByteArray( | 498 ScopedJavaLocalRef<jbyteArray> csd1 = base::android::ToJavaByteArray( |
494 env, reinterpret_cast<const uint8*>(&codec_delay_ns), | 499 env, reinterpret_cast<const uint8_t*>(&codec_delay_ns), |
495 sizeof(int64_t)); | 500 sizeof(int64_t)); |
496 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, csd1.obj()); | 501 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, csd1.obj()); |
497 | 502 |
498 // csd2 - Seek Preroll | 503 // csd2 - Seek Preroll |
499 ScopedJavaLocalRef<jbyteArray> csd2 = base::android::ToJavaByteArray( | 504 ScopedJavaLocalRef<jbyteArray> csd2 = base::android::ToJavaByteArray( |
500 env, reinterpret_cast<const uint8*>(&seek_preroll_ns), | 505 env, reinterpret_cast<const uint8_t*>(&seek_preroll_ns), |
501 sizeof(int64_t)); | 506 sizeof(int64_t)); |
502 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 2, csd2.obj()); | 507 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 2, csd2.obj()); |
503 break; | 508 break; |
504 } | 509 } |
505 default: | 510 default: |
506 LOG(ERROR) << "Invalid header encountered for codec: " | 511 LOG(ERROR) << "Invalid header encountered for codec: " |
507 << AudioCodecToAndroidMimeType(codec); | 512 << AudioCodecToAndroidMimeType(codec); |
508 return false; | 513 return false; |
509 } | 514 } |
510 return true; | 515 return true; |
511 } | 516 } |
512 | 517 |
513 int64 AudioCodecBridge::PlayOutputBuffer(int index, | 518 int64_t AudioCodecBridge::PlayOutputBuffer(int index, |
514 size_t size, | 519 size_t size, |
515 size_t offset, | 520 size_t offset, |
516 bool postpone) { | 521 bool postpone) { |
517 DCHECK_LE(0, index); | 522 DCHECK_LE(0, index); |
518 int numBytes = base::checked_cast<int>(size); | 523 int numBytes = base::checked_cast<int>(size); |
519 | 524 |
520 void* buffer = nullptr; | 525 void* buffer = nullptr; |
521 int capacity = GetOutputBufferAddress(index, offset, &buffer); | 526 int capacity = GetOutputBufferAddress(index, offset, &buffer); |
522 numBytes = std::min(capacity, numBytes); | 527 numBytes = std::min(capacity, numBytes); |
523 CHECK_GE(numBytes, 0); | 528 CHECK_GE(numBytes, 0); |
524 | 529 |
525 JNIEnv* env = AttachCurrentThread(); | 530 JNIEnv* env = AttachCurrentThread(); |
526 ScopedJavaLocalRef<jbyteArray> byte_array = base::android::ToJavaByteArray( | 531 ScopedJavaLocalRef<jbyteArray> byte_array = base::android::ToJavaByteArray( |
527 env, static_cast<uint8*>(buffer), numBytes); | 532 env, static_cast<uint8_t*>(buffer), numBytes); |
528 return Java_MediaCodecBridge_playOutputBuffer(env, media_codec(), | 533 return Java_MediaCodecBridge_playOutputBuffer(env, media_codec(), |
529 byte_array.obj(), postpone); | 534 byte_array.obj(), postpone); |
530 } | 535 } |
531 | 536 |
532 void AudioCodecBridge::SetVolume(double volume) { | 537 void AudioCodecBridge::SetVolume(double volume) { |
533 JNIEnv* env = AttachCurrentThread(); | 538 JNIEnv* env = AttachCurrentThread(); |
534 Java_MediaCodecBridge_setVolume(env, media_codec(), volume); | 539 Java_MediaCodecBridge_setVolume(env, media_codec(), volume); |
535 } | 540 } |
536 | 541 |
537 // static | 542 // static |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 if (adaptive_playback_supported_for_testing_ == 0) | 634 if (adaptive_playback_supported_for_testing_ == 0) |
630 return false; | 635 return false; |
631 else if (adaptive_playback_supported_for_testing_ > 0) | 636 else if (adaptive_playback_supported_for_testing_ > 0) |
632 return true; | 637 return true; |
633 JNIEnv* env = AttachCurrentThread(); | 638 JNIEnv* env = AttachCurrentThread(); |
634 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), | 639 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(env, media_codec(), |
635 width, height); | 640 width, height); |
636 } | 641 } |
637 | 642 |
638 } // namespace media | 643 } // namespace media |
OLD | NEW |