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

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: rebase Created 5 years, 10 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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 AudioCodecBridge::AudioCodecBridge(const std::string& mime) 524 AudioCodecBridge::AudioCodecBridge(const std::string& mime)
519 // Audio codec doesn't care about security level and there is no need for 525 // Audio codec doesn't care about security level and there is no need for
520 // audio encoding yet. 526 // audio encoding yet.
521 : MediaCodecBridge(mime, false, MEDIA_CODEC_DECODER) {} 527 : MediaCodecBridge(mime, false, MEDIA_CODEC_DECODER) {}
522 528
523 bool AudioCodecBridge::Start(const AudioCodec& codec, 529 bool AudioCodecBridge::Start(const AudioCodec& codec,
524 int sample_rate, 530 int sample_rate,
525 int channel_count, 531 int channel_count,
526 const uint8* extra_data, 532 const uint8* extra_data,
527 size_t extra_data_size, 533 size_t extra_data_size,
534 int64 codec_delay_ns,
535 int64 seek_preroll_ns,
528 bool play_audio, 536 bool play_audio,
529 jobject media_crypto) { 537 jobject media_crypto) {
530 JNIEnv* env = AttachCurrentThread(); 538 JNIEnv* env = AttachCurrentThread();
531 539
532 if (!media_codec()) 540 if (!media_codec())
533 return false; 541 return false;
534 542
535 std::string codec_string = AudioCodecToAndroidMimeType(codec); 543 std::string codec_string = AudioCodecToAndroidMimeType(codec);
536 if (codec_string.empty()) 544 if (codec_string.empty())
537 return false; 545 return false;
538 546
539 ScopedJavaLocalRef<jstring> j_mime = 547 ScopedJavaLocalRef<jstring> j_mime =
540 ConvertUTF8ToJavaString(env, codec_string); 548 ConvertUTF8ToJavaString(env, codec_string);
541 ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat( 549 ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat(
542 env, j_mime.obj(), sample_rate, channel_count)); 550 env, j_mime.obj(), sample_rate, channel_count));
543 DCHECK(!j_format.is_null()); 551 DCHECK(!j_format.is_null());
544 552
545 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size)) 553 if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size,
554 codec_delay_ns, seek_preroll_ns)) {
546 return false; 555 return false;
556 }
547 557
548 if (!Java_MediaCodecBridge_configureAudio( 558 if (!Java_MediaCodecBridge_configureAudio(
549 env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) { 559 env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) {
550 return false; 560 return false;
551 } 561 }
552 562
553 return StartInternal(); 563 return StartInternal();
554 } 564 }
555 565
556 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format, 566 bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format,
557 const AudioCodec& codec, 567 const AudioCodec& codec,
558 const uint8* extra_data, 568 const uint8* extra_data,
559 size_t extra_data_size) { 569 size_t extra_data_size,
560 if (extra_data_size == 0) 570 int64 codec_delay_ns,
571 int64 seek_preroll_ns) {
572 if (extra_data_size == 0 && codec != kCodecOpus)
561 return true; 573 return true;
562 574
563 JNIEnv* env = AttachCurrentThread(); 575 JNIEnv* env = AttachCurrentThread();
564 switch (codec) { 576 switch (codec) {
565 case kCodecVorbis: { 577 case kCodecVorbis: {
566 if (extra_data[0] != 2) { 578 if (extra_data[0] != 2) {
567 LOG(ERROR) << "Invalid number of vorbis headers before the codec " 579 LOG(ERROR) << "Invalid number of vorbis headers before the codec "
568 << "header: " << extra_data[0]; 580 << "header: " << extra_data[0];
569 return false; 581 return false;
570 } 582 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 ScopedJavaLocalRef<jbyteArray> byte_array = 653 ScopedJavaLocalRef<jbyteArray> byte_array =
642 base::android::ToJavaByteArray(env, csd, kCsdLength); 654 base::android::ToJavaByteArray(env, csd, kCsdLength);
643 Java_MediaCodecBridge_setCodecSpecificData( 655 Java_MediaCodecBridge_setCodecSpecificData(
644 env, j_format, 0, byte_array.obj()); 656 env, j_format, 0, byte_array.obj());
645 657
646 // TODO(qinmin): pass an extra variable to this function to determine 658 // TODO(qinmin): pass an extra variable to this function to determine
647 // whether we need to call this. 659 // whether we need to call this.
648 Java_MediaCodecBridge_setFrameHasADTSHeader(env, j_format); 660 Java_MediaCodecBridge_setFrameHasADTSHeader(env, j_format);
649 break; 661 break;
650 } 662 }
663 case kCodecOpus: {
664 if (!extra_data || extra_data_size == 0 ||
665 codec_delay_ns < 0 || seek_preroll_ns < 0) {
666 LOG(ERROR) << "Invalid Opus Header";
667 return false;
668 }
669
670 // csd0 - Opus Header
671 ScopedJavaLocalRef<jbyteArray> csd0 =
672 base::android::ToJavaByteArray(env, extra_data, extra_data_size);
673 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 0, csd0.obj());
674
675 // csd1 - Codec Delay
676 ScopedJavaLocalRef<jbyteArray> csd1 =
677 base::android::ToJavaByteArray(
678 env, reinterpret_cast<const uint8*>(&codec_delay_ns),
679 sizeof(int64_t));
680 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 1, csd1.obj());
681
682 // csd2 - Seek Preroll
683 ScopedJavaLocalRef<jbyteArray> csd2 =
684 base::android::ToJavaByteArray(
685 env, reinterpret_cast<const uint8*>(&seek_preroll_ns),
686 sizeof(int64_t));
687 Java_MediaCodecBridge_setCodecSpecificData(env, j_format, 2, csd2.obj());
688 break;
689 }
651 default: 690 default:
652 LOG(ERROR) << "Invalid header encountered for codec: " 691 LOG(ERROR) << "Invalid header encountered for codec: "
653 << AudioCodecToAndroidMimeType(codec); 692 << AudioCodecToAndroidMimeType(codec);
654 return false; 693 return false;
655 } 694 }
656 return true; 695 return true;
657 } 696 }
658 697
659 int64 AudioCodecBridge::PlayOutputBuffer(int index, size_t size) { 698 int64 AudioCodecBridge::PlayOutputBuffer(int index, size_t size) {
660 DCHECK_LE(0, index); 699 DCHECK_LE(0, index);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 JNIEnv* env = AttachCurrentThread(); 839 JNIEnv* env = AttachCurrentThread();
801 return Java_MediaCodecBridge_isAdaptivePlaybackSupported( 840 return Java_MediaCodecBridge_isAdaptivePlaybackSupported(
802 env, media_codec(), width, height); 841 env, media_codec(), width, height);
803 } 842 }
804 843
805 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { 844 bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) {
806 return RegisterNativesImpl(env); 845 return RegisterNativesImpl(env);
807 } 846 }
808 847
809 } // namespace media 848 } // 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