android_media_MediaCodec.cpp revision 63834f4d23a97b27d830a301328329c7ef682bd5
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 2307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber#include "android_media_MediaCrypto.h" 2488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_Utils.h" 2588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/AndroidRuntime.h" 2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/android_view_Surface.h" 2788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "jni.h" 2888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "JNIHelp.h" 2988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 307ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar#include <cutils/compiler.h> 317ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar 328335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <gui/Surface.h> 338335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian 340e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber#include <media/ICrypto.h> 3588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaCodec.h> 3688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 3888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ALooper.h> 3988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 40bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber#include <media/stagefright/foundation/AString.h> 4188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h> 4288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 438d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber#include <nativehelper/ScopedLocalRef.h> 448d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 45b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber#include <system/window.h> 46b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android { 4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!! 5088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum { 5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_TRY_AGAIN_LATER = -1, 5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED = -2, 5388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, 5488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 5588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 56aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huberenum { 578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_CALLBACK = 1, 588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_SET_CALLBACK = 2, 59aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}; 60aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 615f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic struct CryptoErrorCodes { 623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorNoKey; 633ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorKeyExpired; 643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorResourceBusy; 65336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker jint cryptoErrorInsufficientOutputProtection; 663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker} gCryptoErrorCodes; 673ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 685f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic struct CodecActionCodes { 695f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jint codecActionTransient; 705f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jint codecActionRecoverable; 715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} gCodecActionCodes; 725f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 7388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 7488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 75aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber jmethodID postEventFromNativeID; 7691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumSubSamplesID; 7791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfClearDataID; 7891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfEncryptedDataID; 7991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoKeyID; 8091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoIVID; 8191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoModeID; 8288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 8388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 8588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 928d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mObject(NULL) { 9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 997de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cacheJavaObjects(env); 1007de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 10588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 106aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber true, // canCallJava 1078d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber PRIORITY_FOREGROUND); 10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 1105f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus); 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 1125f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus); 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 1145f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK((mCodec != NULL) != (mInitStatus != OK)); 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1177de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::cacheJavaObjects(JNIEnv *env) { 1187de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jclass clazz = (jclass)env->FindClass("java/nio/ByteBuffer"); 1197de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass = (jclass)env->NewGlobalRef(clazz); 1207de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferClass != NULL); 1217de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1227de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> byteOrderClass( 1237de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("java/nio/ByteOrder")); 1247de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(byteOrderClass.get() != NULL); 1257de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1267de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID nativeOrderID = env->GetStaticMethodID( 1277de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;"); 1287de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(nativeOrderID != NULL); 1297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1307de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject nativeByteOrderObj = 1317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID); 1327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mNativeByteOrderObj = env->NewGlobalRef(nativeByteOrderObj); 1337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mNativeByteOrderObj != NULL); 1347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(nativeByteOrderObj); 1357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar nativeByteOrderObj = NULL; 1367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferOrderMethodID = env->GetMethodID( 1387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, 1397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "order", 1407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); 1417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferOrderMethodID != NULL); 1427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferAsReadOnlyBufferMethodID = env->GetMethodID( 1447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;"); 1457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferAsReadOnlyBufferMethodID != NULL); 1467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1477de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferPositionMethodID = env->GetMethodID( 1487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "position", "(I)Ljava/nio/Buffer;"); 1497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferPositionMethodID != NULL); 1507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferLimitMethodID = env->GetMethodID( 1527de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "limit", "(I)Ljava/nio/Buffer;"); 1537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferLimitMethodID != NULL); 1547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 1557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 15688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 1575f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return mInitStatus; 15888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 160aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Hubervoid JMediaCodec::registerSelf() { 161aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber mLooper->registerHandler(this); 162aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 163aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 164128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhangvoid JMediaCodec::release() { 165d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo if (mCodec != NULL) { 166d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec->release(); 167d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec.clear(); 1685f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mInitStatus = NO_INIT; 169d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo } 17088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 171128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang if (mLooper != NULL) { 172128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper->unregisterHandler(id()); 173128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper->stop(); 174128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper.clear(); 175128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang } 176128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang} 177128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang 178128b012cc8c2369136bb8450bc91c81aebe18506Chong ZhangJMediaCodec::~JMediaCodec() { 179128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang if (mCodec != NULL || mLooper != NULL) { 180128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang /* MediaCodec and looper should have been released explicitly already 181128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * in setMediaCodec() (see comments in setMediaCodec()). 182128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * 183128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * Otherwise JMediaCodec::~JMediaCodec() might be called from within the 184128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * message handler, doing release() there risks deadlock as MediaCodec:: 185128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * release() post synchronous message to the same looper. 186128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * 187128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * Print a warning and try to proceed with releasing. 188128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang */ 189128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()..."); 190128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang release(); 191128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec()."); 192128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang } 193128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang 19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 2007de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar deleteJavaObjects(env); 2017de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 2027de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 2037de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::deleteJavaObjects(JNIEnv *env) { 2047de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteGlobalRef(mByteBufferClass); 2057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass = NULL; 2067de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteGlobalRef(mNativeByteOrderObj); 2077de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mNativeByteOrderObj = NULL; 2087de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 2097de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferOrderMethodID = NULL; 2107de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferAsReadOnlyBufferMethodID = NULL; 2117de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferPositionMethodID = NULL; 2127de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferLimitMethodID = NULL; 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2158d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatus_t JMediaCodec::setCallback(jobject cb) { 2168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (cb != NULL) { 2178d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (mCallbackNotification == NULL) { 21863834f4d23a97b27d830a301328329c7ef682bd5Lajos Molnar mCallbackNotification = new AMessage(kWhatCallbackNotify, this); 2198d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 2208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } else { 2218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mCallbackNotification.clear(); 2228d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 2238d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 2248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->setCallback(mCallbackNotification); 2258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang} 2268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 22888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 229d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden const sp<IGraphicBufferProducer> &bufferProducer, 2308240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const sp<ICrypto> &crypto, 23188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 23252800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> client; 233d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden if (bufferProducer != NULL) { 234aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber mSurfaceTextureClient = 235aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber new Surface(bufferProducer, true /* controlledByApp */); 236b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } else { 237b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 23888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 239b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 240b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return mCodec->configure(format, mSurfaceTextureClient, crypto, flags); 24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 24288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2432621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface( 2442621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 2452621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->createInputSurface(bufferProducer); 2462621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 2472621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 24888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 2498d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->start(); 25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 253b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 254b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 2558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->stop(); 25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2621e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatus_t JMediaCodec::reset() { 2631e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar return mCodec->reset(); 2641e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar} 2651e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 268bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags, 269bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 270bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return mCodec->queueInputBuffer( 271bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timeUs, flags, errorDetailMsg); 27288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 27388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer( 2759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t index, 2769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t offset, 2779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const CryptoPlugin::SubSample *subSamples, 2789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t numSubSamples, 2799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t key[16], 2809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t iv[16], 2819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::Mode mode, 2829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber int64_t presentationTimeUs, 283bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber uint32_t flags, 284bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 2859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return mCodec->queueSecureInputBuffer( 2869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, subSamples, numSubSamples, key, iv, mode, 287bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber presentationTimeUs, flags, errorDetailMsg); 2889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 2899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 2918d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->dequeueInputBuffer(index, timeoutUs); 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 299aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber status_t err = mCodec->dequeueOutputBuffer( 300aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber index, &offset, &size, &timeUs, &flags, timeoutUs); 301aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 302aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber if (err != OK) { 30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3068d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 3078d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$BufferInfo")); 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3098d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 310fef85ef152ab176fd96dbe3047c8025136fa8560Ashok Bhat env->CallVoidMethod(bufferInfo, method, (jint)offset, (jint)size, timeUs, flags); 31188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3157c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnarstatus_t JMediaCodec::releaseOutputBuffer( 3167c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar size_t index, bool render, bool updatePTS, int64_t timestampNs) { 3177c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar if (updatePTS) { 3187c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar return mCodec->renderOutputBufferAndRelease(index, timestampNs); 3197c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar } 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3252621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() { 3262621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->signalEndOfInputStream(); 3272621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 3282621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 329d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getFormat(JNIEnv *env, bool input, jobject *format) const { 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 332d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar err = input ? mCodec->getInputFormat(&msg) : mCodec->getOutputFormat(&msg); 333d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != OK) { 334d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return err; 335d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 336d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 337d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return ConvertMessageToMap(env, msg, format); 338d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 339d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 340d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, size_t index, jobject *format) const { 341d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<AMessage> msg; 342d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err; 343d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if ((err = mCodec->getOutputFormat(index, &msg)) != OK) { 34488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 34588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber Vector<sp<ABuffer> > buffers; 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 3647de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar buffers.size(), mByteBufferClass, NULL); 365cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (*bufArray == NULL) { 366cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 367cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ABuffer> &buffer = buffers.itemAt(i); 37188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject byteBuffer = NULL; 3737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 3747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, true /* clearBuffer */, buffer, &byteBuffer); 3757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 3767de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return err; 377cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 3787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (byteBuffer != NULL) { 3797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->SetObjectArrayElement( 3807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *bufArray, i, byteBuffer); 3817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 382d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(byteBuffer); 3837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 384d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3907de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar// static 3917de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::createByteBufferFromABuffer( 3927de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar JNIEnv *env, bool readOnly, bool clearBuffer, const sp<ABuffer> &buffer, 3937de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject *buf) const { 394d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if this is an ABuffer that doesn't actually hold any accessible memory, 395d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // use a null ByteBuffer 3967de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = NULL; 397d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (buffer->base() == NULL) { 398d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 399d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 400d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 401d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject byteBuffer = 4027de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->NewDirectByteBuffer(buffer->base(), buffer->capacity()); 4037de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (readOnly && byteBuffer != NULL) { 404d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject readOnlyBuffer = env->CallObjectMethod( 4057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferAsReadOnlyBufferMethodID); 406d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(byteBuffer); 407d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar byteBuffer = readOnlyBuffer; 408d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 409d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (byteBuffer == NULL) { 410d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NO_MEMORY; 411d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 412d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject me = env->CallObjectMethod( 4137de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferOrderMethodID, mNativeByteOrderObj); 414d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(me); 415d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar me = env->CallObjectMethod( 4167de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferLimitMethodID, 4177de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar clearBuffer ? buffer->capacity() : (buffer->offset() + buffer->size())); 418d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(me); 4197be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar me = env->CallObjectMethod( 4207de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferPositionMethodID, 4217de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar clearBuffer ? 0 : buffer->offset()); 4227be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar env->DeleteLocalRef(me); 423d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar me = NULL; 424d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 425d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar *buf = byteBuffer; 426d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 427d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 428d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 4297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::getBuffer( 4307de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar JNIEnv *env, bool input, size_t index, jobject *buf) const { 4317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar sp<ABuffer> buffer; 4327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar status_t err = 4347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar input 4357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ? mCodec->getInputBuffer(index, &buffer) 4367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar : mCodec->getOutputBuffer(index, &buffer); 4377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 4397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return err; 4407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 4417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return createByteBufferFromABuffer( 4437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, input /* clearBuffer */, buffer, buf); 4447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 4457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 446d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getImage( 447d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, bool input, size_t index, jobject *buf) const { 448d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<ABuffer> buffer; 449d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 450d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = 451d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar input 452d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ? mCodec->getInputBuffer(index, &buffer) 453d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar : mCodec->getOutputBuffer(index, &buffer); 454d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 455d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != OK) { 456d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return err; 457d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 458d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 459d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if this is an ABuffer that doesn't actually hold any accessible memory, 460d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // use a null ByteBuffer 461d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar *buf = NULL; 462d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (buffer->base() == NULL) { 463d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 464d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 465d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 466d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // check if buffer is an image 4677de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar sp<ABuffer> imageData; 4687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (!buffer->meta()->findBuffer("image-data", &imageData)) { 4697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return OK; 4707de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 4717de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar int64_t timestamp = 0; 4737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (!input && buffer->meta()->findInt64("timeUs", ×tamp)) { 4747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar timestamp *= 1000; // adjust to ns 4757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 4767de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject byteBuffer = NULL; 4787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 4797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, input /* clearBuffer */, buffer, &byteBuffer); 4807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 4817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return OK; 4827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 4837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4847de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject infoBuffer = NULL; 4857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 4867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, true /* readOnly */, true /* clearBuffer */, imageData, &infoBuffer); 4877de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 4887de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(byteBuffer); 4897de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 490d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 491d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 492d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 4937de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject cropRect = NULL; 4947de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar int32_t left, top, right, bottom; 4957de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (buffer->meta()->findRect("crop-rect", &left, &top, &right, &bottom)) { 4967de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> rectClazz( 4977de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("android/graphics/Rect")); 4987de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(rectClazz.get() != NULL); 4997de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5007de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID rectConstructID = env->GetMethodID( 5017de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar rectClazz.get(), "<init>", "(IIII)V"); 5027de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5037de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cropRect = env->NewObject( 5047de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar rectClazz.get(), rectConstructID, left, top, right + 1, bottom + 1); 5057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5067de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5077de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> imageClazz( 5087de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("android/media/MediaCodec$MediaImage")); 5097de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(imageClazz.get() != NULL); 5107de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5117de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID imageConstructID = env->GetMethodID(imageClazz.get(), "<init>", 5127de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;ZJIILandroid/graphics/Rect;)V"); 5137de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5147de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = env->NewObject(imageClazz.get(), imageConstructID, 5157de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, infoBuffer, 5167de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jboolean)!input /* readOnly */, 5177de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jlong)timestamp, 5187de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jint)0 /* xOffset */, (jint)0 /* yOffset */, cropRect); 5197de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5207de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar // if MediaImage creation fails, return null 5217de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (env->ExceptionCheck()) { 5227de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->ExceptionDescribe(); 5237de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->ExceptionClear(); 5247de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = NULL; 5257de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5267de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5277de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (cropRect != NULL) { 5287de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(cropRect); 5297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cropRect = NULL; 5307de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(byteBuffer); 5337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 5347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(infoBuffer); 5367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar infoBuffer = NULL; 5377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 538d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 539d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 540d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 541056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const { 542056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo AString name; 543056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 544056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = mCodec->getName(&name); 545056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 546056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err != OK) { 547056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return err; 548056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 549056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 550056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo *nameStr = env->NewStringUTF(name.c_str()); 551056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 552056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return OK; 553056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 554056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 555226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatus_t JMediaCodec::setParameters(const sp<AMessage> &msg) { 556226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return mCodec->setParameters(msg); 557226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 558226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 559b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) { 560b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mSurfaceTextureClient != NULL) { 561b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode); 562b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 563b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 564b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 5655f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic jthrowable createCodecException( 5665f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) { 5675f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung ScopedLocalRef<jclass> clazz( 5685f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, env->FindClass("android/media/MediaCodec$CodecException")); 5695f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(clazz.get() != NULL); 5705f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(IILjava/lang/String;)V"); 5725f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(ctor != NULL); 5735f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5745f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung ScopedLocalRef<jstring> msgObj( 5755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, env->NewStringUTF(msg != NULL ? msg : String8::format("Error %#x", err))); 5765f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5775f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // translate action code to Java equivalent 5785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung switch (actionCode) { 5795f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case ACTION_CODE_TRANSIENT: 5805f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = gCodecActionCodes.codecActionTransient; 5815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 5825f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case ACTION_CODE_RECOVERABLE: 5835f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = gCodecActionCodes.codecActionRecoverable; 5845f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 5855f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung default: 5865f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = 0; // everything else is fatal 5875f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 5885f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } 5895f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5905f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return (jthrowable)env->NewObject(clazz.get(), ctor, err, actionCode, msgObj.get()); 5915f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} 5925f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5938d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::handleCallback(const sp<AMessage> &msg) { 5948d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang int32_t arg1, arg2 = 0; 5958d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject obj = NULL; 5968d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("callbackID", &arg1)); 5978d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang JNIEnv *env = AndroidRuntime::getJNIEnv(); 5988d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 5998d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang switch (arg1) { 6008d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_INPUT_AVAILABLE: 601aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 6028d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("index", &arg2)); 6038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang break; 6048d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6058d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6068d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_OUTPUT_AVAILABLE: 6078d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { 6088d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("index", &arg2)); 6098d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6108d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang size_t size, offset; 6118d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang int64_t timeUs; 6128d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang uint32_t flags; 6138d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findSize("size", &size)); 6148d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findSize("offset", &offset)); 6158d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt64("timeUs", &timeUs)); 6168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("flags", (int32_t *)&flags)); 6178d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6188d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang ScopedLocalRef<jclass> clazz( 6198d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env, env->FindClass("android/media/MediaCodec$BufferInfo")); 6208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "()V"); 6218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 6228d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6238d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang obj = env->NewObject(clazz.get(), ctor); 6248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (obj == NULL) { 6268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (env->ExceptionCheck()) { 6278d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang ALOGE("Could not create MediaCodec.BufferInfo."); 6288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->ExceptionClear(); 6298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6308d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 6318d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 632aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 633aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6348d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->CallVoidMethod(obj, method, (jint)offset, (jint)size, timeUs, flags); 635aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 636aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 637aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6388d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_ERROR: 639aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 64094686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang int32_t err, actionCode; 64194686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang CHECK(msg->findInt32("err", &err)); 6428d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("actionCode", &actionCode)); 643aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6445f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // note that DRM errors could conceivably alias into a CodecException 6455f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung obj = (jobject)createCodecException(env, err, actionCode); 646aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6478d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (obj == NULL) { 6488d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (env->ExceptionCheck()) { 64994686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang ALOGE("Could not create CodecException object."); 6508d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->ExceptionClear(); 6518d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6528d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 6538d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 6548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 655aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 656aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 657aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 658aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 660aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 6618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang sp<AMessage> format; 6628d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findMessage("format", &format)); 663aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6648d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (OK != ConvertMessageToMap(env, format, &obj)) { 6658d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 6668d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 6678d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 668aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 669aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 670aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 671aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 672aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber default: 673aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber TRESPASS(); 674aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 6758d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6768d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->CallVoidMethod( 6778d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mObject, 6788d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang gFields.postEventFromNativeID, 6798d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_CALLBACK, 6808d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang arg1, 6818d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang arg2, 6828d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang obj); 6838d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6848d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->DeleteLocalRef(obj); 685aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 686aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6878d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::onMessageReceived(const sp<AMessage> &msg) { 6888d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang switch (msg->what()) { 6898d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case kWhatCallbackNotify: 6908d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { 6918d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang handleCallback(msg); 6928d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang break; 6938d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6948d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang default: 6958d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang TRESPASS(); 6968d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 697aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 698aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 69988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 70088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 70288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 70488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 70688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 707075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat sp<JMediaCodec> old = (JMediaCodec *)env->GetLongField(thiz, gFields.context); 70888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 70988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 71088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 71188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 712128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang /* release MediaCodec and stop the looper now before decStrong. 713128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * otherwise JMediaCodec::~JMediaCodec() could be called from within 714128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * its message handler, doing release() from there will deadlock 715128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * (as MediaCodec::release() post synchronous message to the same looper) 716128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang */ 717128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang old->release(); 71888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 71988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 720075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, gFields.context, (jlong)codec.get()); 72188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 72388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 72488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 726075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (JMediaCodec *)env->GetLongField(thiz, gFields.context); 72788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 72888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 73088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 73188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 73288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7335f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic void throwCodecException(JNIEnv *env, status_t err, int32_t actionCode, const char *msg) { 7345f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jthrowable exception = createCodecException(env, err, actionCode, msg); 7355f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->Throw(exception); 7365f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} 7375f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 738bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { 7398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 7408d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$CryptoException")); 7418d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 742bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 743bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jmethodID constructID = 7448d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V"); 745bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(constructID != NULL); 746bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 747bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error"); 748bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 7495f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung /* translate OS errors to Java API CryptoException errorCodes (which are positive) */ 7503ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker switch (err) { 7513ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_NO_LICENSE: 7523ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorNoKey; 7533ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 7543ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_LICENSE_EXPIRED: 7553ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorKeyExpired; 7563ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 7573ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_RESOURCE_BUSY: 7583ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorResourceBusy; 7593ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 760336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION: 761336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection; 762336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker break; 7635f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung default: /* Other negative DRM error codes go out as is. */ 7643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 7653ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker } 7663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 767bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jthrowable exception = 7688d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj); 769bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 770bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->Throw(exception); 771bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber} 772bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 773bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary( 7745f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung JNIEnv *env, status_t err, int32_t actionCode = ACTION_CODE_FATAL, 7755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const char *msg = NULL) { 77688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 77788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 77888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 77988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 78188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 78288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 78488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 78588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 78788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 78888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7895f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case INVALID_OPERATION: 7905f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/IllegalStateException", msg); 7915f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 7923ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 79388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 7945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung if (isCryptoError(err)) { 7955f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwCryptoException(env, err, msg); 7965f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 7975f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } 7985f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwCodecException(env, err, actionCode, msg); 7995f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 80088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 80188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 80288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatic void android_media_MediaCodec_native_setCallback( 8048d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang JNIEnv *env, 8058d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject thiz, 8068d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject cb) { 8078d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang sp<JMediaCodec> codec = getMediaCodec(env, thiz); 8088d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 8098d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (codec == NULL) { 8105f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 8118d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 8128d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 8138d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 8148d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang status_t err = codec->setCallback(cb); 8158d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 8168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang throwExceptionAsNecessary(env, err); 8178d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang} 8188d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 81988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 82088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 82188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 82288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 82388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 8248240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jobject jcrypto, 82588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 82688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 82788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 82888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 8295f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 83088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 83188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 83288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 83388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 83488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 83588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 83688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 83788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 83888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 83988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 84088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 841d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> bufferProducer; 84288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 84364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 84488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 84552800617946c456e78ed010c82d0ec4358368164Mathias Agopian bufferProducer = surface->getIGraphicBufferProducer(); 84688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 84788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 84888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 84988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 85088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 85188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 85288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 85388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 85488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8558240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto; 8568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto != NULL) { 8578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto = JCrypto::GetCrypto(env, jcrypto); 8588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 8598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 860d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden err = codec->configure(format, bufferProducer, crypto, flags); 86188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 86288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 86388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 86488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8652621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env, 8662621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 8672621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_createInputSurface"); 8682621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 8692621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 8702621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 8715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 8722621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 8732621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 8742621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 8752621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Tell the MediaCodec that we want to use a Surface as input. 8762621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer> bufferProducer; 8772621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->createInputSurface(&bufferProducer); 8782621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (err != NO_ERROR) { 8792621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 8802621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 8812621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 8822621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 8832621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Wrap the IGBP in a Java-language Surface. 8842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return android_view_Surface_createFromIGraphicBufferProducer(env, 8852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden bufferProducer); 8862621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 8872621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 88888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 88988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 89088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 89188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 89288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 89388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 8945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 89588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 89688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 89788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 89888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 89988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9005f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, "start failed"); 90188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 90288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 90488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 90588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 90788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9095f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 91088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 91188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 91288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 91488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 91688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 91788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9181e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatic void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) { 9191e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar ALOGV("android_media_MediaCodec_reset"); 9201e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 9211e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 9221e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 9231e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar if (codec == NULL) { 9245f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 9251e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar return; 9261e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar } 9271e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 9281e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar status_t err = codec->reset(); 9291e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar if (err != OK) { 9301e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar // treat all errors as fatal for now, though resource not available 9311e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar // errors could be treated as transient. 9325f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // we also should avoid sending INVALID_OPERATION here due to 9335f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // the transitory nature of reset(), it should not inadvertently 9345f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // trigger an IllegalStateException. 9355f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung err = UNKNOWN_ERROR; 9361e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar } 9371e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar throwExceptionAsNecessary(env, err); 9381e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar} 9391e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 94088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 94188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 94288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 94388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 94488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 94588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9465f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 94788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 94888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 94988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 95188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 95388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 95488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 95688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 95788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 95888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 95988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 96088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 96188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 96288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 96388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 96488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 96588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 96688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 96788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9685f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 96988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 97088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 97188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 972bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 973bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 97488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 975bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timestampUs, flags, &errorDetailMsg); 97688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 977bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 9785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 97988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 98088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer( 9829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber JNIEnv *env, 9839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jobject thiz, 9849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint index, 9859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint offset, 98691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jobject cryptoInfoObj, 9879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jlong timestampUs, 9889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint flags) { 9899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ALOGV("android_media_MediaCodec_queueSecureInputBuffer"); 9909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 9919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 9929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 9939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (codec == NULL) { 9945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 9959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return; 9969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 9979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 99891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint numSubSamples = 99991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); 100091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 100191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfClearDataObj = 100291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 100391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); 100491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 100591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfEncryptedDataObj = 100691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 100791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); 100891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 100991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray keyObj = 101091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); 101191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 101291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray ivObj = 101391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); 101491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 101591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); 101691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 10179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber status_t err = OK; 10189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::SubSample *subSamples = NULL; 10209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *key = NULL; 10219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *iv = NULL; 10229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numSubSamples <= 0) { 10249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 10259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj == NULL 10269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && numBytesOfEncryptedDataObj == NULL) { 10279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 10289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfEncryptedDataObj != NULL 10299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { 10309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 10319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj != NULL 10329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { 10339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 10347ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar // subSamples array may silently overflow if number of samples are too large. Use 10357ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms 10365f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } else if ( CC_UNLIKELY(numSubSamples >= (signed)(INT32_MAX / sizeof(*subSamples))) ) { 10377ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar err = -EINVAL; 10389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 10399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 10409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfClearData = 10429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearDataObj == NULL) 10439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 10449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); 10459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfEncryptedData = 10479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedDataObj == NULL) 10489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 10499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); 10509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = new CryptoPlugin::SubSample[numSubSamples]; 10529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber for (jint i = 0; i < numSubSamples; ++i) { 10549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfClearData = 10559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; 10569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10579e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfEncryptedData = 10589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedData == NULL) 10599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? 0 : numBytesOfEncryptedData[i]; 10609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfEncryptedData != NULL) { 10639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 10649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); 10659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedData = NULL; 10669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfClearData != NULL) { 10699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 10709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearDataObj, numBytesOfClearData, 0); 10719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearData = NULL; 10729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && keyObj != NULL) { 10769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(keyObj) != 16) { 10779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 10789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 10799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 10809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = env->GetByteArrayElements(keyObj, &isCopy); 10819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && ivObj != NULL) { 10859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(ivObj) != 16) { 10869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 10879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 10889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 10899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = env->GetByteArrayElements(ivObj, &isCopy); 10909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1093bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 1094bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 10959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK) { 10969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = codec->queueSecureInputBuffer( 10979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, 10989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples, numSubSamples, 10999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (const uint8_t *)key, (const uint8_t *)iv, 11009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (CryptoPlugin::Mode)mode, 1101bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber timestampUs, 1102bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber flags, 1103bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber &errorDetailMsg); 11049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 11059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 11069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (iv != NULL) { 11079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(ivObj, iv, 0); 11089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = NULL; 11099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 11109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 11119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (key != NULL) { 11129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(keyObj, key, 0); 11139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = NULL; 11149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 11159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 11169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber delete[] subSamples; 11179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = NULL; 11189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1119bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 11205f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 11219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 11229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 112388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 112488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 112588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 112688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 112788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 112888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 112988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11305f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 113188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 113288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 113388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 113488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 113588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 113688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 113788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 1138075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 113988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 114088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 114188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 114288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 114388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 114488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 114588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 114688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 114788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 114888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 114988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 115088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 11520e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber return 0; 115388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 115488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 115588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 115688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 115788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 115888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 115988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 1160075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 116188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 116288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 116388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 116488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 116588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 116688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 11677c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar JNIEnv *env, jobject thiz, 11687c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar jint index, jboolean render, jboolean updatePTS, jlong timestampNs) { 116988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 117088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 117188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 117288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 117388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11745f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 117588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 117688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 117788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11787c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs); 117988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 118088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 118188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 118288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11832621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env, 11842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 11852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_signalEndOfInputStream"); 11862621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11872621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 11882621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 11895f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 11902621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return; 11912621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 11922621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11932621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->signalEndOfInputStream(); 11942621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11952621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 11962621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 11972621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1198d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getFormatNative( 1199d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input) { 1200d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getFormatNative"); 1201d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1202d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1203d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1204d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 12055f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1206d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1207d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1208d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1209d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject format; 1210d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getFormat(env, input, &format); 1211d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1212d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1213d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return format; 1214d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1215d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1216d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1217d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1218d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1219d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1220d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1221d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getOutputFormatForIndexNative( 1222d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jint index) { 1223d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getOutputFormatForIndexNative"); 122488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 122588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 122688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 122788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12285f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 122988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 123088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 123188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 1233d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getOutputFormat(env, index, &format); 123488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 123688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 123788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 123888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 124088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 124288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 124388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 124588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 124688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 124788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 124988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 125288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 125388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 125488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 125688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 125788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 125988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 126088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 126188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1262cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if we're out of memory, an exception was already thrown 1263cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (err != NO_MEMORY) { 1264cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen throwExceptionAsNecessary(env, err); 1265cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 126688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 126788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 126888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 126988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1270d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getBuffer( 1271d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input, jint index) { 1272d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getBuffer"); 1273d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1274d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1275d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1276d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 12775f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1278d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1279d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1280d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1281d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject buffer; 1282d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getBuffer(env, input, index, &buffer); 1283d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1284d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1285d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return buffer; 1286d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1287d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1288d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if we're out of memory, an exception was already thrown 1289d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != NO_MEMORY) { 1290d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1291d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1292d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1293d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1294d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1295d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1296d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getImage( 1297d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input, jint index) { 1298d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getImage"); 1299d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1300d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1301d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1302d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 13035f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1304d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1305d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1306d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1307d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject image; 1308d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getImage(env, input, index, &image); 1309d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1310d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1311d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return image; 1312d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1313d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1314d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if we're out of memory, an exception was already thrown 1315d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != NO_MEMORY) { 1316d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1317d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1318d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1319d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1320d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1321d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1322056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName( 1323056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo JNIEnv *env, jobject thiz) { 1324056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo ALOGV("android_media_MediaCodec_getName"); 1325056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1326056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1327056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1328056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (codec == NULL) { 13295f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1330056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 1331056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 1332056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1333056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jstring name; 1334056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = codec->getName(env, &name); 1335056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1336056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err == OK) { 1337056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return name; 1338056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 1339056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1340056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo throwExceptionAsNecessary(env, err); 1341056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1342056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 1343056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 1344056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1345226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatic void android_media_MediaCodec_setParameters( 1346226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) { 1347226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber ALOGV("android_media_MediaCodec_setParameters"); 1348226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1349226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1350226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1351226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (codec == NULL) { 13525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1353226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return; 1354226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 1355226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1356226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<AMessage> params; 1357226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, ¶ms); 1358226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1359226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (err == OK) { 1360226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber err = codec->setParameters(params); 1361226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 1362226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1363226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber throwExceptionAsNecessary(env, err); 1364226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 1365226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1366b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode( 1367b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber JNIEnv *env, jobject thiz, jint mode) { 1368b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1369b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1370b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (codec == NULL) { 13715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1372b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 1373b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 1374b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1375b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW 1376b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 1377b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/InvalidArgumentException", NULL); 1378b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 1379b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 1380b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1381b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber codec->setVideoScalingMode(mode); 1382b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 1383b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 138488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 13858d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 13868d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec")); 13878d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 138888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1389075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J"); 139088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 139191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 1392aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber gFields.postEventFromNativeID = 1393aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber env->GetMethodID( 1394aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V"); 1395aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 1396aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber CHECK(gFields.postEventFromNativeID != NULL); 1397aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 13988d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo")); 13998d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 140091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 140191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumSubSamplesID = 14028d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numSubSamples", "I"); 140391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumSubSamplesID != NULL); 140491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 140591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfClearDataID = 14068d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I"); 140791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL); 140891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 140991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfEncryptedDataID = 14108d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I"); 141191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL); 141291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 14138d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B"); 141491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoKeyID != NULL); 141591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 14168d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B"); 141791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoIVID != NULL); 141891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 14198d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I"); 142091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoModeID != NULL); 14213ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 14228d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException")); 14238d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 14243ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 14253ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jfieldID field; 14268d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I"); 14273ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 14288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorNoKey = 14298d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 14303ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 14318d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I"); 14323ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 14338d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorKeyExpired = 14348d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 14353ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 14368d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I"); 14373ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 14388d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorResourceBusy = 14398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 14405f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 1441336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_OUTPUT_PROTECTION", "I"); 1442336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker CHECK(field != NULL); 1443336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection = 1444336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker env->GetStaticIntField(clazz.get(), field); 1445336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker 14465f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung clazz.reset(env->FindClass("android/media/MediaCodec$CodecException")); 14475f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(clazz.get() != NULL); 14485f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I"); 14495f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(field != NULL); 14505f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung gCodecActionCodes.codecActionTransient = 14515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->GetStaticIntField(clazz.get(), field); 14525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 14535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung field = env->GetStaticFieldID(clazz.get(), "ACTION_RECOVERABLE", "I"); 14545f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(field != NULL); 14555f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung gCodecActionCodes.codecActionRecoverable = 14565f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->GetStaticIntField(clazz.get(), field); 145788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 145888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 145988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 146088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 146188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 146288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 14635f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/NullPointerException", NULL); 146488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 146588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 146688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 146788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 146888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 146988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 147088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 147188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 147288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 147388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 147488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const status_t err = codec->initCheck(); 14765f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung if (err == NAME_NOT_FOUND) { 14775f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // fail and do not try again. 14785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/IllegalArgumentException", 14795f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung String8::format("Failed to initialize %s, error %#x", tmp, err)); 14805f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 14815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return; 14825f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } else if (err != OK) { 14835f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // believed possible to try again 14845f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/io/IOException", 14855f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung String8::format("Failed to find matching codec %s, error %#x", tmp, err)); 14865f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 148788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 148888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 148988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14905f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 14915f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 1492aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber codec->registerSelf(); 1493aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 149488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 149588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 149688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 149788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 149888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 149988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 150088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 150188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 150288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = { 1503d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_release", "()V", (void *)android_media_MediaCodec_release }, 150488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15051e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar { "native_reset", "()V", (void *)android_media_MediaCodec_reset }, 15061e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 15078d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { "native_setCallback", 15088d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang "(Landroid/media/MediaCodec$Callback;)V", 15098d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang (void *)android_media_MediaCodec_native_setCallback }, 15108d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 151188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 15128240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;" 151307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber "Landroid/media/MediaCrypto;I)V", 151488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 151588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15162621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "createInputSurface", "()Landroid/view/Surface;", 15172621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_createInputSurface }, 15182621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1519d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_start", "()V", (void *)android_media_MediaCodec_start }, 1520aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { "native_stop", "()V", (void *)android_media_MediaCodec_stop }, 1521d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_flush", "()V", (void *)android_media_MediaCodec_flush }, 152288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1523d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_queueInputBuffer", "(IIIJI)V", 152488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 152588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1526d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", 15279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (void *)android_media_MediaCodec_queueSecureInputBuffer }, 15289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1529d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_dequeueInputBuffer", "(J)I", 153088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 153188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1532d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 153388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 153488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15357c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar { "releaseOutputBuffer", "(IZZJ)V", 153688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 153788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15382621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "signalEndOfInputStream", "()V", 15392621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_signalEndOfInputStream }, 15402621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1541d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getFormatNative", "(Z)Ljava/util/Map;", 1542d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getFormatNative }, 1543d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1544d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getOutputFormatNative", "(I)Ljava/util/Map;", 1545d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getOutputFormatForIndexNative }, 154688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 154788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 154888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 154988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1550d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getBuffer", "(ZI)Ljava/nio/ByteBuffer;", 1551d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getBuffer }, 1552d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1553d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getImage", "(ZI)Landroid/media/Image;", 1554d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getImage }, 1555d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1556056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo { "getName", "()Ljava/lang/String;", 1557056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo (void *)android_media_MediaCodec_getName }, 1558056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1559226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V", 1560226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber (void *)android_media_MediaCodec_setParameters }, 1561226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1562b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber { "setVideoScalingMode", "(I)V", 1563b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber (void *)android_media_MediaCodec_setVideoScalingMode }, 1564b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 156588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 156688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 156788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 156888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 156988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 157088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 157188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 157288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 157388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 157488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 157588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 157688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 157788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 1578