summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorqinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-26 02:04:19 +0000
committerqinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-26 02:04:19 +0000
commit31203376861a403af9e92810d03c453ad01b8f57 (patch)
tree49a81216b8f47c689479538984ae4b4c822c3786 /media
parent20c8b942168996a3f0345c9341dc4fa6e99f3a36 (diff)
downloadchromium_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.java32
-rw-r--r--media/base/android/media_codec_bridge.cc77
-rw-r--r--media/base/android/media_codec_bridge.h16
-rw-r--r--media/base/android/media_codec_bridge_unittest.cc11
-rw-r--r--media/base/android/media_jni_registrar.cc3
-rw-r--r--media/base/android/media_source_player.cc4
-rw-r--r--media/media.gyp1
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',