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