diff options
author | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-26 02:04:19 +0000 |
---|---|---|
committer | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-26 02:04:19 +0000 |
commit | 31203376861a403af9e92810d03c453ad01b8f57 (patch) | |
tree | 49a81216b8f47c689479538984ae4b4c822c3786 /media | |
parent | 20c8b942168996a3f0345c9341dc4fa6e99f3a36 (diff) | |
download | chromium_src-31203376861a403af9e92810d03c453ad01b8f57.zip chromium_src-31203376861a403af9e92810d03c453ad01b8f57.tar.gz chromium_src-31203376861a403af9e92810d03c453ad01b8f57.tar.bz2 |
Add Create() function to AudioCodecBridge and VideoCodecBridge to allow return of null pointers
If codec is not supported, we should allow null pointers to be returned when trying to create a MediaCodecBridge.
BUG=233420
Review URL: https://chromiumcodereview.appspot.com/14932020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202323 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/android/java/src/org/chromium/media/MediaCodecBridge.java | 32 | ||||
-rw-r--r-- | media/base/android/media_codec_bridge.cc | 77 | ||||
-rw-r--r-- | media/base/android/media_codec_bridge.h | 16 | ||||
-rw-r--r-- | media/base/android/media_codec_bridge_unittest.cc | 11 | ||||
-rw-r--r-- | media/base/android/media_jni_registrar.cc | 3 | ||||
-rw-r--r-- | media/base/android/media_source_player.cc | 4 | ||||
-rw-r--r-- | media/media.gyp | 1 |
7 files changed, 83 insertions, 61 deletions
diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java index 9e7894c..13b9334 100644 --- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java @@ -111,8 +111,13 @@ class MediaCodecBridge { } @CalledByNative - private MediaFormat getOutputFormat() { - return mMediaCodec.getOutputFormat(); + private int getOutputHeight() { + return mMediaCodec.getOutputFormat().getInteger(MediaFormat.KEY_HEIGHT); + } + + @CalledByNative + private int getOutputWidth() { + return mMediaCodec.getOutputFormat().getInteger(MediaFormat.KEY_WIDTH); } @CalledByNative @@ -156,6 +161,29 @@ class MediaCodecBridge { } @CalledByNative + private static MediaFormat createAudioFormat(String mime, int SampleRate, int ChannelCount) { + return MediaFormat.createAudioFormat(mime, SampleRate, ChannelCount); + } + + @CalledByNative + private static MediaFormat createVideoFormat(String mime, int width, int height) { + return MediaFormat.createVideoFormat(mime, width, height); + } + + @CalledByNative + private static void setCodecSpecificData(MediaFormat format, int index, ByteBuffer bytes) { + String name = null; + if (index == 0) { + name = "csd-0"; + } else if (index == 1) { + name = "csd-1"; + } + if (name != null) { + format.setByteBuffer(name, bytes); + } + } + + @CalledByNative private void configureAudio(MediaFormat format, MediaCrypto crypto, int flags, boolean playAudio) { mMediaCodec.configure(format, null, crypto, flags); diff --git a/media/base/android/media_codec_bridge.cc b/media/base/android/media_codec_bridge.cc index 37949f4..2587fc4 100644 --- a/media/base/android/media_codec_bridge.cc +++ b/media/base/android/media_codec_bridge.cc @@ -17,36 +17,11 @@ #include "base/stringprintf.h" #include "jni/MediaCodecBridge_jni.h" -#include "jni/MediaFormat_jni.h" using base::android::AttachCurrentThread; using base::android::ConvertUTF8ToJavaString; using base::android::ScopedJavaLocalRef; -namespace { - -class MediaCodecNativeRegisterer { - public: - MediaCodecNativeRegisterer() { - JNIEnv* env = AttachCurrentThread(); - jni_initialized_ = - media::RegisterNativesImpl(env) && - JNI_MediaFormat::RegisterNativesImpl(env); - } - - bool IsRegistered() { - return jni_initialized_; - } - - private: - bool jni_initialized_; -}; - -static base::LazyInstance<MediaCodecNativeRegisterer> g_native_registerer = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - namespace media { enum { kBufferFlagEndOfStream = 4 }; @@ -92,7 +67,6 @@ bool MediaCodecBridge::IsAvailable() { MediaCodecBridge::MediaCodecBridge(const char* mime) { JNIEnv* env = AttachCurrentThread(); CHECK(env); - CHECK(g_native_registerer.Pointer()->IsRegistered()); DCHECK(mime); ScopedJavaLocalRef<jstring> j_type = ConvertUTF8ToJavaString(env, mime); @@ -124,19 +98,8 @@ void MediaCodecBridge::Stop() { void MediaCodecBridge::GetOutputFormat(int* width, int* height) { JNIEnv* env = AttachCurrentThread(); - ScopedJavaLocalRef<jobject> j_format( - Java_MediaCodecBridge_getOutputFormat(env, j_media_codec_.obj())); - if (!j_format.is_null()) { - ScopedJavaLocalRef<jstring> j_key_width = - ConvertUTF8ToJavaString(env, "width"); - *width = JNI_MediaFormat::Java_MediaFormat_getInteger( - env, j_format.obj(), j_key_width.obj()); - - ScopedJavaLocalRef<jstring> j_key_height = - ConvertUTF8ToJavaString(env, "height"); - *height = JNI_MediaFormat::Java_MediaFormat_getInteger( - env, j_format.obj(), j_key_height.obj()); - } + *width = Java_MediaCodecBridge_getOutputWidth(env, j_media_codec_.obj()); + *height = Java_MediaCodecBridge_getOutputHeight(env, j_media_codec_.obj()); } size_t MediaCodecBridge::QueueInputBuffer( @@ -213,8 +176,8 @@ void MediaCodecBridge::GetOutputBuffers() { Java_MediaCodecBridge_getOutputBuffers(env, j_media_codec_.obj()); } -AudioCodecBridge::AudioCodecBridge(const AudioCodec codec) - : MediaCodecBridge(AudioCodecToMimeType(codec)) { +AudioCodecBridge::AudioCodecBridge(const char* mime) + : MediaCodecBridge(mime) { } bool AudioCodecBridge::Start( @@ -226,7 +189,7 @@ bool AudioCodecBridge::Start( ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, AudioCodecToMimeType(codec)); ScopedJavaLocalRef<jobject> j_format( - JNI_MediaFormat::Java_MediaFormat_createAudioFormat( + Java_MediaCodecBridge_createAudioFormat( env, j_mime.obj(), sample_rate, channel_count)); DCHECK(!j_format.is_null()); @@ -266,16 +229,14 @@ bool AudioCodecBridge::Start( // The first header is identification header. jobject identification_header = env->NewDirectByteBuffer( const_cast<uint8*>(current_pos), header_length[0]); - ScopedJavaLocalRef<jstring> j_csd_0 = ConvertUTF8ToJavaString(env, "csd-0"); - JNI_MediaFormat::Java_MediaFormat_setByteBuffer( - env, j_format.obj(), j_csd_0.obj(), identification_header); + Java_MediaCodecBridge_setCodecSpecificData( + env, j_format.obj(), 0, identification_header); // The last header is codec header. jobject codec_header = env->NewDirectByteBuffer( const_cast<uint8*>(extra_data + total_length), extra_data_size - total_length); - ScopedJavaLocalRef<jstring> j_csd_1 = ConvertUTF8ToJavaString(env, "csd-1"); - JNI_MediaFormat::Java_MediaFormat_setByteBuffer( - env, j_format.obj(), j_csd_1.obj(), codec_header); + Java_MediaCodecBridge_setCodecSpecificData( + env, j_format.obj(), 1, codec_header); env->DeleteLocalRef(codec_header); env->DeleteLocalRef(identification_header); } @@ -300,8 +261,8 @@ void AudioCodecBridge::PlayOutputBuffer(int index, size_t size) { env, media_codec(), byte_array.obj()); } -VideoCodecBridge::VideoCodecBridge(const VideoCodec codec) - : MediaCodecBridge(VideoCodecToMimeType(codec)) { +VideoCodecBridge::VideoCodecBridge(const char* mime) + : MediaCodecBridge(mime) { } bool VideoCodecBridge::Start( @@ -312,7 +273,7 @@ bool VideoCodecBridge::Start( ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, VideoCodecToMimeType(codec)); ScopedJavaLocalRef<jobject> j_format( - JNI_MediaFormat::Java_MediaFormat_createVideoFormat( + Java_MediaCodecBridge_createVideoFormat( env, j_mime.obj(), size.width(), size.height())); DCHECK(!j_format.is_null()); Java_MediaCodecBridge_configureVideo( @@ -321,5 +282,19 @@ bool VideoCodecBridge::Start( return true; } +AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec codec) { + const char* mime = AudioCodecToMimeType(codec); + return mime ? new AudioCodecBridge(mime) : NULL; +} + +VideoCodecBridge* VideoCodecBridge::Create(const VideoCodec codec) { + const char* mime = VideoCodecToMimeType(codec); + return mime ? new VideoCodecBridge(mime) : NULL; +} + +bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) { + return RegisterNativesImpl(env); +} + } // namespace media diff --git a/media/base/android/media_codec_bridge.h b/media/base/android/media_codec_bridge.h index bff24f9..7bea7b6 100644 --- a/media/base/android/media_codec_bridge.h +++ b/media/base/android/media_codec_bridge.h @@ -85,6 +85,8 @@ class MEDIA_EXPORT MediaCodecBridge { // To access them, use DequeueOutputBuffer(). void GetOutputBuffers(); + static bool RegisterMediaCodecBridge(JNIEnv* env); + protected: explicit MediaCodecBridge(const char* mime); @@ -103,7 +105,9 @@ class MEDIA_EXPORT MediaCodecBridge { class AudioCodecBridge : public MediaCodecBridge { public: - explicit AudioCodecBridge(const AudioCodec codec); + // Returns an AudioCodecBridge instance if |codec| is supported, or a NULL + // pointer otherwise. + static AudioCodecBridge* Create(const AudioCodec codec); // Start the audio codec bridge. bool Start(const AudioCodec codec, int sample_rate, int channel_count, @@ -113,16 +117,24 @@ class AudioCodecBridge : public MediaCodecBridge { // Play the output buffer. This call must be called after // DequeueOutputBuffer() and before ReleaseOutputBuffer. void PlayOutputBuffer(int index, size_t size); + + private: + explicit AudioCodecBridge(const char* mime); }; class VideoCodecBridge : public MediaCodecBridge { public: - explicit VideoCodecBridge(const VideoCodec codec); + // Returns an VideoCodecBridge instance if |codec| is supported, or a NULL + // pointer otherwise. + static VideoCodecBridge* Create(const VideoCodec codec); // Start the video codec bridge. // TODO(qinmin): Pass codec specific data if available. bool Start( const VideoCodec codec, const gfx::Size& size, jobject surface); + + private: + explicit VideoCodecBridge(const char* mime); }; } // namespace media diff --git a/media/base/android/media_codec_bridge_unittest.cc b/media/base/android/media_codec_bridge_unittest.cc index ea95c52..962ae3a 100644 --- a/media/base/android/media_codec_bridge_unittest.cc +++ b/media/base/android/media_codec_bridge_unittest.cc @@ -97,7 +97,7 @@ TEST(MediaCodecBridgeTest, Initialize) { return; scoped_ptr<media::MediaCodecBridge> media_codec; - media_codec.reset(new VideoCodecBridge(kCodecH264)); + media_codec.reset(VideoCodecBridge::Create(kCodecH264)); } TEST(MediaCodecBridgeTest, DoNormal) { @@ -105,7 +105,7 @@ TEST(MediaCodecBridgeTest, DoNormal) { return; scoped_ptr<media::AudioCodecBridge> media_codec; - media_codec.reset(new AudioCodecBridge(kCodecMP3)); + media_codec.reset(AudioCodecBridge::Create(kCodecMP3)); media_codec->Start(kCodecMP3, 44100, 2, NULL, 0, false); @@ -162,7 +162,7 @@ TEST(MediaCodecBridgeTest, InvalidVorbisHeader) { return; scoped_ptr<media::AudioCodecBridge> media_codec; - media_codec.reset(new AudioCodecBridge(kCodecVorbis)); + media_codec.reset(AudioCodecBridge::Create(kCodecVorbis)); // The first byte of the header is not 0x02. uint8 invalid_first_byte[] = { 0x00, 0xff, 0xff, 0xff, 0xff }; @@ -187,4 +187,9 @@ TEST(MediaCodecBridgeTest, InvalidVorbisHeader) { delete[] very_large_header; } +TEST(MediaCodecBridgeTest, CreateUnsupportedCodec) { + EXPECT_EQ(NULL, AudioCodecBridge::Create(kUnknownAudioCodec)); + EXPECT_EQ(NULL, VideoCodecBridge::Create(kUnknownVideoCodec)); +} + } // namespace media diff --git a/media/base/android/media_jni_registrar.cc b/media/base/android/media_jni_registrar.cc index 9cedfac..93a46c3 100644 --- a/media/base/android/media_jni_registrar.cc +++ b/media/base/android/media_jni_registrar.cc @@ -9,6 +9,7 @@ #include "base/android/jni_registrar.h" #include "media/audio/android/audio_manager_android.h" +#include "media/base/android/media_codec_bridge.h" #include "media/base/android/media_player_bridge.h" #include "media/base/android/media_player_listener.h" #include "media/base/android/webaudio_media_codec_bridge.h" @@ -19,6 +20,8 @@ namespace media { static base::android::RegistrationMethod kMediaRegisteredMethods[] = { { "AudioManagerAndroid", AudioManagerAndroid::RegisterAudioManager }, + { "MediaCodecBridge", + MediaCodecBridge::RegisterMediaCodecBridge }, { "MediaPlayerBridge", MediaPlayerBridge::RegisterMediaPlayerBridge }, { "MediaPlayerListener", diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc index 00cddb7..193c1a3 100644 --- a/media/base/android/media_source_player.cc +++ b/media/base/android/media_source_player.cc @@ -167,7 +167,7 @@ VideoDecoderJob::VideoDecoderJob( const scoped_refptr<base::MessageLoopProxy>& message_loop, const VideoCodec video_codec, const gfx::Size& size, jobject surface) : MediaDecoderJob(false, message_loop) { - scoped_ptr<VideoCodecBridge> codec(new VideoCodecBridge(video_codec)); + scoped_ptr<VideoCodecBridge> codec(VideoCodecBridge::Create(video_codec)); codec->Start(video_codec, size, surface); media_codec_bridge_.reset(codec.release()); thread_.reset(new base::Thread("MediaSource_VideoDecoderThread")); @@ -181,7 +181,7 @@ AudioDecoderJob::AudioDecoderJob( const uint8* extra_data, size_t extra_data_size) : MediaDecoderJob(true, message_loop) { - scoped_ptr<AudioCodecBridge> codec(new AudioCodecBridge(audio_codec)); + scoped_ptr<AudioCodecBridge> codec(AudioCodecBridge::Create(audio_codec)); codec->Start(audio_codec, sample_rate, channel_count, extra_data, extra_data_size, true); media_codec_bridge_.reset(codec.release()); diff --git a/media/media.gyp b/media/media.gyp index 253f6d4..b913d68 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -1584,7 +1584,6 @@ 'dependencies': [ '../base/base.gyp:base', 'media_android_jni_headers', - 'media_format_jni_headers', ], 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)/media', |