android_media_MediaCodec.cpp revision 88572f7a3e9d7ef85c26865a0150f3c2041561c2
188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber/* 288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Copyright 2012, The Android Open Source Project 388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * 488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * you may not use this file except in compliance with the License. 688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * You may obtain a copy of the License at 788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * 888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * 1088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Unless required by applicable law or agreed to in writing, software 1188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * See the License for the specific language governing permissions and 1488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * limitations under the License. 1588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber */ 1688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//#define LOG_NDEBUG 0 1888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#define LOG_TAG "MediaCodec-JNI" 1988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <utils/Log.h> 2088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_MediaCodec.h" 2288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_Utils.h" 2488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/AndroidRuntime.h" 2588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/android_view_Surface.h" 2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "jni.h" 2788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "JNIHelp.h" 2888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaCodec.h> 3088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 3188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 3288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ALooper.h> 3388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 3488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h> 3588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <surfaceflinger/Surface.h> 3688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android { 3888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!! 4088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum { 4188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_TRY_AGAIN_LATER = -1, 4288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED = -2, 4388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, 4488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 4588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 4988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 5388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 5588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 5688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 5788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 5888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject(NULL) { 5988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 6088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 6188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 6388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 6488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 6688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 6788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 6988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 7088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // canCallJava 7188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber PRIORITY_DEFAULT); 7288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 7488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByType(mLooper, name, encoder); 7588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 7688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByComponentName(mLooper, name); 7788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 8188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec != NULL ? OK : NO_INIT; 8288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 8388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::~JMediaCodec() { 8588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec->stop(); 8688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 9288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ISurfaceTexture> &surfaceTexture, 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 9988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<SurfaceTextureClient> client; 10088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surfaceTexture != NULL) { 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber client = new SurfaceTextureClient(surfaceTexture); 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->configure(format, client, flags); 10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 10588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->start(); 10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->stop(); 11288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags) { 12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->queueInputBuffer(index, offset, size, timeUs, flags); 12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 12388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->dequeueInputBuffer(index, timeoutUs); 12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 12788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 13088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 13388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 13488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->dequeueOutputBuffer( 13588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber index, &size, &offset, &timeUs, &flags, timeoutUs)) != OK) { 13688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 13788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 13888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 13988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec$BufferInfo"); 14088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID method = env->GetMethodID(clazz, "set", "(IIJI)V"); 14288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->CallVoidMethod(bufferInfo, method, offset, size, timeUs, flags); 14388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::releaseOutputBuffer(size_t index, bool render) { 14888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 14988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 15088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 15288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, jobject *format) const { 15488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 15588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 15688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->getOutputFormat(&msg)) != OK) { 15788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 15888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 16188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 16288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 16488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 16588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber Vector<sp<ABuffer> > buffers; 16688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 16788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 16888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 16988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 17088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 17188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 17388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass byteBufferClass = env->FindClass("java/nio/ByteBuffer"); 17788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffers.size(), byteBufferClass, NULL); 18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 18288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ABuffer> &buffer = buffers.itemAt(i); 18388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBuffer = 18588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->NewDirectByteBuffer( 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->base(), 18788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->capacity()); 18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetObjectArrayElement( 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray, i, byteBuffer); 19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteBuffer); 19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteBuffer = NULL; 19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 20688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 20788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> old = (JMediaCodec *)env->GetIntField(thiz, gFields.context); 20888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 20988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 21188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetIntField(thiz, gFields.context, (int)codec.get()); 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return (JMediaCodec *)env->GetIntField(thiz, gFields.context); 22188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 22488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint throwExceptionAsNecessary(JNIEnv *env, status_t err) { 22888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 22988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 23188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 23388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 23488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 23688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 23788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 23988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 24088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 24288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 24488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 24988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 25488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 26388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 26988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 27088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 27188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<ISurfaceTexture> surfaceTexture; 27388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 27488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<Surface> surface(Surface_getSurface(env, jsurface)); 27588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 27688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber surfaceTexture = surface->getSurfaceTexture(); 27788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 27888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 27988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 28088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 28188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber err = codec->configure(format, surfaceTexture, flags); 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 33288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 34288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 34388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 34488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 34588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber index, offset, size, timestampUs, flags); 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 36488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 36988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 37188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 37288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 37488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return index; 37588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 37888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 39288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 39388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 39488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 39688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return index; 39788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 40088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jint index, jboolean render) { 40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 40588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 40788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->releaseOutputBuffer(index, render); 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject android_media_MediaCodec_getOutputFormat( 41988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 42088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getOutputFormat"); 42188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 42388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 42588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 42688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 42888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 43088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getOutputFormat(env, &format); 43188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 43388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 43788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 43988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 44088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 44288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 44388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 44488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 44688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 44888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 44988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 45488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 45688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 45788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 45888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 46088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 46288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 46388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 46588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec"); 46688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 46788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber gFields.context = env->GetFieldID(clazz, "mNativeContext", "I"); 46988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 47088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 47188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 47288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 47388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 47488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 47588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 47688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 47788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 47888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 47988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 48188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 48388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 48488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 48588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 48788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->initCheck(); 48988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars(name, tmp); 49188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 49488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 49588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 49688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/io/IOException", 49788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "Failed to allocate component instance"); 49888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 49988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 50088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 50288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 50388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 50588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 50688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 50788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 50888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = { 51088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "release", "()V", (void *)android_media_MediaCodec_release }, 51188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 51388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;I)V", 51488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 51588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "start", "()V", (void *)android_media_MediaCodec_start }, 51788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "stop", "()V", (void *)android_media_MediaCodec_stop }, 51888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "flush", "()V", (void *)android_media_MediaCodec_flush }, 51988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "queueInputBuffer", "(IIIJI)V", 52188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 52288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueInputBuffer", "(J)I", 52488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 52588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 52788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 52888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "releaseOutputBuffer", "(IZ)V", 53088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 53188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getOutputFormat", "()Ljava/util/Map;", 53388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getOutputFormat }, 53488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 53688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 53788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 53988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 54088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 54188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 54288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 54388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 54488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 54588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 54688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 54788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 54888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 54988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 55088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 551