android_media_MediaCodec.cpp revision 9e9ec943ce7620bbfcadc2f8986a80ac58003e47
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 739e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wustatic struct ExceptionReason { 749e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu jint reasonHardware; 759e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu jint reasonReclaimed; 769e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu} gExceptionReason; 779e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 80aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber jmethodID postEventFromNativeID; 8191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumSubSamplesID; 8291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfClearDataID; 8391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfEncryptedDataID; 8491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoKeyID; 8591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoIVID; 8691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoModeID; 8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 9288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 978d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mObject(NULL) { 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 9988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 10088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1047de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cacheJavaObjects(env); 1057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 10688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 111aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber true, // canCallJava 1128d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber PRIORITY_FOREGROUND); 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 1155f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus); 11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 1175f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus); 11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 1195f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK((mCodec != NULL) != (mInitStatus != OK)); 12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1227de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::cacheJavaObjects(JNIEnv *env) { 1237de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jclass clazz = (jclass)env->FindClass("java/nio/ByteBuffer"); 1247de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass = (jclass)env->NewGlobalRef(clazz); 1257de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferClass != NULL); 1267de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1277de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> byteOrderClass( 1287de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("java/nio/ByteOrder")); 1297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(byteOrderClass.get() != NULL); 1307de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID nativeOrderID = env->GetStaticMethodID( 1327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;"); 1337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(nativeOrderID != NULL); 1347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject nativeByteOrderObj = 1367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID); 1377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mNativeByteOrderObj = env->NewGlobalRef(nativeByteOrderObj); 1387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mNativeByteOrderObj != NULL); 1397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(nativeByteOrderObj); 1407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar nativeByteOrderObj = NULL; 1417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferOrderMethodID = env->GetMethodID( 1437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, 1447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "order", 1457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); 1467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferOrderMethodID != NULL); 1477de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferAsReadOnlyBufferMethodID = env->GetMethodID( 1497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;"); 1507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferAsReadOnlyBufferMethodID != NULL); 1517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1527de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferPositionMethodID = env->GetMethodID( 1537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "position", "(I)Ljava/nio/Buffer;"); 1547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferPositionMethodID != NULL); 1557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1567de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferLimitMethodID = env->GetMethodID( 1577de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "limit", "(I)Ljava/nio/Buffer;"); 1587de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferLimitMethodID != NULL); 1597de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 1607de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 16188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 1625f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return mInitStatus; 16388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 16488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 165aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Hubervoid JMediaCodec::registerSelf() { 166aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber mLooper->registerHandler(this); 167aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 168aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 169128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhangvoid JMediaCodec::release() { 170d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo if (mCodec != NULL) { 171d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec->release(); 172d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec.clear(); 1735f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mInitStatus = NO_INIT; 174d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo } 17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 176128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang if (mLooper != NULL) { 177128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper->unregisterHandler(id()); 178128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper->stop(); 179128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper.clear(); 180128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang } 181128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang} 182128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang 183128b012cc8c2369136bb8450bc91c81aebe18506Chong ZhangJMediaCodec::~JMediaCodec() { 184128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang if (mCodec != NULL || mLooper != NULL) { 185128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang /* MediaCodec and looper should have been released explicitly already 186128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * in setMediaCodec() (see comments in setMediaCodec()). 187128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * 188128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * Otherwise JMediaCodec::~JMediaCodec() might be called from within the 189128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * message handler, doing release() there risks deadlock as MediaCodec:: 190128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * release() post synchronous message to the same looper. 191128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * 192128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * Print a warning and try to proceed with releasing. 193128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang */ 194128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()..."); 195128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang release(); 196128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec()."); 197128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang } 198128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 20388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 2057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar deleteJavaObjects(env); 2067de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 2077de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 2087de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::deleteJavaObjects(JNIEnv *env) { 2097de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteGlobalRef(mByteBufferClass); 2107de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass = NULL; 2117de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteGlobalRef(mNativeByteOrderObj); 2127de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mNativeByteOrderObj = NULL; 2137de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 2147de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferOrderMethodID = NULL; 2157de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferAsReadOnlyBufferMethodID = NULL; 2167de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferPositionMethodID = NULL; 2177de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferLimitMethodID = NULL; 21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatus_t JMediaCodec::setCallback(jobject cb) { 2218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (cb != NULL) { 2228d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (mCallbackNotification == NULL) { 22363834f4d23a97b27d830a301328329c7ef682bd5Lajos Molnar mCallbackNotification = new AMessage(kWhatCallbackNotify, this); 2248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 2258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } else { 2268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mCallbackNotification.clear(); 2278d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 2288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 2298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->setCallback(mCallbackNotification); 2308d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang} 2318d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 23288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 23388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 234d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden const sp<IGraphicBufferProducer> &bufferProducer, 2358240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const sp<ICrypto> &crypto, 23688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 23752800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> client; 238d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden if (bufferProducer != NULL) { 239aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber mSurfaceTextureClient = 240aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber new Surface(bufferProducer, true /* controlledByApp */); 241b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } else { 242b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 244b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 245b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return mCodec->configure(format, mSurfaceTextureClient, crypto, flags); 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2482621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface( 2492621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 2502621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->createInputSurface(bufferProducer); 2512621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 2522621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 2548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->start(); 25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 258b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 259b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 2608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->stop(); 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2671e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatus_t JMediaCodec::reset() { 2681e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar return mCodec->reset(); 2691e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar} 2701e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 27188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 27288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 273bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags, 274bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 275bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return mCodec->queueInputBuffer( 276bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timeUs, flags, errorDetailMsg); 27788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 27888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer( 2809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t index, 2819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t offset, 2829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const CryptoPlugin::SubSample *subSamples, 2839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t numSubSamples, 2849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t key[16], 2859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t iv[16], 2869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::Mode mode, 2879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber int64_t presentationTimeUs, 288bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber uint32_t flags, 289bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 2909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return mCodec->queueSecureInputBuffer( 2919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, subSamples, numSubSamples, key, iv, mode, 292bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber presentationTimeUs, flags, errorDetailMsg); 2939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 2949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 2968d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->dequeueInputBuffer(index, timeoutUs); 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 304aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber status_t err = mCodec->dequeueOutputBuffer( 305aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber index, &offset, &size, &timeUs, &flags, timeoutUs); 306aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 307aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber if (err != OK) { 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3118d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 3128d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$BufferInfo")); 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3148d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 315fef85ef152ab176fd96dbe3047c8025136fa8560Ashok Bhat env->CallVoidMethod(bufferInfo, method, (jint)offset, (jint)size, timeUs, flags); 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3207c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnarstatus_t JMediaCodec::releaseOutputBuffer( 3217c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar size_t index, bool render, bool updatePTS, int64_t timestampNs) { 3227c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar if (updatePTS) { 3237c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar return mCodec->renderOutputBufferAndRelease(index, timestampNs); 3247c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar } 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3302621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() { 3312621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->signalEndOfInputStream(); 3322621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 3332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 334d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getFormat(JNIEnv *env, bool input, jobject *format) const { 33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 337d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar err = input ? mCodec->getInputFormat(&msg) : mCodec->getOutputFormat(&msg); 338d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != OK) { 339d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return err; 340d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 341d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 342d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return ConvertMessageToMap(env, msg, format); 343d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 344d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 345d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, size_t index, jobject *format) const { 346d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<AMessage> msg; 347d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err; 348d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if ((err = mCodec->getOutputFormat(index, &msg)) != OK) { 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber Vector<sp<ABuffer> > buffers; 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 36588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 3697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar buffers.size(), mByteBufferClass, NULL); 370cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (*bufArray == NULL) { 371cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 372cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 37388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 37588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ABuffer> &buffer = buffers.itemAt(i); 37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject byteBuffer = NULL; 3787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 3797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, true /* clearBuffer */, buffer, &byteBuffer); 3807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 3817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return err; 382cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 3837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (byteBuffer != NULL) { 3847de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->SetObjectArrayElement( 3857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *bufArray, i, byteBuffer); 3867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 387d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(byteBuffer); 3887de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 389d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 39388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 39488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3957de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar// static 3967de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::createByteBufferFromABuffer( 3977de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar JNIEnv *env, bool readOnly, bool clearBuffer, const sp<ABuffer> &buffer, 3987de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject *buf) const { 399d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if this is an ABuffer that doesn't actually hold any accessible memory, 400d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // use a null ByteBuffer 4017de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = NULL; 402d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (buffer->base() == NULL) { 403d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 404d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 405d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 406d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject byteBuffer = 4077de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->NewDirectByteBuffer(buffer->base(), buffer->capacity()); 4087de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (readOnly && byteBuffer != NULL) { 409d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject readOnlyBuffer = env->CallObjectMethod( 4107de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferAsReadOnlyBufferMethodID); 411d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(byteBuffer); 412d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar byteBuffer = readOnlyBuffer; 413d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 414d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (byteBuffer == NULL) { 415d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NO_MEMORY; 416d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 417d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject me = env->CallObjectMethod( 4187de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferOrderMethodID, mNativeByteOrderObj); 419d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(me); 420d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar me = env->CallObjectMethod( 4217de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferLimitMethodID, 4227de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar clearBuffer ? buffer->capacity() : (buffer->offset() + buffer->size())); 423d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(me); 4247be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar me = env->CallObjectMethod( 4257de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferPositionMethodID, 4267de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar clearBuffer ? 0 : buffer->offset()); 4277be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar env->DeleteLocalRef(me); 428d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar me = NULL; 429d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 430d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar *buf = byteBuffer; 431d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 432d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 433d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 4347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::getBuffer( 4357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar JNIEnv *env, bool input, size_t index, jobject *buf) const { 4367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar sp<ABuffer> buffer; 4377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar status_t err = 4397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar input 4407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ? mCodec->getInputBuffer(index, &buffer) 4417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar : mCodec->getOutputBuffer(index, &buffer); 4427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 4447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return err; 4457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 4467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4477de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return createByteBufferFromABuffer( 4487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, input /* clearBuffer */, buffer, buf); 4497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 4507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 451d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getImage( 452d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, bool input, size_t index, jobject *buf) const { 453d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<ABuffer> buffer; 454d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 455d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = 456d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar input 457d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ? mCodec->getInputBuffer(index, &buffer) 458d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar : mCodec->getOutputBuffer(index, &buffer); 459d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 460d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != OK) { 461d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return err; 462d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 463d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 464d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if this is an ABuffer that doesn't actually hold any accessible memory, 465d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // use a null ByteBuffer 466d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar *buf = NULL; 467d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (buffer->base() == NULL) { 468d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 469d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 470d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 471d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // check if buffer is an image 4727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar sp<ABuffer> imageData; 4737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (!buffer->meta()->findBuffer("image-data", &imageData)) { 4747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return OK; 4757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 4767de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar int64_t timestamp = 0; 4787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (!input && buffer->meta()->findInt64("timeUs", ×tamp)) { 4797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar timestamp *= 1000; // adjust to ns 4807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 4817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject byteBuffer = NULL; 4837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 4847de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, input /* clearBuffer */, buffer, &byteBuffer); 4857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 4867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return OK; 4877de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 4887de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4897de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject infoBuffer = NULL; 4907de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 4917de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, true /* readOnly */, true /* clearBuffer */, imageData, &infoBuffer); 4927de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 4937de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(byteBuffer); 4947de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 495d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 496d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 497d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 4987de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject cropRect = NULL; 4997de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar int32_t left, top, right, bottom; 5007de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (buffer->meta()->findRect("crop-rect", &left, &top, &right, &bottom)) { 5017de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> rectClazz( 5027de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("android/graphics/Rect")); 5037de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(rectClazz.get() != NULL); 5047de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID rectConstructID = env->GetMethodID( 5067de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar rectClazz.get(), "<init>", "(IIII)V"); 5077de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5087de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cropRect = env->NewObject( 5097de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar rectClazz.get(), rectConstructID, left, top, right + 1, bottom + 1); 5107de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5117de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5127de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> imageClazz( 5137de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("android/media/MediaCodec$MediaImage")); 5147de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(imageClazz.get() != NULL); 5157de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5167de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID imageConstructID = env->GetMethodID(imageClazz.get(), "<init>", 5177de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;ZJIILandroid/graphics/Rect;)V"); 5187de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5197de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = env->NewObject(imageClazz.get(), imageConstructID, 5207de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, infoBuffer, 5217de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jboolean)!input /* readOnly */, 5227de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jlong)timestamp, 5237de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jint)0 /* xOffset */, (jint)0 /* yOffset */, cropRect); 5247de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5257de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar // if MediaImage creation fails, return null 5267de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (env->ExceptionCheck()) { 5277de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->ExceptionDescribe(); 5287de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->ExceptionClear(); 5297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = NULL; 5307de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (cropRect != NULL) { 5337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(cropRect); 5347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cropRect = NULL; 5357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(byteBuffer); 5387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 5397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(infoBuffer); 5417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar infoBuffer = NULL; 5427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 543d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 544d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 545d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 546056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const { 547056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo AString name; 548056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 549056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = mCodec->getName(&name); 550056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 551056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err != OK) { 552056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return err; 553056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 554056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 555056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo *nameStr = env->NewStringUTF(name.c_str()); 556056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 557056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return OK; 558056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 559056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 560226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatus_t JMediaCodec::setParameters(const sp<AMessage> &msg) { 561226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return mCodec->setParameters(msg); 562226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 563226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 564b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) { 565b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mSurfaceTextureClient != NULL) { 566b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode); 567b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 568b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 569b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 5705f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic jthrowable createCodecException( 5715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) { 5725f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung ScopedLocalRef<jclass> clazz( 5735f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, env->FindClass("android/media/MediaCodec$CodecException")); 5745f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(clazz.get() != NULL); 5755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5769e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu const jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(IILjava/lang/String;I)V"); 5775f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(ctor != NULL); 5785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5795f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung ScopedLocalRef<jstring> msgObj( 5805f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, env->NewStringUTF(msg != NULL ? msg : String8::format("Error %#x", err))); 5815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5825f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // translate action code to Java equivalent 5835f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung switch (actionCode) { 5845f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case ACTION_CODE_TRANSIENT: 5855f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = gCodecActionCodes.codecActionTransient; 5865f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 5875f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case ACTION_CODE_RECOVERABLE: 5885f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = gCodecActionCodes.codecActionRecoverable; 5895f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 5905f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung default: 5915f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = 0; // everything else is fatal 5925f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 5935f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } 5945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 5959e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu // TODO: propagate reason from MediaCodec. 5969e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu int reason = gExceptionReason.reasonHardware; 5979e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu return (jthrowable)env->NewObject(clazz.get(), ctor, err, actionCode, msgObj.get(), reason); 5985f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} 5995f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 6008d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::handleCallback(const sp<AMessage> &msg) { 6018d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang int32_t arg1, arg2 = 0; 6028d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject obj = NULL; 6038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("callbackID", &arg1)); 6048d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang JNIEnv *env = AndroidRuntime::getJNIEnv(); 6058d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6068d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang switch (arg1) { 6078d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_INPUT_AVAILABLE: 608aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 6098d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("index", &arg2)); 6108d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang break; 6118d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6128d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6138d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_OUTPUT_AVAILABLE: 6148d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { 6158d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("index", &arg2)); 6168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6178d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang size_t size, offset; 6188d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang int64_t timeUs; 6198d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang uint32_t flags; 6208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findSize("size", &size)); 6218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findSize("offset", &offset)); 6228d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt64("timeUs", &timeUs)); 6238d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("flags", (int32_t *)&flags)); 6248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang ScopedLocalRef<jclass> clazz( 6268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env, env->FindClass("android/media/MediaCodec$BufferInfo")); 6278d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "()V"); 6288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 6298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6308d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang obj = env->NewObject(clazz.get(), ctor); 6318d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6328d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (obj == NULL) { 6338d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (env->ExceptionCheck()) { 6348d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang ALOGE("Could not create MediaCodec.BufferInfo."); 6358d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->ExceptionClear(); 6368d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6378d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 6388d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 639aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 640aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6418d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->CallVoidMethod(obj, method, (jint)offset, (jint)size, timeUs, flags); 642aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 643aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 644aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6458d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_ERROR: 646aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 64794686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang int32_t err, actionCode; 64894686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang CHECK(msg->findInt32("err", &err)); 6498d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("actionCode", &actionCode)); 650aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // note that DRM errors could conceivably alias into a CodecException 6525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung obj = (jobject)createCodecException(env, err, actionCode); 653aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (obj == NULL) { 6558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (env->ExceptionCheck()) { 65694686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang ALOGE("Could not create CodecException object."); 6578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->ExceptionClear(); 6588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 6608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 6618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 662aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 663aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 664aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 665aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6668d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 667aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 6688d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang sp<AMessage> format; 6698d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findMessage("format", &format)); 670aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6718d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (OK != ConvertMessageToMap(env, format, &obj)) { 6728d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 6738d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 6748d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 675aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 676aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 677aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 678aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 679aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber default: 680aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber TRESPASS(); 681aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 6828d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6838d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->CallVoidMethod( 6848d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mObject, 6858d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang gFields.postEventFromNativeID, 6868d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_CALLBACK, 6878d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang arg1, 6888d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang arg2, 6898d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang obj); 6908d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6918d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->DeleteLocalRef(obj); 692aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 693aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 6948d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::onMessageReceived(const sp<AMessage> &msg) { 6958d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang switch (msg->what()) { 6968d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case kWhatCallbackNotify: 6978d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { 6988d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang handleCallback(msg); 6998d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang break; 7008d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 7018d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang default: 7028d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang TRESPASS(); 7038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 704aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 705aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 70688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 70788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 70988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 71188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 71388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 714075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat sp<JMediaCodec> old = (JMediaCodec *)env->GetLongField(thiz, gFields.context); 71588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 71688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 71788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 71888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 719128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang /* release MediaCodec and stop the looper now before decStrong. 720128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * otherwise JMediaCodec::~JMediaCodec() could be called from within 721128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * its message handler, doing release() from there will deadlock 722128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * (as MediaCodec::release() post synchronous message to the same looper) 723128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang */ 724128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang old->release(); 72588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 72688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 727075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, gFields.context, (jlong)codec.get()); 72888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 73088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 73188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 733075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (JMediaCodec *)env->GetLongField(thiz, gFields.context); 73488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 73588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 73788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 73888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 73988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7405f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic void throwCodecException(JNIEnv *env, status_t err, int32_t actionCode, const char *msg) { 7415f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jthrowable exception = createCodecException(env, err, actionCode, msg); 7425f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->Throw(exception); 7435f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} 7445f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 745bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { 7468d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 7478d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$CryptoException")); 7488d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 749bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 750bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jmethodID constructID = 7518d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V"); 752bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(constructID != NULL); 753bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 754bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error"); 755bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 7565f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung /* translate OS errors to Java API CryptoException errorCodes (which are positive) */ 7573ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker switch (err) { 7583ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_NO_LICENSE: 7593ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorNoKey; 7603ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 7613ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_LICENSE_EXPIRED: 7623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorKeyExpired; 7633ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 7643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_RESOURCE_BUSY: 7653ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorResourceBusy; 7663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 767336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION: 768336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection; 769336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker break; 7705f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung default: /* Other negative DRM error codes go out as is. */ 7713ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 7723ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker } 7733ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 774bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jthrowable exception = 7758d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj); 776bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 777bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->Throw(exception); 778bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber} 779bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 780bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary( 7815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung JNIEnv *env, status_t err, int32_t actionCode = ACTION_CODE_FATAL, 7825f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const char *msg = NULL) { 78388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 78488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 78588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 78688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 78888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 78988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 79088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 79188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 79288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 79388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 79488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 79588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7965f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case INVALID_OPERATION: 7975f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/IllegalStateException", msg); 7985f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 7993ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 80088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 8015f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung if (isCryptoError(err)) { 8025f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwCryptoException(env, err, msg); 8035f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 8045f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } 8055f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwCodecException(env, err, actionCode, msg); 8065f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 80788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 80888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 80988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8108d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatic void android_media_MediaCodec_native_setCallback( 8118d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang JNIEnv *env, 8128d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject thiz, 8138d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject cb) { 8148d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang sp<JMediaCodec> codec = getMediaCodec(env, thiz); 8158d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 8168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (codec == NULL) { 8175f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 8188d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 8198d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 8208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 8218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang status_t err = codec->setCallback(cb); 8228d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 8238d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang throwExceptionAsNecessary(env, err); 8248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang} 8258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 82688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 82788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 82888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 82988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 83088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 8318240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jobject jcrypto, 83288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 83388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 83488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 83588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 8365f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 83788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 83888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 83988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 84088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 84188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 84288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 84388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 84488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 84588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 84688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 84788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 848d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> bufferProducer; 84988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 85064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 85188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 85252800617946c456e78ed010c82d0ec4358368164Mathias Agopian bufferProducer = surface->getIGraphicBufferProducer(); 85388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 85488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 85588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 85688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 85788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 85888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 85988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 86088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 86188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto; 8638240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto != NULL) { 8648240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto = JCrypto::GetCrypto(env, jcrypto); 8658240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 8668240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 867d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden err = codec->configure(format, bufferProducer, crypto, flags); 86888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 86988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 87088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 87188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8722621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env, 8732621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 8742621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_createInputSurface"); 8752621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 8762621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 8772621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 8785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 8792621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 8802621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 8812621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 8822621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Tell the MediaCodec that we want to use a Surface as input. 8832621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer> bufferProducer; 8842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->createInputSurface(&bufferProducer); 8852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (err != NO_ERROR) { 8862621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 8872621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 8882621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 8892621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 8902621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Wrap the IGBP in a Java-language Surface. 8912621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return android_view_Surface_createFromIGraphicBufferProducer(env, 8922621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden bufferProducer); 8932621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 8942621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 89588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 89688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 89788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 89888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 89988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9015f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 90288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 90388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 90488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 90688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9075f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, "start failed"); 90888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 90988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 91188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 91288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 91488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9165f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 91788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 91888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 91988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 92088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 92188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 92288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 92388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 92488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9251e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatic void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) { 9261e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar ALOGV("android_media_MediaCodec_reset"); 9271e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 9281e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 9291e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 9301e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar if (codec == NULL) { 9315f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 9321e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar return; 9331e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar } 9341e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 9351e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar status_t err = codec->reset(); 9361e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar if (err != OK) { 9371e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar // treat all errors as fatal for now, though resource not available 9381e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar // errors could be treated as transient. 9395f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // we also should avoid sending INVALID_OPERATION here due to 9405f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // the transitory nature of reset(), it should not inadvertently 9415f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // trigger an IllegalStateException. 9425f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung err = UNKNOWN_ERROR; 9431e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar } 9441e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar throwExceptionAsNecessary(env, err); 9451e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar} 9461e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 94788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 94888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 94988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 95188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 95488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 95588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 95688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 95888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 96088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 96188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 96288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 96388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 96488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 96588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 96688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 96788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 96888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 96988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 97088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 97188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 97288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 97388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 97488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 97688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 97788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 97888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 979bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 980bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 98188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 982bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timestampUs, flags, &errorDetailMsg); 98388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 984bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 9855f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 98688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 98788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer( 9899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber JNIEnv *env, 9909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jobject thiz, 9919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint index, 9929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint offset, 99391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jobject cryptoInfoObj, 9949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jlong timestampUs, 9959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint flags) { 9969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ALOGV("android_media_MediaCodec_queueSecureInputBuffer"); 9979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 9989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 9999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (codec == NULL) { 10015f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 10029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return; 10039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 100591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint numSubSamples = 100691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); 100791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 100891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfClearDataObj = 100991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 101091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); 101191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 101291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfEncryptedDataObj = 101391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 101491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); 101591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 101691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray keyObj = 101791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); 101891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 101991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray ivObj = 102091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); 102191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 102291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); 102391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 10249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber status_t err = OK; 10259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::SubSample *subSamples = NULL; 10279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *key = NULL; 10289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *iv = NULL; 10299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numSubSamples <= 0) { 10319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 10329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj == NULL 10339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && numBytesOfEncryptedDataObj == NULL) { 10349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 10359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfEncryptedDataObj != NULL 10369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { 10379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 10389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj != NULL 10399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { 10409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 10417ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar // subSamples array may silently overflow if number of samples are too large. Use 10427ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms 10435f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } else if ( CC_UNLIKELY(numSubSamples >= (signed)(INT32_MAX / sizeof(*subSamples))) ) { 10447ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar err = -EINVAL; 10459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 10469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 10479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfClearData = 10499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearDataObj == NULL) 10509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 10519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); 10529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfEncryptedData = 10549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedDataObj == NULL) 10559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 10569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); 10579e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = new CryptoPlugin::SubSample[numSubSamples]; 10599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber for (jint i = 0; i < numSubSamples; ++i) { 10619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfClearData = 10629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; 10639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfEncryptedData = 10659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedData == NULL) 10669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? 0 : numBytesOfEncryptedData[i]; 10679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfEncryptedData != NULL) { 10709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 10719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); 10729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedData = NULL; 10739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfClearData != NULL) { 10769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 10779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearDataObj, numBytesOfClearData, 0); 10789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearData = NULL; 10799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && keyObj != NULL) { 10839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(keyObj) != 16) { 10849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 10859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 10869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 10879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = env->GetByteArrayElements(keyObj, &isCopy); 10889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 10919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && ivObj != NULL) { 10929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(ivObj) != 16) { 10939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 10949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 10959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 10969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = env->GetByteArrayElements(ivObj, &isCopy); 10979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 10999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1100bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 1101bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 11029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK) { 11039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = codec->queueSecureInputBuffer( 11049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, 11059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples, numSubSamples, 11069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (const uint8_t *)key, (const uint8_t *)iv, 11079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (CryptoPlugin::Mode)mode, 1108bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber timestampUs, 1109bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber flags, 1110bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber &errorDetailMsg); 11119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 11129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 11139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (iv != NULL) { 11149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(ivObj, iv, 0); 11159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = NULL; 11169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 11179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 11189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (key != NULL) { 11199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(keyObj, key, 0); 11209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = NULL; 11219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 11229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 11239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber delete[] subSamples; 11249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = NULL; 11259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1126bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 11275f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 11289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 11299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 113088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 113188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 113288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 113388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 113488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 113588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 113688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11375f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 113888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 113988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 114088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 114188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 114288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 114388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 114488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 1145075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 114688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 114788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 114888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 114988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 115088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 115188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 115288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 115388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 115488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 115588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 115688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 115788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11585f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 11590e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber return 0; 116088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 116188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 116288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 116388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 116488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 116588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 116688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 1167075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 116888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 116988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 117088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 117188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 117288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 117388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 11747c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar JNIEnv *env, jobject thiz, 11757c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar jint index, jboolean render, jboolean updatePTS, jlong timestampNs) { 117688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 117788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 117888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 117988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 118088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 118288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 118388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 118488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11857c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs); 118688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 118788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 118888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 118988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11902621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env, 11912621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 11922621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_signalEndOfInputStream"); 11932621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11942621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 11952621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 11965f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 11972621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return; 11982621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 11992621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 12002621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->signalEndOfInputStream(); 12012621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 12022621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 12032621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 12042621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1205d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getFormatNative( 1206d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input) { 1207d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getFormatNative"); 1208d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1209d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1210d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1211d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 12125f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1213d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1214d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1215d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1216d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject format; 1217d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getFormat(env, input, &format); 1218d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1219d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1220d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return format; 1221d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1222d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1223d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1224d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1225d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1226d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1227d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1228d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getOutputFormatForIndexNative( 1229d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jint index) { 1230d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getOutputFormatForIndexNative"); 123188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 123388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12355f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 123688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 123788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 123888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 1240d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getOutputFormat(env, index, &format); 124188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 124388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 124488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 124588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 124788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 124988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 125088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 125288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 125388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 125488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 125688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12585f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 125988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 126088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 126188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 126288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 126388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 126488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 126588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 126688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 126788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 126888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1269cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if we're out of memory, an exception was already thrown 1270cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (err != NO_MEMORY) { 1271cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen throwExceptionAsNecessary(env, err); 1272cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 127388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 127488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 127588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 127688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1277d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getBuffer( 1278d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input, jint index) { 1279d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getBuffer"); 1280d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1281d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1282d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1283d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 12845f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1285d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1286d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1287d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1288d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject buffer; 1289d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getBuffer(env, input, index, &buffer); 1290d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1291d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1292d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return buffer; 1293d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1294d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1295d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if we're out of memory, an exception was already thrown 1296d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != NO_MEMORY) { 1297d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1298d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1299d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1300d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1301d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1302d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1303d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getImage( 1304d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input, jint index) { 1305d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getImage"); 1306d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1307d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1308d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1309d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 13105f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1311d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1312d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1313d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1314d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject image; 1315d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getImage(env, input, index, &image); 1316d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1317d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1318d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return image; 1319d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1320d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1321d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if we're out of memory, an exception was already thrown 1322d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != NO_MEMORY) { 1323d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1324d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1325d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1326d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1327d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1328d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1329056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName( 1330056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo JNIEnv *env, jobject thiz) { 1331056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo ALOGV("android_media_MediaCodec_getName"); 1332056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1333056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1334056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1335056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (codec == NULL) { 13365f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1337056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 1338056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 1339056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1340056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jstring name; 1341056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = codec->getName(env, &name); 1342056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1343056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err == OK) { 1344056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return name; 1345056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 1346056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1347056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo throwExceptionAsNecessary(env, err); 1348056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1349056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 1350056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 1351056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1352226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatic void android_media_MediaCodec_setParameters( 1353226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) { 1354226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber ALOGV("android_media_MediaCodec_setParameters"); 1355226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1356226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1357226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1358226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (codec == NULL) { 13595f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1360226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return; 1361226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 1362226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1363226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<AMessage> params; 1364226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, ¶ms); 1365226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1366226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (err == OK) { 1367226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber err = codec->setParameters(params); 1368226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 1369226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1370226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber throwExceptionAsNecessary(env, err); 1371226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 1372226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1373b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode( 1374b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber JNIEnv *env, jobject thiz, jint mode) { 1375b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1376b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1377b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (codec == NULL) { 13785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1379b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 1380b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 1381b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1382b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW 1383b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 1384b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/InvalidArgumentException", NULL); 1385b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 1386b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 1387b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1388b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber codec->setVideoScalingMode(mode); 1389b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 1390b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 139188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 13928d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 13938d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec")); 13948d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 139588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1396075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J"); 139788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 139891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 1399aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber gFields.postEventFromNativeID = 1400aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber env->GetMethodID( 1401aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V"); 1402aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 1403aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber CHECK(gFields.postEventFromNativeID != NULL); 1404aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 14058d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo")); 14068d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 140791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 140891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumSubSamplesID = 14098d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numSubSamples", "I"); 141091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumSubSamplesID != NULL); 141191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 141291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfClearDataID = 14138d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I"); 141491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL); 141591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 141691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfEncryptedDataID = 14178d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I"); 141891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL); 141991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 14208d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B"); 142191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoKeyID != NULL); 142291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 14238d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B"); 142491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoIVID != NULL); 142591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 14268d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I"); 142791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoModeID != NULL); 14283ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 14298d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException")); 14308d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 14313ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 14323ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jfieldID field; 14338d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I"); 14343ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 14358d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorNoKey = 14368d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 14373ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 14388d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I"); 14393ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 14408d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorKeyExpired = 14418d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 14423ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 14438d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I"); 14443ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 14458d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorResourceBusy = 14468d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 14475f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 1448336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_OUTPUT_PROTECTION", "I"); 1449336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker CHECK(field != NULL); 1450336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection = 1451336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker env->GetStaticIntField(clazz.get(), field); 1452336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker 14535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung clazz.reset(env->FindClass("android/media/MediaCodec$CodecException")); 14545f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(clazz.get() != NULL); 14555f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I"); 14565f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(field != NULL); 14575f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung gCodecActionCodes.codecActionTransient = 14585f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->GetStaticIntField(clazz.get(), field); 14595f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 14605f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung field = env->GetStaticFieldID(clazz.get(), "ACTION_RECOVERABLE", "I"); 14615f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(field != NULL); 14625f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung gCodecActionCodes.codecActionRecoverable = 14635f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->GetStaticIntField(clazz.get(), field); 14649e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 14659e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu field = env->GetStaticFieldID(clazz.get(), "REASON_HARDWARE", "I"); 14669e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu CHECK(field != NULL); 14679e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu gExceptionReason.reasonHardware = 14689e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu env->GetStaticIntField(clazz.get(), field); 14699e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 14709e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu field = env->GetStaticFieldID(clazz.get(), "REASON_RECLAIMED", "I"); 14719e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu CHECK(field != NULL); 14729e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu gExceptionReason.reasonReclaimed = 14739e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu env->GetStaticIntField(clazz.get(), field); 147488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 147588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 147688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 147788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 147888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 147988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 14805f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/NullPointerException", NULL); 148188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 148288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 148388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 148488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 148588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 148688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 148788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 148888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 148988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 149088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 149188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14925f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const status_t err = codec->initCheck(); 14935f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung if (err == NAME_NOT_FOUND) { 14945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // fail and do not try again. 14955f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/IllegalArgumentException", 14965f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung String8::format("Failed to initialize %s, error %#x", tmp, err)); 14975f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 14985f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return; 14995f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } else if (err != OK) { 15005f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // believed possible to try again 15015f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/io/IOException", 15025f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung String8::format("Failed to find matching codec %s, error %#x", tmp, err)); 15035f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 150488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 150588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 150688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15075f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 15085f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 1509aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber codec->registerSelf(); 1510aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 151188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 151288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 151388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 151488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 151588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 151688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 151788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 151888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 151988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = { 1520d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_release", "()V", (void *)android_media_MediaCodec_release }, 152188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15221e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar { "native_reset", "()V", (void *)android_media_MediaCodec_reset }, 15231e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 15248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { "native_setCallback", 15258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang "(Landroid/media/MediaCodec$Callback;)V", 15268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang (void *)android_media_MediaCodec_native_setCallback }, 15278d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 152888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 15298240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;" 153007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber "Landroid/media/MediaCrypto;I)V", 153188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 153288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "createInputSurface", "()Landroid/view/Surface;", 15342621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_createInputSurface }, 15352621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1536d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_start", "()V", (void *)android_media_MediaCodec_start }, 1537aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { "native_stop", "()V", (void *)android_media_MediaCodec_stop }, 1538d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_flush", "()V", (void *)android_media_MediaCodec_flush }, 153988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1540d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_queueInputBuffer", "(IIIJI)V", 154188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 154288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1543d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", 15449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (void *)android_media_MediaCodec_queueSecureInputBuffer }, 15459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1546d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_dequeueInputBuffer", "(J)I", 154788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 154888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1549d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 155088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 155188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15527c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar { "releaseOutputBuffer", "(IZZJ)V", 155388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 155488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15552621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "signalEndOfInputStream", "()V", 15562621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_signalEndOfInputStream }, 15572621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1558d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getFormatNative", "(Z)Ljava/util/Map;", 1559d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getFormatNative }, 1560d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1561d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getOutputFormatNative", "(I)Ljava/util/Map;", 1562d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getOutputFormatForIndexNative }, 156388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 156488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 156588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 156688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1567d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getBuffer", "(ZI)Ljava/nio/ByteBuffer;", 1568d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getBuffer }, 1569d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1570d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getImage", "(ZI)Landroid/media/Image;", 1571d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getImage }, 1572d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1573056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo { "getName", "()Ljava/lang/String;", 1574056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo (void *)android_media_MediaCodec_getName }, 1575056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1576226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V", 1577226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber (void *)android_media_MediaCodec_setParameters }, 1578226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1579b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber { "setVideoScalingMode", "(I)V", 1580b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber (void *)android_media_MediaCodec_setVideoScalingMode }, 1581b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 158288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 158388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 158488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 158588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 158688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 158788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 158888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 158988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 159088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 159188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 159288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 159388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 159488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 1595