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

Unified Diff: media/base/android/media_codec_bridge.cc

Issue 74563002: AndroidVideoEncodeAccelerator is born! (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/android/media_codec_bridge.cc
diff --git a/media/base/android/media_codec_bridge.cc b/media/base/android/media_codec_bridge.cc
index 1acd23afa7abac6d5da42d24f09595e4e27284e5..15ce6e4dbc8937df9c3a25e55087dd1fd94040e0 100644
--- a/media/base/android/media_codec_bridge.cc
+++ b/media/base/android/media_codec_bridge.cc
@@ -28,7 +28,11 @@ using base::android::ScopedJavaLocalRef;
namespace media {
-enum { kBufferFlagEndOfStream = 4 };
+enum {
+ kBufferFlagSyncFrame = 1, // BUFFER_FLAG_SYNC_FRAME
+ kBufferFlagEndOfStream = 4, // BUFFER_FLAG_END_OF_STREAM
+ kConfigureFlagEncode = 1, // CONFIGURE_FLAG_ENCODE
+};
static const std::string AudioCodecToAndroidMimeType(const AudioCodec& codec) {
switch (codec) {
@@ -64,7 +68,7 @@ static const std::string CodecTypeToAndroidMimeType(const std::string& codec) {
return "audio/mp4a-latm";
if (codec == "vp8" || codec == "vp8.0")
return "video/x-vnd.on2.vp8";
- if (codec == "vp9" || codec == "vp9.0")
+ if (codec == "vp9" || codec == "vp9.0")
return "video/x-vnd.on2.vp9";
if (codec == "vorbis")
return "audio/vorbis";
@@ -90,8 +94,8 @@ static const std::string AndroidMimeTypeToCodecType(const std::string& mime) {
return std::string();
}
-static ScopedJavaLocalRef<jintArray> ToJavaIntArray(
- JNIEnv* env, scoped_ptr<jint[]> native_array, int size) {
+static ScopedJavaLocalRef<jintArray>
+ToJavaIntArray(JNIEnv* env, scoped_ptr<jint[]> native_array, int size) {
ScopedJavaLocalRef<jintArray> j_array(env, env->NewIntArray(size));
env->SetIntArrayRegion(j_array.obj(), 0, size, native_array.get());
return j_array;
@@ -104,11 +108,17 @@ bool MediaCodecBridge::IsAvailable() {
}
// static
-void MediaCodecBridge::GetCodecsInfo(
- std::vector<CodecsInfo>* codecs_info) {
+bool MediaCodecBridge::SupportsSetParameters() {
+ // MediaCodec.setParameters() is only available starting with K.
+ return base::android::BuildInfo::GetInstance()->sdk_int() >= 19;
+}
+
+// static
+std::vector<MediaCodecBridge::CodecsInfo> MediaCodecBridge::GetCodecsInfo() {
+ std::vector<CodecsInfo> codecs_info;
JNIEnv* env = AttachCurrentThread();
if (!IsAvailable())
- return;
+ return codecs_info;
std::string mime_type;
std::string codec_name;
@@ -126,8 +136,11 @@ void MediaCodecBridge::GetCodecsInfo(
CodecsInfo info;
info.codecs = AndroidMimeTypeToCodecType(mime_type);
ConvertJavaStringToUTF8(env, j_codec_name.obj(), &info.name);
- codecs_info->push_back(info);
+ info.direction = static_cast<MediaCodecDirection>(
+ Java_CodecInfo_direction(env, j_info.obj()));
+ codecs_info.push_back(info);
}
+ return codecs_info;
}
// static
@@ -138,7 +151,7 @@ bool MediaCodecBridge::CanDecode(const std::string& codec, bool is_secure) {
return false;
ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
ScopedJavaLocalRef<jobject> j_media_codec_bridge =
- Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure);
+ Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure, false);
if (!j_media_codec_bridge.is_null()) {
Java_MediaCodecBridge_release(env, j_media_codec_bridge.obj());
return true;
@@ -147,12 +160,14 @@ bool MediaCodecBridge::CanDecode(const std::string& codec, bool is_secure) {
}
// static
-bool MediaCodecBridge::IsKnownUnaccelerated(const std::string& mime_type) {
+bool MediaCodecBridge::IsKnownUnaccelerated(const std::string& mime_type,
+ MediaCodecDirection direction) {
std::string codec_type = AndroidMimeTypeToCodecType(mime_type);
- std::vector<media::MediaCodecBridge::CodecsInfo> codecs_info;
- media::MediaCodecBridge::GetCodecsInfo(&codecs_info);
+ std::vector<media::MediaCodecBridge::CodecsInfo> codecs_info =
+ MediaCodecBridge::GetCodecsInfo();
for (size_t i = 0; i < codecs_info.size(); ++i) {
- if (codecs_info[i].codecs == codec_type) {
+ if (codecs_info[i].codecs == codec_type &&
+ codecs_info[i].direction == direction) {
// It would be nice if MediaCodecInfo externalized some notion of
// HW-acceleration but it doesn't. Android Media guidance is that the
// prefix below is always used for SW decoders, so that's what we use.
@@ -162,13 +177,15 @@ bool MediaCodecBridge::IsKnownUnaccelerated(const std::string& mime_type) {
return true;
}
-MediaCodecBridge::MediaCodecBridge(const std::string& mime, bool is_secure) {
+MediaCodecBridge::MediaCodecBridge(const std::string& mime,
+ bool is_secure,
+ MediaCodecDirection direction) {
JNIEnv* env = AttachCurrentThread();
CHECK(env);
DCHECK(!mime.empty());
ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
j_media_codec_.Reset(
- Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure));
+ Java_MediaCodecBridge_create(env, j_mime.obj(), is_secure, direction));
}
MediaCodecBridge::~MediaCodecBridge() {
@@ -203,22 +220,41 @@ void MediaCodecBridge::GetOutputFormat(int* width, int* height) {
}
MediaCodecStatus MediaCodecBridge::QueueInputBuffer(
- int index, const uint8* data, int data_size,
+ int index,
+ const uint8* data,
+ int orig_data_size,
const base::TimeDelta& presentation_time) {
- if (!FillInputBuffer(index, data, data_size))
+ DVLOG(3) << "MediaCodecBridge::QueueInputBuffer: " << index << ": "
+ << orig_data_size;
+ size_t data_size = base::checked_numeric_cast<size_t>(orig_data_size);
+ if (data && !FillInputBuffer(index, data, data_size))
return MEDIA_CODEC_ERROR;
JNIEnv* env = AttachCurrentThread();
- return static_cast<MediaCodecStatus>(Java_MediaCodecBridge_queueInputBuffer(
- env, j_media_codec_.obj(),
- index, 0, data_size, presentation_time.InMicroseconds(), 0));
+ return static_cast<MediaCodecStatus>(
+ Java_MediaCodecBridge_queueInputBuffer(env,
+ j_media_codec_.obj(),
+ index,
+ 0,
+ data_size,
+ presentation_time.InMicroseconds(),
+ 0));
}
MediaCodecStatus MediaCodecBridge::QueueSecureInputBuffer(
- int index, const uint8* data, int data_size, const uint8* key_id,
- int key_id_size, const uint8* iv, int iv_size,
- const SubsampleEntry* subsamples, int subsamples_size,
+ int index,
+ const uint8* data,
+ int orig_data_size,
+ const uint8* key_id,
+ int key_id_size,
+ const uint8* iv,
+ int iv_size,
+ const SubsampleEntry* subsamples,
+ int subsamples_size,
const base::TimeDelta& presentation_time) {
- if (!FillInputBuffer(index, data, data_size))
+ DVLOG(3) << "MediaCodecBridge::QueueSecureInputBuffer: " << index << ": "
+ << orig_data_size;
+ size_t data_size = base::checked_numeric_cast<size_t>(orig_data_size);
+ if (data && !FillInputBuffer(index, data, data_size))
return MEDIA_CODEC_ERROR;
JNIEnv* env = AttachCurrentThread();
@@ -256,55 +292,87 @@ MediaCodecStatus MediaCodecBridge::QueueSecureInputBuffer(
}
ScopedJavaLocalRef<jintArray> clear_array =
- ToJavaIntArray(env, native_clear_array.Pass(), new_subsamples_size);
+ ToJavaIntArray(env, native_clear_array.Pass(), new_subsamples_size);
ScopedJavaLocalRef<jintArray> cypher_array =
- ToJavaIntArray(env, native_cypher_array.Pass(), new_subsamples_size);
+ ToJavaIntArray(env, native_cypher_array.Pass(), new_subsamples_size);
return static_cast<MediaCodecStatus>(
Java_MediaCodecBridge_queueSecureInputBuffer(
- env, j_media_codec_.obj(), index, 0, j_iv.obj(), j_key_id.obj(),
- clear_array.obj(), cypher_array.obj(), new_subsamples_size,
+ env,
+ j_media_codec_.obj(),
+ index,
+ 0,
+ j_iv.obj(),
+ j_key_id.obj(),
+ clear_array.obj(),
+ cypher_array.obj(),
+ new_subsamples_size,
presentation_time.InMicroseconds()));
}
void MediaCodecBridge::QueueEOS(int input_buffer_index) {
+ DVLOG(3) << "MediaCodecBridge::QueueEOS: " << input_buffer_index;
JNIEnv* env = AttachCurrentThread();
- Java_MediaCodecBridge_queueInputBuffer(
- env, j_media_codec_.obj(),
- input_buffer_index, 0, 0, 0, kBufferFlagEndOfStream);
+ Java_MediaCodecBridge_queueInputBuffer(env,
+ j_media_codec_.obj(),
+ input_buffer_index,
+ 0,
+ 0,
+ 0,
+ kBufferFlagEndOfStream);
}
MediaCodecStatus MediaCodecBridge::DequeueInputBuffer(
- const base::TimeDelta& timeout, int* index) {
+ const base::TimeDelta& timeout,
+ int* index) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> result = Java_MediaCodecBridge_dequeueInputBuffer(
env, j_media_codec_.obj(), timeout.InMicroseconds());
*index = Java_DequeueInputResult_index(env, result.obj());
- return static_cast<MediaCodecStatus>(
+ MediaCodecStatus status = static_cast<MediaCodecStatus>(
Java_DequeueInputResult_status(env, result.obj()));
+ DVLOG(3) << "MediaCodecBridge::DequeueInputBuffer: status: " << status
+ << ", index: " << *index;
+ return status;
}
MediaCodecStatus MediaCodecBridge::DequeueOutputBuffer(
- const base::TimeDelta& timeout, int* index, size_t* offset, size_t* size,
- base::TimeDelta* presentation_time, bool* end_of_stream) {
+ const base::TimeDelta& timeout,
+ int* index,
+ size_t* offset,
+ size_t* size,
+ base::TimeDelta* presentation_time,
+ bool* end_of_stream,
+ bool* key_frame) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> result =
- Java_MediaCodecBridge_dequeueOutputBuffer(env, j_media_codec_.obj(),
- timeout.InMicroseconds());
- *index = Java_DequeueOutputResult_index(env, result.obj());;
+ Java_MediaCodecBridge_dequeueOutputBuffer(
+ env, j_media_codec_.obj(), timeout.InMicroseconds());
+ *index = Java_DequeueOutputResult_index(env, result.obj());
*offset = base::checked_numeric_cast<size_t>(
- Java_DequeueOutputResult_offset(env, result.obj()));
+ Java_DequeueOutputResult_offset(env, result.obj()));
*size = base::checked_numeric_cast<size_t>(
- Java_DequeueOutputResult_numBytes(env, result.obj()));
- *presentation_time = base::TimeDelta::FromMicroseconds(
- Java_DequeueOutputResult_presentationTimeMicroseconds(env, result.obj()));
+ Java_DequeueOutputResult_numBytes(env, result.obj()));
+ if (presentation_time) {
+ *presentation_time = base::TimeDelta::FromMicroseconds(
+ Java_DequeueOutputResult_presentationTimeMicroseconds(env,
+ result.obj()));
+ }
int flags = Java_DequeueOutputResult_flags(env, result.obj());
- *end_of_stream = flags & kBufferFlagEndOfStream;
- return static_cast<MediaCodecStatus>(
+ if (end_of_stream)
+ *end_of_stream = flags & kBufferFlagEndOfStream;
+ if (key_frame)
+ *key_frame = flags & kBufferFlagSyncFrame;
+ MediaCodecStatus status = static_cast<MediaCodecStatus>(
Java_DequeueOutputResult_status(env, result.obj()));
+ DVLOG(3) << "MediaCodecBridge::DequeueOutputBuffer: status: " << status
+ << ", index: " << *index << ", offset: " << *offset
+ << ", size: " << *size << ", flags: " << flags;
+ return status;
}
void MediaCodecBridge::ReleaseOutputBuffer(int index, bool render) {
+ DVLOG(3) << "MediaCodecBridge::ReleaseOutputBuffer: " << index;
JNIEnv* env = AttachCurrentThread();
CHECK(env);
@@ -312,38 +380,85 @@ void MediaCodecBridge::ReleaseOutputBuffer(int index, bool render) {
env, j_media_codec_.obj(), index, render);
}
+int MediaCodecBridge::GetInputBuffersCount() {
+ JNIEnv* env = AttachCurrentThread();
+ return Java_MediaCodecBridge_getInputBuffersCount(env, j_media_codec_.obj());
+}
+
+int MediaCodecBridge::GetOutputBuffersCount() {
+ JNIEnv* env = AttachCurrentThread();
+ return Java_MediaCodecBridge_getOutputBuffersCount(env, j_media_codec_.obj());
+}
+
+size_t MediaCodecBridge::GetOutputBuffersCapacity() {
+ JNIEnv* env = AttachCurrentThread();
+ return Java_MediaCodecBridge_getOutputBuffersCapacity(env,
+ j_media_codec_.obj());
+}
+
bool MediaCodecBridge::GetOutputBuffers() {
JNIEnv* env = AttachCurrentThread();
return Java_MediaCodecBridge_getOutputBuffers(env, j_media_codec_.obj());
}
-bool MediaCodecBridge::FillInputBuffer(int index, const uint8* data, int size) {
+void MediaCodecBridge::GetInputBuffer(int input_buffer_index,
+ uint8** data,
+ size_t* capacity) {
JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> j_buffer(Java_MediaCodecBridge_getInputBuffer(
+ env, j_media_codec_.obj(), input_buffer_index));
+ *data = static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj()));
+ *capacity = base::checked_numeric_cast<size_t>(
+ env->GetDirectBufferCapacity(j_buffer.obj()));
+}
+bool MediaCodecBridge::CopyFromOutputBuffer(int index,
+ size_t offset,
+ void* dst,
+ int dst_size) {
+ JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> j_buffer(
- Java_MediaCodecBridge_getInputBuffer(env, j_media_codec_.obj(), index));
- jlong capacity = env->GetDirectBufferCapacity(j_buffer.obj());
+ Java_MediaCodecBridge_getOutputBuffer(env, j_media_codec_.obj(), index));
+ void* src_data =
+ reinterpret_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj())) +
+ offset;
+ int src_capacity = env->GetDirectBufferCapacity(j_buffer.obj()) - offset;
+ if (src_capacity < dst_size)
+ return false;
+ memcpy(dst, src_data, dst_size);
+ return true;
+}
+
+bool MediaCodecBridge::FillInputBuffer(int index,
+ const uint8* data,
+ size_t size) {
+ uint8* dst = NULL;
+ size_t capacity = 0;
+ GetInputBuffer(index, &dst, &capacity);
+ CHECK(dst);
+
if (size > capacity) {
LOG(ERROR) << "Input buffer size " << size
<< " exceeds MediaCodec input buffer capacity: " << capacity;
return false;
}
- uint8* direct_buffer =
- static_cast<uint8*>(env->GetDirectBufferAddress(j_buffer.obj()));
- memcpy(direct_buffer, data, size);
+ memcpy(dst, data, size);
return true;
}
AudioCodecBridge::AudioCodecBridge(const std::string& mime)
- // Audio codec doesn't care about security level.
- : MediaCodecBridge(mime, false) {
-}
-
-bool AudioCodecBridge::Start(
- const AudioCodec& codec, int sample_rate, int channel_count,
- const uint8* extra_data, size_t extra_data_size, bool play_audio,
- jobject media_crypto) {
+ // Audio codec doesn't care about security level and there is no need for
+ // audio encoding yet.
+ : MediaCodecBridge(mime, false, MEDIA_CODEC_DECODER) {}
+
+bool AudioCodecBridge::Start(const AudioCodec& codec,
+ int sample_rate,
+ int channel_count,
+ const uint8* extra_data,
+ size_t extra_data_size,
+ bool play_audio,
+ jobject media_crypto) {
JNIEnv* env = AttachCurrentThread();
if (!media_codec())
@@ -355,32 +470,31 @@ bool AudioCodecBridge::Start(
ScopedJavaLocalRef<jstring> j_mime =
ConvertUTF8ToJavaString(env, codec_string);
- ScopedJavaLocalRef<jobject> j_format(
- Java_MediaCodecBridge_createAudioFormat(
- env, j_mime.obj(), sample_rate, channel_count));
+ ScopedJavaLocalRef<jobject> j_format(Java_MediaCodecBridge_createAudioFormat(
+ env, j_mime.obj(), sample_rate, channel_count));
DCHECK(!j_format.is_null());
if (!ConfigureMediaFormat(j_format.obj(), codec, extra_data, extra_data_size))
return false;
if (!Java_MediaCodecBridge_configureAudio(
- env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) {
+ env, media_codec(), j_format.obj(), media_crypto, 0, play_audio)) {
return false;
}
return StartInternal();
}
-bool AudioCodecBridge::ConfigureMediaFormat(
- jobject j_format, const AudioCodec& codec, const uint8* extra_data,
- size_t extra_data_size) {
+bool AudioCodecBridge::ConfigureMediaFormat(jobject j_format,
+ const AudioCodec& codec,
+ const uint8* extra_data,
+ size_t extra_data_size) {
if (extra_data_size == 0)
return true;
JNIEnv* env = AttachCurrentThread();
switch (codec) {
- case kCodecVorbis:
- {
+ case kCodecVorbis: {
if (extra_data[0] != 2) {
LOG(ERROR) << "Invalid number of vorbis headers before the codec "
<< "header: " << extra_data[0];
@@ -425,8 +539,7 @@ bool AudioCodecBridge::ConfigureMediaFormat(
env, j_format, 1, last_header.obj());
break;
}
- case kCodecAAC:
- {
+ case kCodecAAC: {
media::BitReader reader(extra_data, extra_data_size);
// The following code is copied from aac.cc
@@ -485,8 +598,7 @@ void AudioCodecBridge::PlayOutputBuffer(int index, size_t size) {
ScopedJavaLocalRef<jbyteArray> byte_array =
base::android::ToJavaByteArray(env, buffer, numBytes);
- Java_MediaCodecBridge_playOutputBuffer(
- env, media_codec(), byte_array.obj());
+ Java_MediaCodecBridge_playOutputBuffer(env, media_codec(), byte_array.obj());
}
void AudioCodecBridge::SetVolume(double volume) {
@@ -494,57 +606,104 @@ void AudioCodecBridge::SetVolume(double volume) {
Java_MediaCodecBridge_setVolume(env, media_codec(), volume);
}
-VideoCodecBridge::VideoCodecBridge(const std::string& mime, bool is_secure)
- : MediaCodecBridge(mime, is_secure) {
+AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) {
+ const std::string mime = AudioCodecToAndroidMimeType(codec);
+ return mime.empty() ? NULL : new AudioCodecBridge(mime);
}
-bool VideoCodecBridge::Start(
- const VideoCodec& codec, const gfx::Size& size, jobject surface,
- jobject media_crypto) {
- JNIEnv* env = AttachCurrentThread();
+// static
+bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) {
+ return MediaCodecBridge::IsKnownUnaccelerated(
+ AudioCodecToAndroidMimeType(codec), MEDIA_CODEC_DECODER);
+}
- if (!media_codec())
- return false;
+// static
+bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec,
+ MediaCodecDirection direction) {
+ return MediaCodecBridge::IsKnownUnaccelerated(
+ VideoCodecToAndroidMimeType(codec), direction);
+}
- std::string codec_string = VideoCodecToAndroidMimeType(codec);
- if (codec_string.empty())
- return false;
+VideoCodecBridge* VideoCodecBridge::CreateDecoder(const VideoCodec& codec,
+ bool is_secure,
+ const gfx::Size& size,
+ jobject surface,
+ jobject media_crypto) {
+ JNIEnv* env = AttachCurrentThread();
+ const std::string mime = VideoCodecToAndroidMimeType(codec);
+ if (mime.empty())
+ return NULL;
- ScopedJavaLocalRef<jstring> j_mime =
- ConvertUTF8ToJavaString(env, codec_string);
+ scoped_ptr<VideoCodecBridge> bridge(
+ new VideoCodecBridge(mime, is_secure, MEDIA_CODEC_DECODER));
+
+ ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
ScopedJavaLocalRef<jobject> j_format(
- Java_MediaCodecBridge_createVideoFormat(
+ Java_MediaCodecBridge_createVideoDecoderFormat(
env, j_mime.obj(), size.width(), size.height()));
DCHECK(!j_format.is_null());
- if (!Java_MediaCodecBridge_configureVideo(
- env, media_codec(), j_format.obj(), surface, media_crypto, 0)) {
- return false;
+ if (!Java_MediaCodecBridge_configureVideo(env,
+ bridge->media_codec(),
+ j_format.obj(),
+ surface,
+ media_crypto,
+ 0)) {
+ return NULL;
}
- return StartInternal();
+ return bridge->StartInternal() ? bridge.release() : NULL;
}
-AudioCodecBridge* AudioCodecBridge::Create(const AudioCodec& codec) {
- const std::string mime = AudioCodecToAndroidMimeType(codec);
- return mime.empty() ? NULL : new AudioCodecBridge(mime);
-}
+VideoCodecBridge* VideoCodecBridge::CreateEncoder(const VideoCodec& codec,
+ const gfx::Size& size,
+ int bit_rate,
+ int frame_rate,
+ int i_frame_interval,
+ int color_format) {
+ JNIEnv* env = AttachCurrentThread();
+ const std::string mime = VideoCodecToAndroidMimeType(codec);
+ if (mime.empty())
+ return NULL;
-// static
-bool AudioCodecBridge::IsKnownUnaccelerated(const AudioCodec& codec) {
- return MediaCodecBridge::IsKnownUnaccelerated(
- AudioCodecToAndroidMimeType(codec));
+ scoped_ptr<VideoCodecBridge> bridge(
+ new VideoCodecBridge(mime, false, MEDIA_CODEC_ENCODER));
+
+ ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, mime);
+ ScopedJavaLocalRef<jobject> j_format(
+ Java_MediaCodecBridge_createVideoEncoderFormat(env,
+ j_mime.obj(),
+ size.width(),
+ size.height(),
+ bit_rate,
+ frame_rate,
+ i_frame_interval,
+ color_format));
+ DCHECK(!j_format.is_null());
+ if (!Java_MediaCodecBridge_configureVideo(env,
+ bridge->media_codec(),
+ j_format.obj(),
+ NULL,
+ NULL,
+ kConfigureFlagEncode)) {
+ return NULL;
+ }
+
+ return bridge->StartInternal() ? bridge.release() : NULL;
}
-VideoCodecBridge* VideoCodecBridge::Create(const VideoCodec& codec,
- bool is_secure) {
- const std::string mime = VideoCodecToAndroidMimeType(codec);
- return mime.empty() ? NULL : new VideoCodecBridge(mime, is_secure);
+VideoCodecBridge::VideoCodecBridge(const std::string& mime,
+ bool is_secure,
+ MediaCodecDirection direction)
+ : MediaCodecBridge(mime, is_secure, direction) {}
+
+void VideoCodecBridge::SetVideoBitrate(int bps) {
+ JNIEnv* env = AttachCurrentThread();
+ Java_MediaCodecBridge_setVideoBitrate(env, media_codec(), bps);
}
-// static
-bool VideoCodecBridge::IsKnownUnaccelerated(const VideoCodec& codec) {
- return MediaCodecBridge::IsKnownUnaccelerated(
- VideoCodecToAndroidMimeType(codec));
+void VideoCodecBridge::RequestKeyFrameSoon() {
+ JNIEnv* env = AttachCurrentThread();
+ Java_MediaCodecBridge_requestKeyFrameSoon(env, media_codec());
}
bool MediaCodecBridge::RegisterMediaCodecBridge(JNIEnv* env) {
« 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