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

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

Issue 866573004: media: Enable Opus support in Clank <video> and MSE (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nit fixes Created 5 years, 11 months 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
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 23 matching lines...) Expand all
34 kBufferFlagEndOfStream = 4, // BUFFER_FLAG_END_OF_STREAM 34 kBufferFlagEndOfStream = 4, // BUFFER_FLAG_END_OF_STREAM
35 kConfigureFlagEncode = 1, // CONFIGURE_FLAG_ENCODE 35 kConfigureFlagEncode = 1, // CONFIGURE_FLAG_ENCODE
36 }; 36 };
37 37
38 static const std::string AudioCodecToAndroidMimeType(const AudioCodec& codec) { 38 static const std::string AudioCodecToAndroidMimeType(const AudioCodec& codec) {
39 switch (codec) { 39 switch (codec) {
40 case kCodecMP3: 40 case kCodecMP3:
41 return "audio/mpeg"; 41 return "audio/mpeg";
42 case kCodecVorbis: 42 case kCodecVorbis:
43 return "audio/vorbis"; 43 return "audio/vorbis";
44 case kCodecOpus:
45 return "audio/opus";
44 case kCodecAAC: 46 case kCodecAAC:
45 return "audio/mp4a-latm"; 47 return "audio/mp4a-latm";
46 default: 48 default:
47 return std::string(); 49 return std::string();
48 } 50 }
49 } 51 }
50 52
51 static const std::string VideoCodecToAndroidMimeType(const VideoCodec& codec) { 53 static const std::string VideoCodecToAndroidMimeType(const VideoCodec& codec) {
52 switch (codec) { 54 switch (codec) {
53 case kCodecH264: 55 case kCodecH264:
(...skipping 12 matching lines...) Expand all
66 if (codec == "avc1") 68 if (codec == "avc1")
67 return "video/avc"; 69 return "video/avc";
68 if (codec == "mp4a") 70 if (codec == "mp4a")
69 return "audio/mp4a-latm"; 71 return "audio/mp4a-latm";
70 if (codec == "vp8" || codec == "vp8.0") 72 if (codec == "vp8" || codec == "vp8.0")
71 return "video/x-vnd.on2.vp8"; 73 return "video/x-vnd.on2.vp8";
72 if (codec == "vp9" || codec == "vp9.0") 74 if (codec == "vp9" || codec == "vp9.0")
73 return "video/x-vnd.on2.vp9"; 75 return "video/x-vnd.on2.vp9";
74 if (codec == "vorbis") 76 if (codec == "vorbis")
75 return "audio/vorbis"; 77 return "audio/vorbis";
78 if (codec == "opus")
79 return "audio/opus";
76 return std::string(); 80 return std::string();
77 } 81 }
78 82
79 // TODO(qinmin): using a map to help all the conversions in this class. 83 // TODO(qinmin): using a map to help all the conversions in this class.
80 static const std::string AndroidMimeTypeToCodecType(const std::string& mime) { 84 static const std::string AndroidMimeTypeToCodecType(const std::string& mime) {
81 if (mime == "video/mp4v-es") 85 if (mime == "video/mp4v-es")
82 return "mp4v"; 86 return "mp4v";
83 if (mime == "video/avc") 87 if (mime == "video/avc")
84 return "avc1"; 88 return "avc1";
85 if (mime == "video/x-vnd.on2.vp8") 89 if (mime == "video/x-vnd.on2.vp8")
86 return "vp8"; 90 return "vp8";
87 if (mime == "video/x-vnd.on2.vp9") 91 if (mime == "video/x-vnd.on2.vp9")
88 return "vp9"; 92 return "vp9";
89 if (mime == "audio/mp4a-latm") 93 if (mime == "audio/mp4a-latm")
90 return "mp4a"; 94 return "mp4a";
91 if (mime == "audio/mpeg") 95 if (mime == "audio/mpeg")
92 return "mp3"; 96 return "mp3";
93 if (mime == "audio/vorbis") 97 if (mime == "audio/vorbis")
94 return "vorbis"; 98 return "vorbis";
99 if (mime == "audio/opus")
100 return "opus";
95 return std::string(); 101 return std::string();
96 } 102 }
97 103
98 static ScopedJavaLocalRef<jintArray> 104 static ScopedJavaLocalRef<jintArray>
99 ToJavaIntArray(JNIEnv* env, scoped_ptr<jint[]> native_array, int size) { 105 ToJavaIntArray(JNIEnv* env, scoped_ptr<jint[]> native_array, int size) {
100 ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size)); 106 ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size));
101 env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get()); 107 env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get());
102 return j_array; 108 return j_array;
103 } 109 }
104 110
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 AudioCodecBridge::AudioCodecBridge(const std::string& mime) 514 AudioCodecBridge::AudioCodecBridge(const std::string& mime)
509 // Audio codec doesn't care about security level and there is no need for 515 // Audio codec doesn't care about security level and there is no need for
510 // audio encoding yet. 516 // audio encoding yet.
511 : MediaCodecBridge(mime, false, MEDIA_CODEC_DECODER) {} 517 : MediaCodecBridge(mime, false, MEDIA_CODEC_DECODER) {}
512 518
513 bool AudioCodecBridge::Start(const AudioCodec& codec, 519 bool AudioCodecBridge::Start(const AudioCodec& codec,
514 int sample_rate, 520 int sample_rate,
515 int channel_count, 521 int channel_count,
516 const uint8* extra_data, 522 const uint8* extra_data,
517 size_t extra_data_size, 523 size_t extra_data_size,
524 int64 codec_delay_ns,
525 int64 seek_preroll_ns,
518 bool play_audio, 526 bool play_audio,
519 jobject media_crypto) { 527 jobject media_crypto) {
520 JNIEnv* env = AttachCurrentThread(); 528 JNIEnv* env = AttachCurrentThread();
521 529
522 if (!media_codec()) 530 if (!media_codec())
523 return false; 531 return false;
524 532
525 std::string codec_string = AudioCodecToAndroidMimeType(codec); 533 std::string codec_string = AudioCodecToAndroidMimeType(codec);
526 if (codec_string.empty()) 534 if (codec_string.empty())
527 return false; 535 return false;
528 536
529 ScopedJavaLocalRef<jstring> j_mime = 537 ScopedJavaLocalRef<jstring> j_mime =
530 ConvertUTF8ToJavaString(env, codec_string); 538 ConvertUTF8ToJavaString(env, codec_string);
531 ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat( 539 ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat(
532 env, j_mime.obj(), sample_rate, channel_count)); 540 env, j_mime.obj(), sample_rate, channel_count));
533 DCHECK(!j_format.is_null()); 541 DCHECK(!j_format.is_null());
534 542
535 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size)) 543 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size,
544 codec_delay_ns, seek_preroll_ns)) {
536 return false; 545 return false;
546 }
537 547
538 if (!Java_MediaCodecBridge_configureAudio( 548 if (!Java_MediaCodecBridge_configureAudio(
539 env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) { 549 env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) {
540 return false; 550 return false;
541 } 551 }
542 552
543 return StartInternal(); 553 return StartInternal();
544 } 554 }
545 555
546 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format, 556 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format,
547 const AudioCodec& codec, 557 const AudioCodec& codec,
548 const uint8* extra_data, 558 const uint8* extra_data,
549 size_t extra_data_size) { 559 size_t extra_data_size,
560 int64 codec_delay_ns,
561 int64 seek_preroll_ns) {
550 if (extra_data_size == 0) 562 if (extra_data_size == 0)
wolenetz 2015/01/22 22:06:22 Might it ever be valid to configure opus with 0 ex
vignesh 2015/01/22 22:48:42 Opus always need extra data from the headers. I ha
wolenetz 2015/01/22 23:01:06 Acknowledged.
551 return true; 563 return true;
552 564
553 JNIEnv* env = AttachCurrentThread(); 565 JNIEnv* env = AttachCurrentThread();
554 switch (codec) { 566 switch (codec) {
555 case kCodecVorbis: { 567 case kCodecVorbis: {
556 if (extra_data[0] != 2) { 568 if (extra_data[0] != 2) {
557 LOG(ERROR) << "Invalid number of vorbis headers before the codec " 569 LOG(ERROR) << "Invalid number of vorbis headers before the codec "
558 << "header: " << extra_data[0]; 570 << "header: " << extra_data[0];
559 return false; 571 return false;
560 } 572 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 ScopedJavaLocalRef<jbyteArray> byte_array = 643 ScopedJavaLocalRef<jbyteArray> byte_array =
632 base::android::ToJavaByteArray(env, csd, kCsdLength); 644 base::android::ToJavaByteArray(env, csd, kCsdLength);
633 Java_MediaCodecBridge_setCodecSpecificData( 645 Java_MediaCodecBridge_setCodecSpecificData(
634 env, j_format, 0, byte_array.obj()); 646 env, j_format, 0, byte_array.obj());
635 647
636 // TODO(qinmin): pass an extra variable to this function to determine 648 // TODO(qinmin): pass an extra variable to this function to determine
637 // whether we need to call this. 649 // whether we need to call this.
638 Java_MediaCodecBridge_setFrameHasADTSHeader(env, j_format); 650 Java_MediaCodecBridge_setFrameHasADTSHeader(env, j_format);
639 break; 651 break;
640 } 652 }
653 case kCodecOpus: {
654 if (codec_delay_ns < 0 || seek_preroll_ns < 0) {
wolenetz 2015/01/22 22:06:22 nit: default DemuxerConfig initializer values for
vignesh 2015/01/22 22:48:42 Done.
655 LOG(ERROR) << "Invalid Opus Header";
656 return false;
657 }
658
659 // csd0 - Opus Header
660 ScopedJavaLocalRef<jbyteArray> csd0 =
661 base::android::ToJavaByteArray(env, extra_data, extra_data_size);
662 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, csd0.obj());
663
664 // csd1 - Codec Delay
665 ScopedJavaLocalRef<jbyteArray> csd1 =
666 base::android::ToJavaByteArray(
667 env, reinterpret_cast<const uint8*>(&codec_delay_ns),
668 sizeof(int64_t));
669 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, csd1.obj());
670
671 // csd2 - Seek Preroll
672 ScopedJavaLocalRef<jbyteArray> csd2 =
673 base::android::ToJavaByteArray(
674 env, reinterpret_cast<const uint8*>(&seek_preroll_ns),
675 sizeof(int64_t));
676 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 2, csd1.obj());
wolenetz 2015/01/22 22:06:22 hmm. this looks wrong. should it instead be sendin
vignesh 2015/01/22 22:48:42 Whoops. Any idea how i can add a test for this? S
wolenetz 2015/01/22 23:01:06 I guess you could add a mediasourceplayertest that
677 break;
678 }
641 default: 679 default:
642 LOG(ERROR) << "Invalid header encountered for codec: " 680 LOG(ERROR) << "Invalid header encountered for codec: "
643 << AudioCodecToAndroidMimeType(codec); 681 << AudioCodecToAndroidMimeType(codec);
644 return false; 682 return false;
645 } 683 }
646 return true; 684 return true;
647 } 685 }
648 686
649 int64 AudioCodecBridge::PlayOutputBuffer(int index, size_t size) { 687 int64 AudioCodecBridge::PlayOutputBuffer(int index, size_t size) {
650 DCHECK_LE(0, index); 688 DCHECK_LE(0, index);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 JNIEnv* env = AttachCurrentThread(); 828 JNIEnv* env = AttachCurrentThread();
791 return Java_MediaCodecBridge_isAdaptivePlaybackSupported( 829 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(
792 env, media_codec(), width, height); 830 env, media_codec(), width, height);
793 } 831 }
794 832
795 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { 833 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) {
796 return RegisterNativesImpl(env); 834 return RegisterNativesImpl(env);
797 } 835 }
798 836
799 } // namespace media 837 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_codec_bridge.h ('k') | media/base/android/media_codec_bridge_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698