android_media_MediaCodec.cpp revision 4273dd03a83fd5f9ba25f3b7c3a4add7bce7206c
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> 354273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim#include <media/MediaCodecBuffer.h> 3688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaCodec.h> 3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 3888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 3988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ALooper.h> 4088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 41bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber#include <media/stagefright/foundation/AString.h> 4288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h> 438034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang#include <media/stagefright/PersistentSurface.h> 448d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber#include <nativehelper/ScopedLocalRef.h> 458d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 46b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber#include <system/window.h> 47b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android { 4988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!! 5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum { 5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_TRY_AGAIN_LATER = -1, 5388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED = -2, 5488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, 5588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 5688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 57aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huberenum { 588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_CALLBACK = 1, 598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_SET_CALLBACK = 2, 60d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar EVENT_FRAME_RENDERED = 3, 61aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}; 62aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 635f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic struct CryptoErrorCodes { 643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorNoKey; 653ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorKeyExpired; 663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorResourceBusy; 67336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker jint cryptoErrorInsufficientOutputProtection; 6896a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker jint cryptoErrorSessionNotOpened; 69d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker jint cryptoErrorUnsupportedOperation; 703ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker} gCryptoErrorCodes; 713ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 725f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic struct CodecActionCodes { 735f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jint codecActionTransient; 745f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jint codecActionRecoverable; 755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} gCodecActionCodes; 765f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 77c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wustatic struct CodecErrorCodes { 78c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu jint errorInsufficientResource; 79c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu jint errorReclaimed; 80c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu} gCodecErrorCodes; 819e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 828034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic struct { 838034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jclass clazz; 848034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jfieldID mLock; 858034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jfieldID mPersistentObject; 868034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jmethodID ctor; 878034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jmethodID setNativeObjectLocked; 888034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} gPersistentSurfaceClassInfo; 898034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 90d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinkerstatic struct { 91d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jint Unencrypted; 92d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jint AesCtr; 93d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jint AesCbc; 94d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker} gCryptoModes; 95d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 96d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 99aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber jmethodID postEventFromNativeID; 10091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumSubSamplesID; 10191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfClearDataID; 10291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfEncryptedDataID; 10391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoKeyID; 10491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoIVID; 10591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoModeID; 106d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jfieldID cryptoInfoPatternID; 107d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jfieldID patternEncryptBlocksID; 108d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jfieldID patternSkipBlocksID; 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 1128034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic const void *sRefBaseOwner; 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 1208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mObject(NULL) { 12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 12388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1277de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cacheJavaObjects(env); 1287de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 13088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 13388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 134aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber true, // canCallJava 1358d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber PRIORITY_FOREGROUND); 13688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 13788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 1385f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus); 13988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 1405f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus); 14188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 1425f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK((mCodec != NULL) != (mInitStatus != OK)); 14388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::cacheJavaObjects(JNIEnv *env) { 1467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jclass clazz = (jclass)env->FindClass("java/nio/ByteBuffer"); 1477de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass = (jclass)env->NewGlobalRef(clazz); 1487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferClass != NULL); 1497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> byteOrderClass( 1517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("java/nio/ByteOrder")); 1527de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(byteOrderClass.get() != NULL); 1537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID nativeOrderID = env->GetStaticMethodID( 1557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;"); 1567de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(nativeOrderID != NULL); 1577de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1587de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject nativeByteOrderObj = 1597de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID); 1607de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mNativeByteOrderObj = env->NewGlobalRef(nativeByteOrderObj); 1617de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mNativeByteOrderObj != NULL); 1627de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(nativeByteOrderObj); 1637de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar nativeByteOrderObj = NULL; 1647de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1657de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferOrderMethodID = env->GetMethodID( 1667de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, 1677de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "order", 1687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); 1697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferOrderMethodID != NULL); 1707de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1717de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferAsReadOnlyBufferMethodID = env->GetMethodID( 1727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;"); 1737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferAsReadOnlyBufferMethodID != NULL); 1747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferPositionMethodID = env->GetMethodID( 1767de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "position", "(I)Ljava/nio/Buffer;"); 1777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferPositionMethodID != NULL); 1787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferLimitMethodID = env->GetMethodID( 1807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "limit", "(I)Ljava/nio/Buffer;"); 1817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferLimitMethodID != NULL); 1827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 1837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 1855f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return mInitStatus; 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 18788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 188aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Hubervoid JMediaCodec::registerSelf() { 189aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber mLooper->registerHandler(this); 190aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 191aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 192128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhangvoid JMediaCodec::release() { 193d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo if (mCodec != NULL) { 194d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec->release(); 195d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec.clear(); 1965f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mInitStatus = NO_INIT; 197d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo } 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 199128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang if (mLooper != NULL) { 200128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper->unregisterHandler(id()); 201128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper->stop(); 202128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper.clear(); 203128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang } 204128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang} 205128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang 206128b012cc8c2369136bb8450bc91c81aebe18506Chong ZhangJMediaCodec::~JMediaCodec() { 207128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang if (mCodec != NULL || mLooper != NULL) { 208128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang /* MediaCodec and looper should have been released explicitly already 209128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * in setMediaCodec() (see comments in setMediaCodec()). 210128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * 211128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * Otherwise JMediaCodec::~JMediaCodec() might be called from within the 212128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * message handler, doing release() there risks deadlock as MediaCodec:: 213128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * release() post synchronous message to the same looper. 214128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * 215128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * Print a warning and try to proceed with releasing. 216128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang */ 217128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()..."); 218128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang release(); 219128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec()."); 220128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang } 221128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 2287de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar deleteJavaObjects(env); 2297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 2307de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 2317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::deleteJavaObjects(JNIEnv *env) { 2327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteGlobalRef(mByteBufferClass); 2337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass = NULL; 2347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteGlobalRef(mNativeByteOrderObj); 2357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mNativeByteOrderObj = NULL; 2367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 2377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferOrderMethodID = NULL; 2387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferAsReadOnlyBufferMethodID = NULL; 2397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferPositionMethodID = NULL; 2407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferLimitMethodID = NULL; 24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 24288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 243d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarstatus_t JMediaCodec::enableOnFrameRenderedListener(jboolean enable) { 244d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar if (enable) { 245d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar if (mOnFrameRenderedNotification == NULL) { 246d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar mOnFrameRenderedNotification = new AMessage(kWhatFrameRendered, this); 247d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 248d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } else { 249d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar mOnFrameRenderedNotification.clear(); 250d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 251d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 252d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar return mCodec->setOnFrameRenderedNotification(mOnFrameRenderedNotification); 253d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar} 254d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 2558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatus_t JMediaCodec::setCallback(jobject cb) { 2568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (cb != NULL) { 2578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (mCallbackNotification == NULL) { 25863834f4d23a97b27d830a301328329c7ef682bd5Lajos Molnar mCallbackNotification = new AMessage(kWhatCallbackNotify, this); 2598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 2608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } else { 2618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mCallbackNotification.clear(); 2628d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 2638d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 2648d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->setCallback(mCallbackNotification); 2658d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang} 2668d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 269d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden const sp<IGraphicBufferProducer> &bufferProducer, 2708240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const sp<ICrypto> &crypto, 27188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 27252800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> client; 273d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden if (bufferProducer != NULL) { 274aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber mSurfaceTextureClient = 275aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber new Surface(bufferProducer, true /* controlledByApp */); 276b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } else { 277b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 27888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 279b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 280b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return mCodec->configure(format, mSurfaceTextureClient, crypto, flags); 28188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2835e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnarstatus_t JMediaCodec::setSurface( 2845e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar const sp<IGraphicBufferProducer> &bufferProducer) { 2855e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar sp<Surface> client; 2865e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (bufferProducer != NULL) { 2875e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar client = new Surface(bufferProducer, true /* controlledByApp */); 2885e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 2895e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar status_t err = mCodec->setSurface(client); 2905e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (err == OK) { 2915e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar mSurfaceTextureClient = client; 2925e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 2935e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar return err; 2945e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar} 2955e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 2962621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface( 2972621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 2982621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->createInputSurface(bufferProducer); 2992621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 3002621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 3019560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhangstatus_t JMediaCodec::setInputSurface( 3028034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang const sp<PersistentSurface> &surface) { 3039560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang return mCodec->setInputSurface(surface); 3048034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 3058034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 3078d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->start(); 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 311b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 312b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 3138d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->stop(); 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3201e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatus_t JMediaCodec::reset() { 3211e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar return mCodec->reset(); 3221e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar} 3231e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 326bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags, 327bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 328bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return mCodec->queueInputBuffer( 329bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timeUs, flags, errorDetailMsg); 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer( 3339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t index, 3349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t offset, 3359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const CryptoPlugin::SubSample *subSamples, 3369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t numSubSamples, 3379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t key[16], 3389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t iv[16], 3399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::Mode mode, 340d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker const CryptoPlugin::Pattern &pattern, 3419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber int64_t presentationTimeUs, 342bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber uint32_t flags, 343bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 3449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return mCodec->queueSecureInputBuffer( 345d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker index, offset, subSamples, numSubSamples, key, iv, mode, pattern, 346bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber presentationTimeUs, flags, errorDetailMsg); 3479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 3489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 3508d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->dequeueInputBuffer(index, timeoutUs); 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 358aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber status_t err = mCodec->dequeueOutputBuffer( 359aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber index, &offset, &size, &timeUs, &flags, timeoutUs); 360aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 361aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber if (err != OK) { 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 36488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3658d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 3668d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$BufferInfo")); 36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3688d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 369fef85ef152ab176fd96dbe3047c8025136fa8560Ashok Bhat env->CallVoidMethod(bufferInfo, method, (jint)offset, (jint)size, timeUs, flags); 37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 37288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 37388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3747c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnarstatus_t JMediaCodec::releaseOutputBuffer( 3757c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar size_t index, bool render, bool updatePTS, int64_t timestampNs) { 3767c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar if (updatePTS) { 3777c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar return mCodec->renderOutputBufferAndRelease(index, timestampNs); 3787c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar } 37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() { 3852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->signalEndOfInputStream(); 3862621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 3872621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 388d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getFormat(JNIEnv *env, bool input, jobject *format) const { 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 391d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar err = input ? mCodec->getInputFormat(&msg) : mCodec->getOutputFormat(&msg); 392d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != OK) { 393d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return err; 394d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 395d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 396d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return ConvertMessageToMap(env, msg, format); 397d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 398d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 399d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, size_t index, jobject *format) const { 400d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<AMessage> msg; 401d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err; 402d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if ((err = mCodec->getOutputFormat(index, &msg)) != OK) { 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 40588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 40788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 4114273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim Vector<sp<MediaCodecBuffer> > buffers; 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 41988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 42088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 42188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 4237de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar buffers.size(), mByteBufferClass, NULL); 424cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (*bufArray == NULL) { 425cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 426cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 4294273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim const sp<MediaCodecBuffer> &buffer = buffers.itemAt(i); 43088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject byteBuffer = NULL; 4327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 4337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, true /* clearBuffer */, buffer, &byteBuffer); 4347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 4357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return err; 436cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 4377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (byteBuffer != NULL) { 4387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->SetObjectArrayElement( 4397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *bufArray, i, byteBuffer); 4407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 441d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(byteBuffer); 4427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 443d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 44488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 44688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 44788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 44888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar// static 4504273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kimtemplate <typename T> 4517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::createByteBufferFromABuffer( 4524273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim JNIEnv *env, bool readOnly, bool clearBuffer, const sp<T> &buffer, 4537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject *buf) const { 454d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if this is an ABuffer that doesn't actually hold any accessible memory, 455d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // use a null ByteBuffer 4567de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = NULL; 457e5b641e6effda54945577e9348df86213b38baebAaron Vaage 458e5b641e6effda54945577e9348df86213b38baebAaron Vaage if (buffer == NULL) { 459e5b641e6effda54945577e9348df86213b38baebAaron Vaage ALOGV("createByteBufferFromABuffer - given NULL, returning NULL"); 460e5b641e6effda54945577e9348df86213b38baebAaron Vaage return OK; 461e5b641e6effda54945577e9348df86213b38baebAaron Vaage } 462e5b641e6effda54945577e9348df86213b38baebAaron Vaage 463d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (buffer->base() == NULL) { 464d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 465d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 466d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 467d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject byteBuffer = 4687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->NewDirectByteBuffer(buffer->base(), buffer->capacity()); 4697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (readOnly && byteBuffer != NULL) { 470d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject readOnlyBuffer = env->CallObjectMethod( 4717de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferAsReadOnlyBufferMethodID); 472d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(byteBuffer); 473d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar byteBuffer = readOnlyBuffer; 474d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 475d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (byteBuffer == NULL) { 476d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NO_MEMORY; 477d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 478d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject me = env->CallObjectMethod( 4797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferOrderMethodID, mNativeByteOrderObj); 480d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(me); 481d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar me = env->CallObjectMethod( 4827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferLimitMethodID, 4837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar clearBuffer ? buffer->capacity() : (buffer->offset() + buffer->size())); 484d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(me); 4857be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar me = env->CallObjectMethod( 4867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferPositionMethodID, 4877de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar clearBuffer ? 0 : buffer->offset()); 4887be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar env->DeleteLocalRef(me); 489d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar me = NULL; 490d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 491d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar *buf = byteBuffer; 492d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 493d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 494d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 4957de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::getBuffer( 4967de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar JNIEnv *env, bool input, size_t index, jobject *buf) const { 4974273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim sp<MediaCodecBuffer> buffer; 4987de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 4997de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar status_t err = 5007de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar input 5017de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ? mCodec->getInputBuffer(index, &buffer) 5027de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar : mCodec->getOutputBuffer(index, &buffer); 5037de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5047de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 5057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return err; 5067de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5077de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5087de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return createByteBufferFromABuffer( 5097de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, input /* clearBuffer */, buffer, buf); 5107de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 5117de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 512d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getImage( 513d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, bool input, size_t index, jobject *buf) const { 5144273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim sp<MediaCodecBuffer> buffer; 515d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 516d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = 517d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar input 518d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ? mCodec->getInputBuffer(index, &buffer) 519d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar : mCodec->getOutputBuffer(index, &buffer); 520d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 521d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != OK) { 522d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return err; 523d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 524d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 525d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if this is an ABuffer that doesn't actually hold any accessible memory, 526d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // use a null ByteBuffer 527d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar *buf = NULL; 528d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (buffer->base() == NULL) { 529d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 530d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 531d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 532d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // check if buffer is an image 5337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar sp<ABuffer> imageData; 5347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (!buffer->meta()->findBuffer("image-data", &imageData)) { 5357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return OK; 5367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar int64_t timestamp = 0; 5397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (!input && buffer->meta()->findInt64("timeUs", ×tamp)) { 5407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar timestamp *= 1000; // adjust to ns 5417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject byteBuffer = NULL; 5447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 5457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, input /* clearBuffer */, buffer, &byteBuffer); 5467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 5477de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return OK; 5487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject infoBuffer = NULL; 5517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 5527de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, true /* readOnly */, true /* clearBuffer */, imageData, &infoBuffer); 5537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 5547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(byteBuffer); 5557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 556d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 557d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 558d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 5597de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject cropRect = NULL; 5607de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar int32_t left, top, right, bottom; 5617de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (buffer->meta()->findRect("crop-rect", &left, &top, &right, &bottom)) { 5627de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> rectClazz( 5637de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("android/graphics/Rect")); 5647de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(rectClazz.get() != NULL); 5657de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5667de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID rectConstructID = env->GetMethodID( 5677de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar rectClazz.get(), "<init>", "(IIII)V"); 5687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cropRect = env->NewObject( 5707de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar rectClazz.get(), rectConstructID, left, top, right + 1, bottom + 1); 5717de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> imageClazz( 5747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("android/media/MediaCodec$MediaImage")); 5757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(imageClazz.get() != NULL); 5767de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID imageConstructID = env->GetMethodID(imageClazz.get(), "<init>", 5787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;ZJIILandroid/graphics/Rect;)V"); 5797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = env->NewObject(imageClazz.get(), imageConstructID, 5817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, infoBuffer, 5827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jboolean)!input /* readOnly */, 5837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jlong)timestamp, 5847de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jint)0 /* xOffset */, (jint)0 /* yOffset */, cropRect); 5857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar // if MediaImage creation fails, return null 5877de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (env->ExceptionCheck()) { 5887de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->ExceptionDescribe(); 5897de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->ExceptionClear(); 5907de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = NULL; 5917de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5927de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5937de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (cropRect != NULL) { 5947de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(cropRect); 5957de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cropRect = NULL; 5967de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5977de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5987de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(byteBuffer); 5997de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 6007de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 6017de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(infoBuffer); 6027de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar infoBuffer = NULL; 6037de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 604d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 605d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 606d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 607056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const { 608056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo AString name; 609056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 610056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = mCodec->getName(&name); 611056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 612056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err != OK) { 613056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return err; 614056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 615056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 616056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo *nameStr = env->NewStringUTF(name.c_str()); 617056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 618056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return OK; 619056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 620056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 621226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatus_t JMediaCodec::setParameters(const sp<AMessage> &msg) { 622226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return mCodec->setParameters(msg); 623226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 624226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 625b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) { 626b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mSurfaceTextureClient != NULL) { 627b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode); 628b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 629b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 630b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 6315f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic jthrowable createCodecException( 6325f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) { 6335f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung ScopedLocalRef<jclass> clazz( 6345f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, env->FindClass("android/media/MediaCodec$CodecException")); 6355f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(clazz.get() != NULL); 6365f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 637c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu const jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(IILjava/lang/String;)V"); 6385f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(ctor != NULL); 6395f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 6405f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung ScopedLocalRef<jstring> msgObj( 6415f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, env->NewStringUTF(msg != NULL ? msg : String8::format("Error %#x", err))); 6425f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 6435f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // translate action code to Java equivalent 6445f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung switch (actionCode) { 6455f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case ACTION_CODE_TRANSIENT: 6465f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = gCodecActionCodes.codecActionTransient; 6475f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 6485f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case ACTION_CODE_RECOVERABLE: 6495f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = gCodecActionCodes.codecActionRecoverable; 6505f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 6515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung default: 6525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = 0; // everything else is fatal 6535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 6545f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } 6555f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 656c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu /* translate OS errors to Java API CodecException errorCodes */ 657c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu switch (err) { 658c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu case NO_MEMORY: 659c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu err = gCodecErrorCodes.errorInsufficientResource; 660c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu break; 661c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu case DEAD_OBJECT: 662c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu err = gCodecErrorCodes.errorReclaimed; 663c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu break; 664c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu default: /* Other error codes go out as is. */ 665c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu break; 666c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu } 667c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu 668c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu return (jthrowable)env->NewObject(clazz.get(), ctor, err, actionCode, msgObj.get()); 6695f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} 6705f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 6718d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::handleCallback(const sp<AMessage> &msg) { 6728d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang int32_t arg1, arg2 = 0; 6738d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject obj = NULL; 6748d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("callbackID", &arg1)); 6758d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang JNIEnv *env = AndroidRuntime::getJNIEnv(); 6768d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6778d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang switch (arg1) { 6788d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_INPUT_AVAILABLE: 679aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 6808d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("index", &arg2)); 6818d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang break; 6828d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6838d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6848d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_OUTPUT_AVAILABLE: 6858d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { 6868d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("index", &arg2)); 6878d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6888d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang size_t size, offset; 6898d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang int64_t timeUs; 6908d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang uint32_t flags; 6918d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findSize("size", &size)); 6928d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findSize("offset", &offset)); 6938d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt64("timeUs", &timeUs)); 6948d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("flags", (int32_t *)&flags)); 6958d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6968d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang ScopedLocalRef<jclass> clazz( 6978d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env, env->FindClass("android/media/MediaCodec$BufferInfo")); 6988d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "()V"); 6998d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 7008d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7018d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang obj = env->NewObject(clazz.get(), ctor); 7028d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (obj == NULL) { 7048d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (env->ExceptionCheck()) { 7058d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang ALOGE("Could not create MediaCodec.BufferInfo."); 7068d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->ExceptionClear(); 7078d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 7088d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 7098d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 710aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 711aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7128d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->CallVoidMethod(obj, method, (jint)offset, (jint)size, timeUs, flags); 713aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 714aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 715aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_ERROR: 717aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 71894686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang int32_t err, actionCode; 71994686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang CHECK(msg->findInt32("err", &err)); 7208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("actionCode", &actionCode)); 721aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7225f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // note that DRM errors could conceivably alias into a CodecException 7235f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung obj = (jobject)createCodecException(env, err, actionCode); 724aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (obj == NULL) { 7268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (env->ExceptionCheck()) { 72794686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang ALOGE("Could not create CodecException object."); 7288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->ExceptionClear(); 7298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 7308d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 7318d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 7328d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 733aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 734aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 735aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 736aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7378d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 738aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 7398d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang sp<AMessage> format; 7408d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findMessage("format", &format)); 741aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7428d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (OK != ConvertMessageToMap(env, format, &obj)) { 7438d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 7448d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 7458d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 746aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 747aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 748aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 749aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 750aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber default: 751aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber TRESPASS(); 752aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 7538d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->CallVoidMethod( 7558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mObject, 7568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang gFields.postEventFromNativeID, 7578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_CALLBACK, 7588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang arg1, 7598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang arg2, 7608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang obj); 7618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7628d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->DeleteLocalRef(obj); 763aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 764aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 765d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarvoid JMediaCodec::handleFrameRenderedNotification(const sp<AMessage> &msg) { 766d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar int32_t arg1 = 0, arg2 = 0; 767d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar jobject obj = NULL; 768d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar JNIEnv *env = AndroidRuntime::getJNIEnv(); 769d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 770d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar sp<AMessage> data; 771d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar CHECK(msg->findMessage("data", &data)); 772d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 773d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar status_t err = ConvertMessageToMap(env, data, &obj); 774d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar if (err != OK) { 775d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar jniThrowException(env, "java/lang/IllegalStateException", NULL); 776d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar return; 777d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 778d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 779d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar env->CallVoidMethod( 780d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar mObject, gFields.postEventFromNativeID, 781d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar EVENT_FRAME_RENDERED, arg1, arg2, obj); 782d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 783d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar env->DeleteLocalRef(obj); 784d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar} 785d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 7868d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::onMessageReceived(const sp<AMessage> &msg) { 7878d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang switch (msg->what()) { 7888d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case kWhatCallbackNotify: 7898d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { 7908d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang handleCallback(msg); 7918d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang break; 7928d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 793d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar case kWhatFrameRendered: 794d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar { 795d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar handleFrameRenderedNotification(msg); 796d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar break; 797d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 7988d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang default: 7998d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang TRESPASS(); 8008d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 801aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 802aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 80388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 80488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 80588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 80688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 80788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 80888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 80988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 81088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 811075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat sp<JMediaCodec> old = (JMediaCodec *)env->GetLongField(thiz, gFields.context); 81288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 81388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 81488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 81588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 816128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang /* release MediaCodec and stop the looper now before decStrong. 817128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * otherwise JMediaCodec::~JMediaCodec() could be called from within 818128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * its message handler, doing release() from there will deadlock 819128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * (as MediaCodec::release() post synchronous message to the same looper) 820128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang */ 821128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang old->release(); 82288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 82388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 824075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, gFields.context, (jlong)codec.get()); 82588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 82688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 82788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 82888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 82988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 830075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (JMediaCodec *)env->GetLongField(thiz, gFields.context); 83188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 83288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 83388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 83488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 83588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 83688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8375f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic void throwCodecException(JNIEnv *env, status_t err, int32_t actionCode, const char *msg) { 8385f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jthrowable exception = createCodecException(env, err, actionCode, msg); 8395f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->Throw(exception); 8405f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} 8415f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 842bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { 8438d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 8448d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$CryptoException")); 8458d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 846bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 847bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jmethodID constructID = 8488d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V"); 849bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(constructID != NULL); 850bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 8513ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker const char *defaultMsg = "Unknown Error"; 852bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 8535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung /* translate OS errors to Java API CryptoException errorCodes (which are positive) */ 8543ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker switch (err) { 8553ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_NO_LICENSE: 8563ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorNoKey; 8573ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "Crypto key not available"; 8583ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 8593ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_LICENSE_EXPIRED: 8603ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorKeyExpired; 8613ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "License expired"; 8623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 8633ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_RESOURCE_BUSY: 8643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorResourceBusy; 8653ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "Resource busy or unavailable"; 8663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 867336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION: 868336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection; 8693ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "Required output protections are not active"; 870336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker break; 87196a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker case ERROR_DRM_SESSION_NOT_OPENED: 87296a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker err = gCryptoErrorCodes.cryptoErrorSessionNotOpened; 8733ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "Attempted to use a closed session"; 87496a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker break; 875d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker case ERROR_DRM_CANNOT_HANDLE: 876d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker err = gCryptoErrorCodes.cryptoErrorUnsupportedOperation; 877d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker defaultMsg = "Operation not supported in this configuration"; 878d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker break; 8795f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung default: /* Other negative DRM error codes go out as is. */ 8803ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 8813ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker } 8823ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 8833ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker jstring msgObj = env->NewStringUTF(msg != NULL ? msg : defaultMsg); 8843ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker 885bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jthrowable exception = 8868d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj); 887bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 888bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->Throw(exception); 889bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber} 890bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 891bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary( 8925f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung JNIEnv *env, status_t err, int32_t actionCode = ACTION_CODE_FATAL, 8935f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const char *msg = NULL) { 89488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 89588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 89688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 89788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 89888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 89988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 90088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 90288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 90388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 90588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 90688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9075f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case INVALID_OPERATION: 9085f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/IllegalStateException", msg); 9095f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 9103ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 9115e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar case BAD_VALUE: 9125e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar jniThrowException(env, "java/lang/IllegalArgumentException", msg); 9135e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar return 0; 9145e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 91588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 9165f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung if (isCryptoError(err)) { 9175f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwCryptoException(env, err, msg); 9185f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 9195f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } 9205f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwCodecException(env, err, actionCode, msg); 9215f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 92288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 92388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 92488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 925d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarstatic void android_media_MediaCodec_native_enableOnFrameRenderedListener( 926d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar JNIEnv *env, 927d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar jobject thiz, 928d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar jboolean enabled) { 929d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 930d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 931d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar if (codec == NULL) { 932d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 933d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar return; 934d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 935d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 936d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar status_t err = codec->enableOnFrameRenderedListener(enabled); 937d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 938d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar throwExceptionAsNecessary(env, err); 939d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar} 940d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 9418d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatic void android_media_MediaCodec_native_setCallback( 9428d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang JNIEnv *env, 9438d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject thiz, 9448d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject cb) { 9458d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang sp<JMediaCodec> codec = getMediaCodec(env, thiz); 9468d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 9478d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (codec == NULL) { 9485f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 9498d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 9508d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 9518d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 9528d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang status_t err = codec->setCallback(cb); 9538d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 9548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang throwExceptionAsNecessary(env, err); 9558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang} 9568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 95788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 95888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 95988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 96088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 96188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 9628240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jobject jcrypto, 96388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 96488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 96588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 96688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9675f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 96888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 96988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 97088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 97188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 97288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 97388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 97488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 97588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 97688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 97788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 97888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 979d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> bufferProducer; 98088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 98164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 98288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 98352800617946c456e78ed010c82d0ec4358368164Mathias Agopian bufferProducer = surface->getIGraphicBufferProducer(); 98488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 98588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 98688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 98788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 98888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 98988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 99088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 99188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 99288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9938240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto; 9948240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto != NULL) { 9958240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto = JCrypto::GetCrypto(env, jcrypto); 9968240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 9978240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 998d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden err = codec->configure(format, bufferProducer, crypto, flags); 99988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 100088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 100188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 100288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10035e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnarstatic void android_media_MediaCodec_native_setSurface( 10045e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar JNIEnv *env, 10055e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar jobject thiz, 10065e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar jobject jsurface) { 10075e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 10085e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 10095e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (codec == NULL) { 10105e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 10115e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar return; 10125e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 10135e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 10145e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar sp<IGraphicBufferProducer> bufferProducer; 10155e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (jsurface != NULL) { 10165e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 10175e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (surface != NULL) { 10185e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar bufferProducer = surface->getIGraphicBufferProducer(); 10195e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } else { 10205e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar jniThrowException( 10215e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar env, 10225e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar "java/lang/IllegalArgumentException", 10235e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar "The surface has been released"); 10245e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar return; 10255e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 10265e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 10275e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 10285e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar status_t err = codec->setSurface(bufferProducer); 10295e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar throwExceptionAsNecessary(env, err); 10305e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar} 10315e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 10328034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangsp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface( 10338034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang JNIEnv* env, jobject object) { 10348034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<PersistentSurface> persistentSurface; 10358034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10368034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jobject lock = env->GetObjectField( 10378034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, gPersistentSurfaceClassInfo.mLock); 10388034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (env->MonitorEnter(lock) == JNI_OK) { 10398034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface = reinterpret_cast<PersistentSurface *>( 10408034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->GetLongField(object, 10418034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mPersistentObject)); 10428034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->MonitorExit(lock); 10438034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10448034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->DeleteLocalRef(lock); 10458034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10468034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return persistentSurface; 10478034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 10488034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10498034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic jobject android_media_MediaCodec_createPersistentInputSurface( 10508034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang JNIEnv* env, jclass /* clazz */) { 10518034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang ALOGV("android_media_MediaCodec_createPersistentInputSurface"); 10528034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<PersistentSurface> persistentSurface = 10538034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang MediaCodec::CreatePersistentInputSurface(); 10548034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10558034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (persistentSurface == NULL) { 10568034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return NULL; 10578034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10588034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10598034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<Surface> surface = new Surface( 10608034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface->getBufferProducer(), true); 10618034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (surface == NULL) { 10628034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return NULL; 10638034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10648034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10658034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jobject object = env->NewObject( 10668034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.clazz, 10678034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.ctor); 10688034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10698034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (object == NULL) { 10708034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (env->ExceptionCheck()) { 10718034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang ALOGE("Could not create PersistentSurface."); 10728034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->ExceptionClear(); 10738034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10748034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return NULL; 10758034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10768034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10778034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jobject lock = env->GetObjectField( 10788034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, gPersistentSurfaceClassInfo.mLock); 10798034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (env->MonitorEnter(lock) == JNI_OK) { 10808034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->CallVoidMethod( 10818034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, 10828034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.setNativeObjectLocked, 10838034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (jlong)surface.get()); 10848034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->SetLongField( 10858034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, 10868034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mPersistentObject, 10878034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (jlong)persistentSurface.get()); 10888034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->MonitorExit(lock); 10898034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } else { 10908034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->DeleteLocalRef(object); 10918034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object = NULL; 10928034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10938034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->DeleteLocalRef(lock); 10948034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10958034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (object != NULL) { 10968034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang surface->incStrong(&sRefBaseOwner); 10978034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface->incStrong(&sRefBaseOwner); 10988034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10998034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11008034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return object; 11018034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 11028034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11038034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic void android_media_MediaCodec_releasePersistentInputSurface( 11048034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang JNIEnv* env, jclass /* clazz */, jobject object) { 11058034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<PersistentSurface> persistentSurface; 11068034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11078034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jobject lock = env->GetObjectField( 11088034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, gPersistentSurfaceClassInfo.mLock); 11098034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (env->MonitorEnter(lock) == JNI_OK) { 11108034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface = reinterpret_cast<PersistentSurface *>( 11118034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->GetLongField( 11128034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, gPersistentSurfaceClassInfo.mPersistentObject)); 11138034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->SetLongField( 11148034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, 11158034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mPersistentObject, 11168034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (jlong)0); 11178034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->MonitorExit(lock); 11188034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11198034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->DeleteLocalRef(lock); 11208034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11218034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (persistentSurface != NULL) { 11228034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface->decStrong(&sRefBaseOwner); 11238034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11248034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang // no need to release surface as it will be released by Surface's jni 11258034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 11268034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11279560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhangstatic void android_media_MediaCodec_setInputSurface( 11288034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang JNIEnv* env, jobject thiz, jobject object) { 11299560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang ALOGV("android_media_MediaCodec_setInputSurface"); 11308034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11318034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<JMediaCodec> codec = getMediaCodec(env, thiz); 11328034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (codec == NULL) { 11338034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang throwExceptionAsNecessary(env, INVALID_OPERATION); 11348034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return; 11358034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11368034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11378034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<PersistentSurface> persistentSurface = 11388034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang android_media_MediaCodec_getPersistentInputSurface(env, object); 11398034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11409560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang status_t err = codec->setInputSurface(persistentSurface); 11418034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (err != NO_ERROR) { 11428034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang throwExceptionAsNecessary(env, err); 11438034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11448034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 11458034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11462621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env, 11472621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 11482621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_createInputSurface"); 11492621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11502621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 11512621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 11525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 11532621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 11542621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 11552621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11562621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Tell the MediaCodec that we want to use a Surface as input. 11572621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer> bufferProducer; 11582621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->createInputSurface(&bufferProducer); 11592621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (err != NO_ERROR) { 11602621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 11612621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 11622621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 11632621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11642621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Wrap the IGBP in a Java-language Surface. 11652621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return android_view_Surface_createFromIGraphicBufferProducer(env, 11662621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden bufferProducer); 11672621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 11682621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 116988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 117088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 117188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 117288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 117388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 117488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 117688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 117788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 117888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 117988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 118088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, "start failed"); 118288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 118388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 118488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 118588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 118688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 118788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 118888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 118988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11905f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 119188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 119288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 119388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 119488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 119588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 119688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 119788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 119888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11991e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatic void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) { 12001e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar ALOGV("android_media_MediaCodec_reset"); 12011e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 12021e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 12031e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 12041e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar if (codec == NULL) { 12055f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 12061e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar return; 12071e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar } 12081e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 12091e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar status_t err = codec->reset(); 12101e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar if (err != OK) { 12111e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar // treat all errors as fatal for now, though resource not available 12121e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar // errors could be treated as transient. 12135f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // we also should avoid sending INVALID_OPERATION here due to 12145f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // the transitory nature of reset(), it should not inadvertently 12155f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // trigger an IllegalStateException. 12165f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung err = UNKNOWN_ERROR; 12171e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar } 12181e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar throwExceptionAsNecessary(env, err); 12191e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar} 12201e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 122188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 122288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 122388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 122488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 122588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 122688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12275f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 122888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 122988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 123088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 123288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 123488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 123588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 123688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 123788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 123888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 123988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 124088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 124188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 124288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 124388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 124488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 124588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 124788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12495f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 125088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 125188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 125288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1253bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 1254bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 125588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 1256bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timestampUs, flags, &errorDetailMsg); 125788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1258bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 12595f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 126088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 126188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer( 12639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber JNIEnv *env, 12649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jobject thiz, 12659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint index, 12669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint offset, 126791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jobject cryptoInfoObj, 12689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jlong timestampUs, 12699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint flags) { 12709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ALOGV("android_media_MediaCodec_queueSecureInputBuffer"); 12719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 12729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 12739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 12749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (codec == NULL) { 12755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 12769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return; 12779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 12789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 127991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint numSubSamples = 128091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); 128191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 128291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfClearDataObj = 128391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 128491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); 128591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 128691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfEncryptedDataObj = 128791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 128891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); 128991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 129091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray keyObj = 129191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); 129291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 129391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray ivObj = 129491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); 129591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 1296d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jint jmode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); 1297d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker enum CryptoPlugin::Mode mode; 1298d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker if (jmode == gCryptoModes.Unencrypted) { 1299d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker mode = CryptoPlugin::kMode_Unencrypted; 1300d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } else if (jmode == gCryptoModes.AesCtr) { 1301d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker mode = CryptoPlugin::kMode_AES_CTR; 1302d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } else if (jmode == gCryptoModes.AesCbc) { 1303d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker mode = CryptoPlugin::kMode_AES_CBC; 1304d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } else { 1305d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker throwExceptionAsNecessary(env, INVALID_OPERATION); 1306d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker return; 1307d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } 1308d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1309d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jobject patternObj = env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID); 1310d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1311d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CryptoPlugin::Pattern pattern; 1312e872ac45f79ca2c0b538df891d983e3d5e037574Jeff Tinker if (patternObj == NULL) { 1313e872ac45f79ca2c0b538df891d983e3d5e037574Jeff Tinker pattern.mEncryptBlocks = 0; 1314e872ac45f79ca2c0b538df891d983e3d5e037574Jeff Tinker pattern.mSkipBlocks = 0; 1315e872ac45f79ca2c0b538df891d983e3d5e037574Jeff Tinker } else { 1316d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker pattern.mEncryptBlocks = env->GetIntField(patternObj, gFields.patternEncryptBlocksID); 1317d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker pattern.mSkipBlocks = env->GetIntField(patternObj, gFields.patternSkipBlocksID); 1318d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } 131991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 13209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber status_t err = OK; 13219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::SubSample *subSamples = NULL; 13239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *key = NULL; 13249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *iv = NULL; 13259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numSubSamples <= 0) { 13279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 13289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj == NULL 13299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && numBytesOfEncryptedDataObj == NULL) { 13309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 13319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfEncryptedDataObj != NULL 13329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { 13339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 13349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj != NULL 13359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { 13369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 13377ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar // subSamples array may silently overflow if number of samples are too large. Use 13387ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms 13395f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } else if ( CC_UNLIKELY(numSubSamples >= (signed)(INT32_MAX / sizeof(*subSamples))) ) { 13407ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar err = -EINVAL; 13419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 13429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 13439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfClearData = 13459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearDataObj == NULL) 13469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 13479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); 13489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfEncryptedData = 13509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedDataObj == NULL) 13519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 13529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); 13539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = new CryptoPlugin::SubSample[numSubSamples]; 13559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber for (jint i = 0; i < numSubSamples; ++i) { 13579e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfClearData = 13589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; 13599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfEncryptedData = 13619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedData == NULL) 13629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? 0 : numBytesOfEncryptedData[i]; 13639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfEncryptedData != NULL) { 13669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 13679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); 13689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedData = NULL; 13699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfClearData != NULL) { 13729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 13739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearDataObj, numBytesOfClearData, 0); 13749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearData = NULL; 13759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && keyObj != NULL) { 13799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(keyObj) != 16) { 13809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 13819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 13829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 13839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = env->GetByteArrayElements(keyObj, &isCopy); 13849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && ivObj != NULL) { 13889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(ivObj) != 16) { 13899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 13909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 13919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 13929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = env->GetByteArrayElements(ivObj, &isCopy); 13939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1396bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 1397bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 13989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK) { 13999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = codec->queueSecureInputBuffer( 14009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, 14019e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples, numSubSamples, 14029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (const uint8_t *)key, (const uint8_t *)iv, 1403d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker mode, 1404d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker pattern, 1405bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber timestampUs, 1406bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber flags, 1407bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber &errorDetailMsg); 14089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 14109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (iv != NULL) { 14119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(ivObj, iv, 0); 14129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = NULL; 14139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 14159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (key != NULL) { 14169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(keyObj, key, 0); 14179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = NULL; 14189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 14209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber delete[] subSamples; 14219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = NULL; 14229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1423bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 14245f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 14259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 14269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 142788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 142888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 142988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 143088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 143188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 143288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 143388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 14345f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 143588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 143688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 143788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 143888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 143988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 144088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 144188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 1442075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 144388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 144488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 144588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 144688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 144788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 144888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 144988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 145088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 145188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 145288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 145388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 145488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 14555f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 14560e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber return 0; 145788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 145888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 145988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 146088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 146188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 146288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 146388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 1464075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 146588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 146688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 146788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 146888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 146988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 147088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 14717c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar JNIEnv *env, jobject thiz, 14727c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar jint index, jboolean render, jboolean updatePTS, jlong timestampNs) { 147388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 147488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 147588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 147688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 147788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 14785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 147988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 148088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 148188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14827c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs); 148388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 148488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 148588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 148688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14872621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env, 14882621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 14892621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_signalEndOfInputStream"); 14902621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 14912621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 14922621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 14935f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 14942621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return; 14952621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 14962621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 14972621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->signalEndOfInputStream(); 14982621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 14992621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 15002621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 15012621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1502d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getFormatNative( 1503d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input) { 1504d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getFormatNative"); 1505d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1506d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1507d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1508d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 15095f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1510d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1511d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1512d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1513d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject format; 1514d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getFormat(env, input, &format); 1515d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1516d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1517d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return format; 1518d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1519d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1520d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1521d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1522d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1523d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1524d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1525d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getOutputFormatForIndexNative( 1526d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jint index) { 1527d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getOutputFormatForIndexNative"); 152888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 152988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 153088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 153188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 15325f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 153388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 153488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 153588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 153688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 1537d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getOutputFormat(env, index, &format); 153888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 153988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 154088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 154188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 154288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 154388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 154488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 154588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 154688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 154788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 154888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 154988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 155088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 155188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 155288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 155388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 155488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 15555f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 155688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 155788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 155888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 155988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 156088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 156188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 156288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 156388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 156488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 156588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1566cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if we're out of memory, an exception was already thrown 1567cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (err != NO_MEMORY) { 1568cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen throwExceptionAsNecessary(env, err); 1569cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 157088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 157188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 157288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 157388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1574d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getBuffer( 1575d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input, jint index) { 1576d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getBuffer"); 1577d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1578d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1579d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1580d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 15815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1582d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1583d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1584d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1585d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject buffer; 1586d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getBuffer(env, input, index, &buffer); 1587d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1588d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1589d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return buffer; 1590d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1591d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1592d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if we're out of memory, an exception was already thrown 1593d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != NO_MEMORY) { 1594d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1595d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1596d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1597d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1598d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1599d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1600d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getImage( 1601d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input, jint index) { 1602d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getImage"); 1603d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1604d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1605d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1606d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 16075f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1608d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1609d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1610d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1611d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject image; 1612d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getImage(env, input, index, &image); 1613d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1614d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1615d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return image; 1616d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1617d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1618d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if we're out of memory, an exception was already thrown 1619d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != NO_MEMORY) { 1620d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1621d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1622d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1623d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1624d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1625d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1626056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName( 1627056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo JNIEnv *env, jobject thiz) { 1628056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo ALOGV("android_media_MediaCodec_getName"); 1629056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1630056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1631056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1632056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (codec == NULL) { 16335f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1634056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 1635056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 1636056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1637056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jstring name; 1638056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = codec->getName(env, &name); 1639056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1640056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err == OK) { 1641056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return name; 1642056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 1643056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1644056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo throwExceptionAsNecessary(env, err); 1645056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1646056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 1647056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 1648056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1649226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatic void android_media_MediaCodec_setParameters( 1650226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) { 1651226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber ALOGV("android_media_MediaCodec_setParameters"); 1652226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1653226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1654226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1655226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (codec == NULL) { 16565f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1657226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return; 1658226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 1659226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1660226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<AMessage> params; 1661226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, ¶ms); 1662226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1663226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (err == OK) { 1664226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber err = codec->setParameters(params); 1665226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 1666226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1667226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber throwExceptionAsNecessary(env, err); 1668226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 1669226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1670b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode( 1671b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber JNIEnv *env, jobject thiz, jint mode) { 1672b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1673b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1674b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (codec == NULL) { 16755f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1676b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 1677b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 1678b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1679b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW 1680b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 1681b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/InvalidArgumentException", NULL); 1682b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 1683b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 1684b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1685b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber codec->setVideoScalingMode(mode); 1686b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 1687b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 168888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 16898d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 16908d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec")); 16918d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 169288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1693075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J"); 169488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 169591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 1696aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber gFields.postEventFromNativeID = 1697aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber env->GetMethodID( 1698aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V"); 1699aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 1700aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber CHECK(gFields.postEventFromNativeID != NULL); 1701aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 1702d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jfieldID field; 1703d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_UNENCRYPTED", "I"); 1704d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(field != NULL); 1705d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gCryptoModes.Unencrypted = 1706d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker env->GetStaticIntField(clazz.get(), field); 1707d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1708d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CTR", "I"); 1709d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(field != NULL); 1710d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gCryptoModes.AesCtr = 1711d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker env->GetStaticIntField(clazz.get(), field); 1712d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1713d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CBC", "I"); 1714d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(field != NULL); 1715d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gCryptoModes.AesCbc = 1716d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker env->GetStaticIntField(clazz.get(), field); 1717d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 17188d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo")); 17198d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 172091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 172191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumSubSamplesID = 17228d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numSubSamples", "I"); 172391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumSubSamplesID != NULL); 172491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 172591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfClearDataID = 17268d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I"); 172791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL); 172891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 172991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfEncryptedDataID = 17308d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I"); 173191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL); 173291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 17338d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B"); 173491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoKeyID != NULL); 173591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 17368d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B"); 173791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoIVID != NULL); 173891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 17398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I"); 174091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoModeID != NULL); 17413ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 1742d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gFields.cryptoInfoPatternID = env->GetFieldID(clazz.get(), "pattern", 1743d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker "Landroid/media/MediaCodec$CryptoInfo$Pattern;"); 1744d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(gFields.cryptoInfoPatternID != NULL); 1745d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1746d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo$Pattern")); 1747d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(clazz.get() != NULL); 1748d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1749d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gFields.patternEncryptBlocksID = env->GetFieldID(clazz.get(), "mEncryptBlocks", "I"); 1750d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(gFields.patternEncryptBlocksID != NULL); 1751d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1752d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gFields.patternSkipBlocksID = env->GetFieldID(clazz.get(), "mSkipBlocks", "I"); 1753d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(gFields.patternSkipBlocksID != NULL); 1754d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 17558d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException")); 17568d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 17573ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 17588d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I"); 17593ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 17608d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorNoKey = 17618d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 17623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 17638d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I"); 17643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 17658d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorKeyExpired = 17668d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 17673ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 17688d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I"); 17693ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 17708d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorResourceBusy = 17718d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 17725f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 1773336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_OUTPUT_PROTECTION", "I"); 1774336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker CHECK(field != NULL); 1775336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection = 1776336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker env->GetStaticIntField(clazz.get(), field); 1777336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker 177896a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker field = env->GetStaticFieldID(clazz.get(), "ERROR_SESSION_NOT_OPENED", "I"); 177996a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker CHECK(field != NULL); 178096a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker gCryptoErrorCodes.cryptoErrorSessionNotOpened = 178196a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker env->GetStaticIntField(clazz.get(), field); 178296a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker 1783d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker field = env->GetStaticFieldID(clazz.get(), "ERROR_UNSUPPORTED_OPERATION", "I"); 1784d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker CHECK(field != NULL); 1785d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker gCryptoErrorCodes.cryptoErrorUnsupportedOperation = 1786d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker env->GetStaticIntField(clazz.get(), field); 1787d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker 17885f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung clazz.reset(env->FindClass("android/media/MediaCodec$CodecException")); 17895f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(clazz.get() != NULL); 17905f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I"); 17915f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(field != NULL); 17925f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung gCodecActionCodes.codecActionTransient = 17935f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->GetStaticIntField(clazz.get(), field); 17945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 17955f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung field = env->GetStaticFieldID(clazz.get(), "ACTION_RECOVERABLE", "I"); 17965f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(field != NULL); 17975f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung gCodecActionCodes.codecActionRecoverable = 17985f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->GetStaticIntField(clazz.get(), field); 17999e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 1800c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_RESOURCE", "I"); 18019e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu CHECK(field != NULL); 1802c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu gCodecErrorCodes.errorInsufficientResource = 18039e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu env->GetStaticIntField(clazz.get(), field); 18049e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 1805c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu field = env->GetStaticFieldID(clazz.get(), "ERROR_RECLAIMED", "I"); 18069e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu CHECK(field != NULL); 1807c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu gCodecErrorCodes.errorReclaimed = 18089e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu env->GetStaticIntField(clazz.get(), field); 18098034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18108034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang clazz.reset(env->FindClass("android/view/Surface")); 18118034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(clazz.get() != NULL); 18128034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18138034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang field = env->GetFieldID(clazz.get(), "mLock", "Ljava/lang/Object;"); 18148034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(field != NULL); 18158034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mLock = field; 18168034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18178034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jmethodID method = env->GetMethodID(clazz.get(), "setNativeObjectLocked", "(J)V"); 18188034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(method != NULL); 18198034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.setNativeObjectLocked = method; 18208034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18218034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang clazz.reset(env->FindClass("android/media/MediaCodec$PersistentSurface")); 18228034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(clazz.get() != NULL); 18238034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); 18248034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18258034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang method = env->GetMethodID(clazz.get(), "<init>", "()V"); 18268034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(method != NULL); 18278034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.ctor = method; 18288034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18298034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang field = env->GetFieldID(clazz.get(), "mPersistentObject", "J"); 18308034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(field != NULL); 18318034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mPersistentObject = field; 183288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 183388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 183488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 183588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 183688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 183788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 18385f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/NullPointerException", NULL); 183988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 184088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 184188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 184288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 184388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 184488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 184588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 184688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 184788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 184888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 184988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18505f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const status_t err = codec->initCheck(); 18515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung if (err == NAME_NOT_FOUND) { 18525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // fail and do not try again. 18535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/IllegalArgumentException", 18545f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung String8::format("Failed to initialize %s, error %#x", tmp, err)); 1855c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu env->ReleaseStringUTFChars(name, tmp); 1856c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu return; 1857c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu } if (err == NO_MEMORY) { 1858c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu throwCodecException(env, err, ACTION_CODE_TRANSIENT, 1859c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu String8::format("Failed to initialize %s, error %#x", tmp, err)); 18605f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 18615f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return; 18625f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } else if (err != OK) { 18635f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // believed possible to try again 18645f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/io/IOException", 18655f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung String8::format("Failed to find matching codec %s, error %#x", tmp, err)); 18665f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 186788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 186888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 186988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18705f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 18715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 1872aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber codec->registerSelf(); 1873aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 187488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 187588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 187688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 187788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 187888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 187988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 188088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 188188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 188276f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = { 1883d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_release", "()V", (void *)android_media_MediaCodec_release }, 188488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18851e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar { "native_reset", "()V", (void *)android_media_MediaCodec_reset }, 18861e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 18878034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang { "native_releasePersistentInputSurface", 18888034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang "(Landroid/view/Surface;)V", 18898034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (void *)android_media_MediaCodec_releasePersistentInputSurface}, 18908034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18918034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang { "native_createPersistentInputSurface", 18928034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang "()Landroid/media/MediaCodec$PersistentSurface;", 18938034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (void *)android_media_MediaCodec_createPersistentInputSurface }, 18948034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18959560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang { "native_setInputSurface", "(Landroid/view/Surface;)V", 18969560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang (void *)android_media_MediaCodec_setInputSurface }, 18978034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 1898d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar { "native_enableOnFrameRenderedListener", "(Z)V", 1899d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar (void *)android_media_MediaCodec_native_enableOnFrameRenderedListener }, 1900d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 19018d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { "native_setCallback", 19028d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang "(Landroid/media/MediaCodec$Callback;)V", 19038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang (void *)android_media_MediaCodec_native_setCallback }, 19048d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 190588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 19068240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;" 190707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber "Landroid/media/MediaCrypto;I)V", 190888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 190988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19105e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar { "native_setSurface", 19115e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar "(Landroid/view/Surface;)V", 19125e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar (void *)android_media_MediaCodec_native_setSurface }, 19135e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 19142621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "createInputSurface", "()Landroid/view/Surface;", 19152621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_createInputSurface }, 19162621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1917d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_start", "()V", (void *)android_media_MediaCodec_start }, 1918aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { "native_stop", "()V", (void *)android_media_MediaCodec_stop }, 1919d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_flush", "()V", (void *)android_media_MediaCodec_flush }, 192088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1921d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_queueInputBuffer", "(IIIJI)V", 192288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 192388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1924d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", 19259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (void *)android_media_MediaCodec_queueSecureInputBuffer }, 19269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1927d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_dequeueInputBuffer", "(J)I", 192888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 192988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1930d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 193188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 193288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19337c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar { "releaseOutputBuffer", "(IZZJ)V", 193488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 193588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19362621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "signalEndOfInputStream", "()V", 19372621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_signalEndOfInputStream }, 19382621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1939d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getFormatNative", "(Z)Ljava/util/Map;", 1940d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getFormatNative }, 1941d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1942d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getOutputFormatNative", "(I)Ljava/util/Map;", 1943d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getOutputFormatForIndexNative }, 194488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 194588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 194688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 194788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1948d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getBuffer", "(ZI)Ljava/nio/ByteBuffer;", 1949d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getBuffer }, 1950d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1951d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getImage", "(ZI)Landroid/media/Image;", 1952d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getImage }, 1953d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1954056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo { "getName", "()Ljava/lang/String;", 1955056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo (void *)android_media_MediaCodec_getName }, 1956056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1957226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V", 1958226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber (void *)android_media_MediaCodec_setParameters }, 1959226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1960b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber { "setVideoScalingMode", "(I)V", 1961b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber (void *)android_media_MediaCodec_setVideoScalingMode }, 1962b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 196388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 196488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 196588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 196688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 196788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 196888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 196988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 197088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 197188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 197288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 197388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 197488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 197588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 1976