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" 240e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick#include "android_media_MediaMetricsJNI.h" 2588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_Utils.h" 2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/AndroidRuntime.h" 2788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/android_view_Surface.h" 28d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang#include "android_util_Binder.h" 2988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "jni.h" 3088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "JNIHelp.h" 3188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang#include <android/media/IDescrambler.h> 33d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 347ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar#include <cutils/compiler.h> 357ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar 368335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <gui/Surface.h> 378335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian 380e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber#include <media/ICrypto.h> 394273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim#include <media/MediaCodecBuffer.h> 4088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaCodec.h> 4188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 4288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 4388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ALooper.h> 4488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 45bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber#include <media/stagefright/foundation/AString.h> 4688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h> 478034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang#include <media/stagefright/PersistentSurface.h> 488d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber#include <nativehelper/ScopedLocalRef.h> 498d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 50b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber#include <system/window.h> 51b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android { 5388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!! 5588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum { 5688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_TRY_AGAIN_LATER = -1, 5788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED = -2, 5888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, 5988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 6088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 61aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huberenum { 628d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_CALLBACK = 1, 638d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_SET_CALLBACK = 2, 64d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar EVENT_FRAME_RENDERED = 3, 65aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}; 66aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 675f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic struct CryptoErrorCodes { 683ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorNoKey; 693ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorKeyExpired; 703ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorResourceBusy; 71336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker jint cryptoErrorInsufficientOutputProtection; 7296a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker jint cryptoErrorSessionNotOpened; 73d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker jint cryptoErrorUnsupportedOperation; 743ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker} gCryptoErrorCodes; 753ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 765f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic struct CodecActionCodes { 775f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jint codecActionTransient; 785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jint codecActionRecoverable; 795f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} gCodecActionCodes; 805f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 81c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wustatic struct CodecErrorCodes { 82c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu jint errorInsufficientResource; 83c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu jint errorReclaimed; 84c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu} gCodecErrorCodes; 859e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 868034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic struct { 878034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jclass clazz; 888034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jfieldID mLock; 898034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jfieldID mPersistentObject; 908034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jmethodID ctor; 918034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jmethodID setNativeObjectLocked; 928034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} gPersistentSurfaceClassInfo; 938034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 94d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinkerstatic struct { 95d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jint Unencrypted; 96d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jint AesCtr; 97d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jint AesCbc; 98d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker} gCryptoModes; 99d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 100d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 103aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber jmethodID postEventFromNativeID; 10491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumSubSamplesID; 10591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfClearDataID; 10691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfEncryptedDataID; 10791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoKeyID; 10891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoIVID; 10991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoModeID; 110d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jfieldID cryptoInfoPatternID; 111d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jfieldID patternEncryptBlocksID; 112d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jfieldID patternSkipBlocksID; 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 1168034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic const void *sRefBaseOwner; 11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 12388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 1248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mObject(NULL) { 12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 12788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 13088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cacheJavaObjects(env); 1327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 13388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 13488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 13588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 13688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 13788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 138aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber true, // canCallJava 1398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber PRIORITY_FOREGROUND); 14088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 1425f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus); 14388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 1445f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus); 14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 1465f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK((mCodec != NULL) != (mInitStatus != OK)); 14788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::cacheJavaObjects(JNIEnv *env) { 1507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jclass clazz = (jclass)env->FindClass("java/nio/ByteBuffer"); 1517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass = (jclass)env->NewGlobalRef(clazz); 1527de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferClass != NULL); 1537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> byteOrderClass( 1557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("java/nio/ByteOrder")); 1567de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(byteOrderClass.get() != NULL); 1577de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1587de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID nativeOrderID = env->GetStaticMethodID( 1597de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;"); 1607de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(nativeOrderID != NULL); 1617de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1627de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject nativeByteOrderObj = 1637de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID); 1647de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mNativeByteOrderObj = env->NewGlobalRef(nativeByteOrderObj); 1657de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mNativeByteOrderObj != NULL); 1667de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(nativeByteOrderObj); 1677de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar nativeByteOrderObj = NULL; 1687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferOrderMethodID = env->GetMethodID( 1707de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, 1717de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "order", 1727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); 1737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferOrderMethodID != NULL); 1747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferAsReadOnlyBufferMethodID = env->GetMethodID( 1767de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;"); 1777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferAsReadOnlyBufferMethodID != NULL); 1787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferPositionMethodID = env->GetMethodID( 1807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "position", "(I)Ljava/nio/Buffer;"); 1817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferPositionMethodID != NULL); 1827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 1837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferLimitMethodID = env->GetMethodID( 1847de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass, "limit", "(I)Ljava/nio/Buffer;"); 1857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(mByteBufferLimitMethodID != NULL); 1867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 1877de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 1895f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return mInitStatus; 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 192aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Hubervoid JMediaCodec::registerSelf() { 193aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber mLooper->registerHandler(this); 194aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 195aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 196128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhangvoid JMediaCodec::release() { 197d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo if (mCodec != NULL) { 198d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec->release(); 199d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec.clear(); 2005f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung mInitStatus = NO_INIT; 201d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo } 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 203128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang if (mLooper != NULL) { 204128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper->unregisterHandler(id()); 205128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper->stop(); 206128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang mLooper.clear(); 207128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang } 208128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang} 209128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang 210128b012cc8c2369136bb8450bc91c81aebe18506Chong ZhangJMediaCodec::~JMediaCodec() { 211128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang if (mCodec != NULL || mLooper != NULL) { 212128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang /* MediaCodec and looper should have been released explicitly already 213128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * in setMediaCodec() (see comments in setMediaCodec()). 214128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * 215128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * Otherwise JMediaCodec::~JMediaCodec() might be called from within the 216128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * message handler, doing release() there risks deadlock as MediaCodec:: 217128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * release() post synchronous message to the same looper. 218128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * 219128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * Print a warning and try to proceed with releasing. 220128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang */ 221128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()..."); 222128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang release(); 223128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec()."); 224128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang } 225128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang 22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 22988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 23188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 2327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar deleteJavaObjects(env); 2337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 2347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 2357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::deleteJavaObjects(JNIEnv *env) { 2367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteGlobalRef(mByteBufferClass); 2377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferClass = NULL; 2387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteGlobalRef(mNativeByteOrderObj); 2397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mNativeByteOrderObj = NULL; 2407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 2417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferOrderMethodID = NULL; 2427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferAsReadOnlyBufferMethodID = NULL; 2437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferPositionMethodID = NULL; 2447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar mByteBufferLimitMethodID = NULL; 24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 247d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarstatus_t JMediaCodec::enableOnFrameRenderedListener(jboolean enable) { 248d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar if (enable) { 249d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar if (mOnFrameRenderedNotification == NULL) { 250d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar mOnFrameRenderedNotification = new AMessage(kWhatFrameRendered, this); 251d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 252d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } else { 253d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar mOnFrameRenderedNotification.clear(); 254d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 255d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 256d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar return mCodec->setOnFrameRenderedNotification(mOnFrameRenderedNotification); 257d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar} 258d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 2598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatus_t JMediaCodec::setCallback(jobject cb) { 2608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (cb != NULL) { 2618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (mCallbackNotification == NULL) { 26263834f4d23a97b27d830a301328329c7ef682bd5Lajos Molnar mCallbackNotification = new AMessage(kWhatCallbackNotify, this); 2638d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 2648d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } else { 2658d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mCallbackNotification.clear(); 2668d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 2678d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 2688d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->setCallback(mCallbackNotification); 2698d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang} 2708d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 27188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 27288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 273d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden const sp<IGraphicBufferProducer> &bufferProducer, 2748240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const sp<ICrypto> &crypto, 275d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang const sp<IDescrambler> &descrambler, 27688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 27752800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> client; 278d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden if (bufferProducer != NULL) { 279aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber mSurfaceTextureClient = 280aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber new Surface(bufferProducer, true /* controlledByApp */); 281b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } else { 282b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 284b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 285d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang return mCodec->configure( 286d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang format, mSurfaceTextureClient, crypto, descrambler, flags); 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2895e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnarstatus_t JMediaCodec::setSurface( 2905e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar const sp<IGraphicBufferProducer> &bufferProducer) { 2915e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar sp<Surface> client; 2925e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (bufferProducer != NULL) { 2935e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar client = new Surface(bufferProducer, true /* controlledByApp */); 2945e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 2955e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar status_t err = mCodec->setSurface(client); 2965e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (err == OK) { 2975e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar mSurfaceTextureClient = client; 2985e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 2995e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar return err; 3005e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar} 3015e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 3022621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface( 3032621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 3042621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->createInputSurface(bufferProducer); 3052621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 3062621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 3079560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhangstatus_t JMediaCodec::setInputSurface( 3088034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang const sp<PersistentSurface> &surface) { 3099560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang return mCodec->setInputSurface(surface); 3108034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 3118034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 3138d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->start(); 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 317b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 318b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 3198d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->stop(); 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3261e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatus_t JMediaCodec::reset() { 3271e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar return mCodec->reset(); 3281e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar} 3291e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 332bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags, 333bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 334bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return mCodec->queueInputBuffer( 335bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timeUs, flags, errorDetailMsg); 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer( 3399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t index, 3409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t offset, 3419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const CryptoPlugin::SubSample *subSamples, 3429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t numSubSamples, 3439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t key[16], 3449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t iv[16], 3459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::Mode mode, 346d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker const CryptoPlugin::Pattern &pattern, 3479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber int64_t presentationTimeUs, 348bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber uint32_t flags, 349bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 3509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return mCodec->queueSecureInputBuffer( 351d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker index, offset, subSamples, numSubSamples, key, iv, mode, pattern, 352bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber presentationTimeUs, flags, errorDetailMsg); 3539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 3549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 3568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return mCodec->dequeueInputBuffer(index, timeoutUs); 35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 364aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber status_t err = mCodec->dequeueOutputBuffer( 365aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber index, &offset, &size, &timeUs, &flags, timeoutUs); 366aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 367aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber if (err != OK) { 36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 36988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3718d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 3728d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$BufferInfo")); 37388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3748d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 375fef85ef152ab176fd96dbe3047c8025136fa8560Ashok Bhat env->CallVoidMethod(bufferInfo, method, (jint)offset, (jint)size, timeUs, flags); 37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 37888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3807c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnarstatus_t JMediaCodec::releaseOutputBuffer( 3817c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar size_t index, bool render, bool updatePTS, int64_t timestampNs) { 3827c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar if (updatePTS) { 3837c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar return mCodec->renderOutputBufferAndRelease(index, timestampNs); 3847c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar } 38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3902621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() { 3912621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->signalEndOfInputStream(); 3922621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 3932621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 394d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getFormat(JNIEnv *env, bool input, jobject *format) const { 39588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 39688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 397d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar err = input ? mCodec->getInputFormat(&msg) : mCodec->getOutputFormat(&msg); 398d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != OK) { 399d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return err; 400d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 401d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 402d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return ConvertMessageToMap(env, msg, format); 403d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 404d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 405d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, size_t index, jobject *format) const { 406d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<AMessage> msg; 407d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err; 408d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if ((err = mCodec->getOutputFormat(index, &msg)) != OK) { 40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 4174273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim Vector<sp<MediaCodecBuffer> > buffers; 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 42088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 42188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 42288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 42388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 42588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 42688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 4297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar buffers.size(), mByteBufferClass, NULL); 430cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (*bufArray == NULL) { 431cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 432cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 43388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 4354273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim const sp<MediaCodecBuffer> &buffer = buffers.itemAt(i); 43688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject byteBuffer = NULL; 4387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 4397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, true /* clearBuffer */, buffer, &byteBuffer); 4407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 4417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return err; 442cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 4437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (byteBuffer != NULL) { 4447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->SetObjectArrayElement( 4457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *bufArray, i, byteBuffer); 4467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 447d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(byteBuffer); 4487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 449d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 45488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar// static 4564273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kimtemplate <typename T> 4577de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::createByteBufferFromABuffer( 4584273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim JNIEnv *env, bool readOnly, bool clearBuffer, const sp<T> &buffer, 4597de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject *buf) const { 460d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if this is an ABuffer that doesn't actually hold any accessible memory, 461d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // use a null ByteBuffer 4627de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = NULL; 463e5b641e6effda54945577e9348df86213b38baebAaron Vaage 464e5b641e6effda54945577e9348df86213b38baebAaron Vaage if (buffer == NULL) { 465e5b641e6effda54945577e9348df86213b38baebAaron Vaage ALOGV("createByteBufferFromABuffer - given NULL, returning NULL"); 466e5b641e6effda54945577e9348df86213b38baebAaron Vaage return OK; 467e5b641e6effda54945577e9348df86213b38baebAaron Vaage } 468e5b641e6effda54945577e9348df86213b38baebAaron Vaage 469d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (buffer->base() == NULL) { 470d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 471d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 472d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 473d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject byteBuffer = 4747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->NewDirectByteBuffer(buffer->base(), buffer->capacity()); 4757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (readOnly && byteBuffer != NULL) { 476d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject readOnlyBuffer = env->CallObjectMethod( 4777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferAsReadOnlyBufferMethodID); 478d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(byteBuffer); 479d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar byteBuffer = readOnlyBuffer; 480d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 481d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (byteBuffer == NULL) { 482d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NO_MEMORY; 483d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 484d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject me = env->CallObjectMethod( 4857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferOrderMethodID, mNativeByteOrderObj); 486d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(me); 487d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar me = env->CallObjectMethod( 4887de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferLimitMethodID, 4897de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar clearBuffer ? buffer->capacity() : (buffer->offset() + buffer->size())); 490d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar env->DeleteLocalRef(me); 4917be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar me = env->CallObjectMethod( 4927de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, mByteBufferPositionMethodID, 4937de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar clearBuffer ? 0 : buffer->offset()); 4947be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar env->DeleteLocalRef(me); 495d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar me = NULL; 496d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 497d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar *buf = byteBuffer; 498d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 499d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 500d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 5017de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::getBuffer( 5027de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar JNIEnv *env, bool input, size_t index, jobject *buf) const { 5034273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim sp<MediaCodecBuffer> buffer; 5047de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar status_t err = 5067de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar input 5077de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ? mCodec->getInputBuffer(index, &buffer) 5087de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar : mCodec->getOutputBuffer(index, &buffer); 5097de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5107de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 5117de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return err; 5127de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5137de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5147de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return createByteBufferFromABuffer( 5157de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, input /* clearBuffer */, buffer, buf); 5167de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar} 5177de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 518d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getImage( 519d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, bool input, size_t index, jobject *buf) const { 5204273dd03a83fd5f9ba25f3b7c3a4add7bce7206cWonsik Kim sp<MediaCodecBuffer> buffer; 521d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 522d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = 523d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar input 524d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ? mCodec->getInputBuffer(index, &buffer) 525d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar : mCodec->getOutputBuffer(index, &buffer); 526d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 527d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != OK) { 528d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return err; 529d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 530d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 531d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if this is an ABuffer that doesn't actually hold any accessible memory, 532d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // use a null ByteBuffer 533d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar *buf = NULL; 534d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (buffer->base() == NULL) { 535d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 536d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 537d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 538d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // check if buffer is an image 5397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar sp<ABuffer> imageData; 5407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (!buffer->meta()->findBuffer("image-data", &imageData)) { 5417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return OK; 5427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar int64_t timestamp = 0; 5457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (!input && buffer->meta()->findInt64("timeUs", ×tamp)) { 5467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar timestamp *= 1000; // adjust to ns 5477de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject byteBuffer = NULL; 5507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 5517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, !input /* readOnly */, input /* clearBuffer */, buffer, &byteBuffer); 5527de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 5537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar return OK; 5547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5567de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject infoBuffer = NULL; 5577de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar err = createByteBufferFromABuffer( 5587de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, true /* readOnly */, true /* clearBuffer */, imageData, &infoBuffer); 5597de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (err != OK) { 5607de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(byteBuffer); 5617de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 562d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 563d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 564d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 5657de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jobject cropRect = NULL; 5667de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar int32_t left, top, right, bottom; 5677de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (buffer->meta()->findRect("crop-rect", &left, &top, &right, &bottom)) { 5687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> rectClazz( 5697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("android/graphics/Rect")); 5707de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(rectClazz.get() != NULL); 5717de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID rectConstructID = env->GetMethodID( 5737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar rectClazz.get(), "<init>", "(IIII)V"); 5747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cropRect = env->NewObject( 5767de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar rectClazz.get(), rectConstructID, left, top, right + 1, bottom + 1); 5777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar ScopedLocalRef<jclass> imageClazz( 5807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env, env->FindClass("android/media/MediaCodec$MediaImage")); 5817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar CHECK(imageClazz.get() != NULL); 5827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar jmethodID imageConstructID = env->GetMethodID(imageClazz.get(), "<init>", 5847de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;ZJIILandroid/graphics/Rect;)V"); 5857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = env->NewObject(imageClazz.get(), imageConstructID, 5877de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer, infoBuffer, 5887de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jboolean)!input /* readOnly */, 5897de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jlong)timestamp, 5907de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar (jint)0 /* xOffset */, (jint)0 /* yOffset */, cropRect); 5917de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5927de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar // if MediaImage creation fails, return null 5937de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (env->ExceptionCheck()) { 5947de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->ExceptionDescribe(); 5957de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->ExceptionClear(); 5967de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar *buf = NULL; 5977de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 5987de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 5997de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar if (cropRect != NULL) { 6007de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(cropRect); 6017de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar cropRect = NULL; 6027de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar } 6037de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 6047de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(byteBuffer); 6057de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar byteBuffer = NULL; 6067de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 6077de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar env->DeleteLocalRef(infoBuffer); 6087de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar infoBuffer = NULL; 6097de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar 610d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return OK; 611d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 612d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 613056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const { 614056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo AString name; 615056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 616056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = mCodec->getName(&name); 617056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 618056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err != OK) { 619056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return err; 620056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 621056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 622056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo *nameStr = env->NewStringUTF(name.c_str()); 623056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 624056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return OK; 625056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 626056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 627f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essickstatus_t JMediaCodec::getMetrics(JNIEnv *, MediaAnalyticsItem * &reply) const { 6280e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 6290e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick status_t status = mCodec->getMetrics(reply); 6300e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick return status; 6310e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick} 6320e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 633226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatus_t JMediaCodec::setParameters(const sp<AMessage> &msg) { 634226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return mCodec->setParameters(msg); 635226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 636226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 637b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) { 638b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mSurfaceTextureClient != NULL) { 639b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode); 640b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 641b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 642b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 6435f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic jthrowable createCodecException( 6445f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) { 6455f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung ScopedLocalRef<jclass> clazz( 6465f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, env->FindClass("android/media/MediaCodec$CodecException")); 6475f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(clazz.get() != NULL); 6485f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 649c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu const jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(IILjava/lang/String;)V"); 6505f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(ctor != NULL); 6515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 6525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung ScopedLocalRef<jstring> msgObj( 6535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, env->NewStringUTF(msg != NULL ? msg : String8::format("Error %#x", err))); 6545f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 6555f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // translate action code to Java equivalent 6565f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung switch (actionCode) { 6575f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case ACTION_CODE_TRANSIENT: 6585f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = gCodecActionCodes.codecActionTransient; 6595f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 6605f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case ACTION_CODE_RECOVERABLE: 6615f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = gCodecActionCodes.codecActionRecoverable; 6625f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 6635f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung default: 6645f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung actionCode = 0; // everything else is fatal 6655f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung break; 6665f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } 6675f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 668c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu /* translate OS errors to Java API CodecException errorCodes */ 669c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu switch (err) { 670c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu case NO_MEMORY: 671c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu err = gCodecErrorCodes.errorInsufficientResource; 672c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu break; 673c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu case DEAD_OBJECT: 674c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu err = gCodecErrorCodes.errorReclaimed; 675c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu break; 676c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu default: /* Other error codes go out as is. */ 677c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu break; 678c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu } 679c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu 680c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu return (jthrowable)env->NewObject(clazz.get(), ctor, err, actionCode, msgObj.get()); 6815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} 6825f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 6838d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::handleCallback(const sp<AMessage> &msg) { 6848d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang int32_t arg1, arg2 = 0; 6858d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject obj = NULL; 6868d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("callbackID", &arg1)); 6878d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang JNIEnv *env = AndroidRuntime::getJNIEnv(); 6888d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6898d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang switch (arg1) { 6908d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_INPUT_AVAILABLE: 691aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 6928d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("index", &arg2)); 6938d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang break; 6948d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 6958d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 6968d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_OUTPUT_AVAILABLE: 6978d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { 6988d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("index", &arg2)); 6998d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7008d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang size_t size, offset; 7018d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang int64_t timeUs; 7028d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang uint32_t flags; 7038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findSize("size", &size)); 7048d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findSize("offset", &offset)); 7058d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt64("timeUs", &timeUs)); 7068d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("flags", (int32_t *)&flags)); 7078d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7088d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang ScopedLocalRef<jclass> clazz( 7098d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env, env->FindClass("android/media/MediaCodec$BufferInfo")); 7108d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "()V"); 7118d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 7128d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7138d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang obj = env->NewObject(clazz.get(), ctor); 7148d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7158d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (obj == NULL) { 7168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (env->ExceptionCheck()) { 7178d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang ALOGE("Could not create MediaCodec.BufferInfo."); 7188d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->ExceptionClear(); 7198d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 7208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 7218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 722aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 723aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->CallVoidMethod(obj, method, (jint)offset, (jint)size, timeUs, flags); 725aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 726aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 727aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_ERROR: 729aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 73094686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang int32_t err, actionCode; 73194686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang CHECK(msg->findInt32("err", &err)); 7328d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findInt32("actionCode", &actionCode)); 733aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7345f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // note that DRM errors could conceivably alias into a CodecException 7355f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung obj = (jobject)createCodecException(env, err, actionCode); 736aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7378d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (obj == NULL) { 7388d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (env->ExceptionCheck()) { 73994686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang ALOGE("Could not create CodecException object."); 7408d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->ExceptionClear(); 7418d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 7428d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 7438d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 7448d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 745aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 746aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 747aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 748aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7498d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case MediaCodec::CB_OUTPUT_FORMAT_CHANGED: 750aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { 7518d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang sp<AMessage> format; 7528d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang CHECK(msg->findMessage("format", &format)); 753aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 7548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (OK != ConvertMessageToMap(env, format, &obj)) { 7558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jniThrowException(env, "java/lang/IllegalStateException", NULL); 7568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 7578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 758aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 759aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber break; 760aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 761aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 762aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber default: 763aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber TRESPASS(); 764aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber } 7658d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7668d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->CallVoidMethod( 7678d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang mObject, 7688d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang gFields.postEventFromNativeID, 7698d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang EVENT_CALLBACK, 7708d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang arg1, 7718d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang arg2, 7728d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang obj); 7738d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 7748d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang env->DeleteLocalRef(obj); 775aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 776aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 777d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarvoid JMediaCodec::handleFrameRenderedNotification(const sp<AMessage> &msg) { 778d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar int32_t arg1 = 0, arg2 = 0; 779d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar jobject obj = NULL; 780d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar JNIEnv *env = AndroidRuntime::getJNIEnv(); 781d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 782d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar sp<AMessage> data; 783d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar CHECK(msg->findMessage("data", &data)); 784d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 785d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar status_t err = ConvertMessageToMap(env, data, &obj); 786d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar if (err != OK) { 787d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar jniThrowException(env, "java/lang/IllegalStateException", NULL); 788d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar return; 789d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 790d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 791d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar env->CallVoidMethod( 792d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar mObject, gFields.postEventFromNativeID, 793d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar EVENT_FRAME_RENDERED, arg1, arg2, obj); 794d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 795d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar env->DeleteLocalRef(obj); 796d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar} 797d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 7988d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::onMessageReceived(const sp<AMessage> &msg) { 7998d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang switch (msg->what()) { 8008d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang case kWhatCallbackNotify: 8018d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { 8028d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang handleCallback(msg); 8038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang break; 8048d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 805d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar case kWhatFrameRendered: 806d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar { 807d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar handleFrameRenderedNotification(msg); 808d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar break; 809d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 8108d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang default: 8118d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang TRESPASS(); 8128d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 813aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber} 814aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 81588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 81688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 81788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 81888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 81988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 82088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 82188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 82288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 823075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat sp<JMediaCodec> old = (JMediaCodec *)env->GetLongField(thiz, gFields.context); 82488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 82588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 82688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 82788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 828128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang /* release MediaCodec and stop the looper now before decStrong. 829128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * otherwise JMediaCodec::~JMediaCodec() could be called from within 830128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * its message handler, doing release() from there will deadlock 831128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang * (as MediaCodec::release() post synchronous message to the same looper) 832128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang */ 833128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang old->release(); 83488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 83588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 836075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, gFields.context, (jlong)codec.get()); 83788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 83888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 83988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 84088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 84188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 842075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (JMediaCodec *)env->GetLongField(thiz, gFields.context); 84388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 84488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 84588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 84688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 84788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 84888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8495f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic void throwCodecException(JNIEnv *env, status_t err, int32_t actionCode, const char *msg) { 8505f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jthrowable exception = createCodecException(env, err, actionCode, msg); 8515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->Throw(exception); 8525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} 8535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 854bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { 8558d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 8568d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$CryptoException")); 8578d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 858bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 859bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jmethodID constructID = 8608d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V"); 861bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(constructID != NULL); 862bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 8633ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker const char *defaultMsg = "Unknown Error"; 864bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 8655f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung /* translate OS errors to Java API CryptoException errorCodes (which are positive) */ 8663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker switch (err) { 8673ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_NO_LICENSE: 8683ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorNoKey; 8693ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "Crypto key not available"; 8703ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 8713ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_LICENSE_EXPIRED: 8723ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorKeyExpired; 8733ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "License expired"; 8743ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 8753ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_RESOURCE_BUSY: 8763ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorResourceBusy; 8773ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "Resource busy or unavailable"; 8783ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 879336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION: 880336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection; 8813ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "Required output protections are not active"; 882336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker break; 88396a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker case ERROR_DRM_SESSION_NOT_OPENED: 88496a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker err = gCryptoErrorCodes.cryptoErrorSessionNotOpened; 8853ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker defaultMsg = "Attempted to use a closed session"; 88696a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker break; 887d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker case ERROR_DRM_CANNOT_HANDLE: 888d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker err = gCryptoErrorCodes.cryptoErrorUnsupportedOperation; 889d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker defaultMsg = "Operation not supported in this configuration"; 890d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker break; 8915f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung default: /* Other negative DRM error codes go out as is. */ 8923ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 8933ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker } 8943ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 8953ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker jstring msgObj = env->NewStringUTF(msg != NULL ? msg : defaultMsg); 8963ccb34d7070d73ba6c7842801b070b41de32b842Jeff Tinker 897bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jthrowable exception = 8988d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj); 899bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 900bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->Throw(exception); 901bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber} 902bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 903bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary( 9045f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung JNIEnv *env, status_t err, int32_t actionCode = ACTION_CODE_FATAL, 9055f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const char *msg = NULL) { 90688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 90788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 90888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 90988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 91188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 91288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 91488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 91588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 91788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 91888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9195f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung case INVALID_OPERATION: 9205f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/IllegalStateException", msg); 9215f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 9223ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 9235e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar case BAD_VALUE: 9245e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar jniThrowException(env, "java/lang/IllegalArgumentException", msg); 9255e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar return 0; 9265e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 92788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 9285f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung if (isCryptoError(err)) { 9295f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwCryptoException(env, err, msg); 9305f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 9315f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } 9325f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwCodecException(env, err, actionCode, msg); 9335f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return 0; 93488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 93588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 93688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 937d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarstatic void android_media_MediaCodec_native_enableOnFrameRenderedListener( 938d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar JNIEnv *env, 939d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar jobject thiz, 940d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar jboolean enabled) { 941d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 942d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 943d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar if (codec == NULL) { 944d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 945d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar return; 946d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar } 947d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 948d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar status_t err = codec->enableOnFrameRenderedListener(enabled); 949d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 950d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar throwExceptionAsNecessary(env, err); 951d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar} 952d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 9538d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatic void android_media_MediaCodec_native_setCallback( 9548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang JNIEnv *env, 9558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject thiz, 9568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang jobject cb) { 9578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang sp<JMediaCodec> codec = getMediaCodec(env, thiz); 9588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 9598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang if (codec == NULL) { 9605f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 9618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang return; 9628d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang } 9638d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 9648d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang status_t err = codec->setCallback(cb); 9658d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 9668d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang throwExceptionAsNecessary(env, err); 9678d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang} 9688d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 96988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 97088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 97188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 97288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 97388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 9748240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jobject jcrypto, 975d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang jobject descramblerBinderObj, 97688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 97788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 97888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 97988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 9805f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 98188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 98288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 98388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 98488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 98588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 98688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 98788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 98888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 98988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 99088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 99188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 992d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> bufferProducer; 99388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 99464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 99588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 99652800617946c456e78ed010c82d0ec4358368164Mathias Agopian bufferProducer = surface->getIGraphicBufferProducer(); 99788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 99888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 99988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 100088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 100188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 100288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 100388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 100488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 100588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10068240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto; 10078240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto != NULL) { 10088240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto = JCrypto::GetCrypto(env, jcrypto); 10098240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 10108240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 1011d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang sp<IDescrambler> descrambler; 1012d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang if (descramblerBinderObj != NULL) { 1013d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang sp<IBinder> binder = ibinderForJavaObject(env, descramblerBinderObj); 1014d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang descrambler = interface_cast<IDescrambler>(binder); 1015d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang } 1016d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 1017d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang err = codec->configure(format, bufferProducer, crypto, descrambler, flags); 101888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 101988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 102088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 102188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10225e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnarstatic void android_media_MediaCodec_native_setSurface( 10235e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar JNIEnv *env, 10245e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar jobject thiz, 10255e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar jobject jsurface) { 10265e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 10275e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 10285e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (codec == NULL) { 10295e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 10305e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar return; 10315e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 10325e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 10335e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar sp<IGraphicBufferProducer> bufferProducer; 10345e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (jsurface != NULL) { 10355e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 10365e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar if (surface != NULL) { 10375e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar bufferProducer = surface->getIGraphicBufferProducer(); 10385e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } else { 10395e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar jniThrowException( 10405e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar env, 10415e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar "java/lang/IllegalArgumentException", 10425e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar "The surface has been released"); 10435e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar return; 10445e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 10455e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar } 10465e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 10475e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar status_t err = codec->setSurface(bufferProducer); 10485e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar throwExceptionAsNecessary(env, err); 10495e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar} 10505e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 10518034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangsp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface( 10528034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang JNIEnv* env, jobject object) { 10538034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<PersistentSurface> persistentSurface; 10548034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10558034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jobject lock = env->GetObjectField( 10568034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, gPersistentSurfaceClassInfo.mLock); 10578034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (env->MonitorEnter(lock) == JNI_OK) { 10588034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface = reinterpret_cast<PersistentSurface *>( 10598034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->GetLongField(object, 10608034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mPersistentObject)); 10618034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->MonitorExit(lock); 10628034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10638034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->DeleteLocalRef(lock); 10648034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10658034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return persistentSurface; 10668034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 10678034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10688034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic jobject android_media_MediaCodec_createPersistentInputSurface( 10698034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang JNIEnv* env, jclass /* clazz */) { 10708034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang ALOGV("android_media_MediaCodec_createPersistentInputSurface"); 10718034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<PersistentSurface> persistentSurface = 10728034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang MediaCodec::CreatePersistentInputSurface(); 10738034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10748034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (persistentSurface == NULL) { 10758034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return NULL; 10768034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10778034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10788034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<Surface> surface = new Surface( 10798034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface->getBufferProducer(), true); 10808034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (surface == NULL) { 10818034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return NULL; 10828034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10838034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10848034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jobject object = env->NewObject( 10858034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.clazz, 10868034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.ctor); 10878034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10888034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (object == NULL) { 10898034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (env->ExceptionCheck()) { 10908034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang ALOGE("Could not create PersistentSurface."); 10918034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->ExceptionClear(); 10928034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10938034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return NULL; 10948034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 10958034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 10968034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jobject lock = env->GetObjectField( 10978034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, gPersistentSurfaceClassInfo.mLock); 10988034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (env->MonitorEnter(lock) == JNI_OK) { 10998034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->CallVoidMethod( 11008034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, 11018034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.setNativeObjectLocked, 11028034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (jlong)surface.get()); 11038034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->SetLongField( 11048034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, 11058034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mPersistentObject, 11068034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (jlong)persistentSurface.get()); 11078034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->MonitorExit(lock); 11088034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } else { 11098034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->DeleteLocalRef(object); 11108034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object = NULL; 11118034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11128034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->DeleteLocalRef(lock); 11138034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11148034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (object != NULL) { 11158034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang surface->incStrong(&sRefBaseOwner); 11168034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface->incStrong(&sRefBaseOwner); 11178034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11188034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11198034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return object; 11208034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 11218034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11228034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic void android_media_MediaCodec_releasePersistentInputSurface( 11238034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang JNIEnv* env, jclass /* clazz */, jobject object) { 11248034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<PersistentSurface> persistentSurface; 11258034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11268034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jobject lock = env->GetObjectField( 11278034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, gPersistentSurfaceClassInfo.mLock); 11288034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (env->MonitorEnter(lock) == JNI_OK) { 11298034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface = reinterpret_cast<PersistentSurface *>( 11308034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->GetLongField( 11318034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, gPersistentSurfaceClassInfo.mPersistentObject)); 11328034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->SetLongField( 11338034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang object, 11348034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mPersistentObject, 11358034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (jlong)0); 11368034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->MonitorExit(lock); 11378034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11388034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang env->DeleteLocalRef(lock); 11398034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11408034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (persistentSurface != NULL) { 11418034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang persistentSurface->decStrong(&sRefBaseOwner); 11428034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11438034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang // no need to release surface as it will be released by Surface's jni 11448034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 11458034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11469560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhangstatic void android_media_MediaCodec_setInputSurface( 11478034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang JNIEnv* env, jobject thiz, jobject object) { 11489560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang ALOGV("android_media_MediaCodec_setInputSurface"); 11498034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11508034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<JMediaCodec> codec = getMediaCodec(env, thiz); 11518034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (codec == NULL) { 11528034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang throwExceptionAsNecessary(env, INVALID_OPERATION); 11538034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang return; 11548034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11558034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11568034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang sp<PersistentSurface> persistentSurface = 11578034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang android_media_MediaCodec_getPersistentInputSurface(env, object); 11588034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11599560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang status_t err = codec->setInputSurface(persistentSurface); 11608034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang if (err != NO_ERROR) { 11618034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang throwExceptionAsNecessary(env, err); 11628034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang } 11638034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} 11648034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 11652621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env, 11662621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 11672621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_createInputSurface"); 11682621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11692621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 11702621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 11715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 11722621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 11732621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 11742621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11752621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Tell the MediaCodec that we want to use a Surface as input. 11762621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer> bufferProducer; 11772621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->createInputSurface(&bufferProducer); 11782621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (err != NO_ERROR) { 11792621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 11802621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 11812621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 11822621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 11832621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Wrap the IGBP in a Java-language Surface. 11842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return android_view_Surface_createFromIGraphicBufferProducer(env, 11852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden bufferProducer); 11862621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 11872621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 118888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 118988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 119088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 119188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 119288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 119388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 11945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 119588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 119688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 119788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 119888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 119988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12005f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, "start failed"); 120188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 120288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 120388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 120488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 120588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 120688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 120788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 120888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12095f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 121088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 121188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 121288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 121388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 121488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 121588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 121688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 121788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12181e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatic void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) { 12191e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar ALOGV("android_media_MediaCodec_reset"); 12201e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 12211e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 12221e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 12231e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar if (codec == NULL) { 12245f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 12251e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar return; 12261e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar } 12271e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 12281e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar status_t err = codec->reset(); 12291e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar if (err != OK) { 12301e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar // treat all errors as fatal for now, though resource not available 12311e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar // errors could be treated as transient. 12325f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // we also should avoid sending INVALID_OPERATION here due to 12335f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // the transitory nature of reset(), it should not inadvertently 12345f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // trigger an IllegalStateException. 12355f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung err = UNKNOWN_ERROR; 12361e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar } 12371e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar throwExceptionAsNecessary(env, err); 12381e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar} 12391e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 124088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 124188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 124288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 124488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 124588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12465f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 124788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 124888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 124988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 125188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 125388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 125488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 125588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 125688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 125788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 125888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 125988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 126088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 126188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 126288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 126388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 126488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 126588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 126688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 126788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 12685f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 126988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 127088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 127188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1272bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 1273bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 127488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 1275bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timestampUs, flags, &errorDetailMsg); 127688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1277bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 12785f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 127988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 128088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer( 12829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber JNIEnv *env, 12839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jobject thiz, 12849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint index, 12859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint offset, 128691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jobject cryptoInfoObj, 12879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jlong timestampUs, 12889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint flags) { 12899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ALOGV("android_media_MediaCodec_queueSecureInputBuffer"); 12909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 12919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 12929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 12939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (codec == NULL) { 12945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 12959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return; 12969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 12979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 129891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint numSubSamples = 129991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); 130091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 130191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfClearDataObj = 130291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 130391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); 130491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 130591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfEncryptedDataObj = 130691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 130791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); 130891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 130991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray keyObj = 131091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); 131191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 131291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray ivObj = 131391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); 131491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 1315d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jint jmode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); 1316d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker enum CryptoPlugin::Mode mode; 1317d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker if (jmode == gCryptoModes.Unencrypted) { 1318d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker mode = CryptoPlugin::kMode_Unencrypted; 1319d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } else if (jmode == gCryptoModes.AesCtr) { 1320d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker mode = CryptoPlugin::kMode_AES_CTR; 1321d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } else if (jmode == gCryptoModes.AesCbc) { 1322d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker mode = CryptoPlugin::kMode_AES_CBC; 1323d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } else { 1324d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker throwExceptionAsNecessary(env, INVALID_OPERATION); 1325d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker return; 1326d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } 1327d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1328d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jobject patternObj = env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID); 1329d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1330d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CryptoPlugin::Pattern pattern; 1331e872ac45f79ca2c0b538df891d983e3d5e037574Jeff Tinker if (patternObj == NULL) { 1332e872ac45f79ca2c0b538df891d983e3d5e037574Jeff Tinker pattern.mEncryptBlocks = 0; 1333e872ac45f79ca2c0b538df891d983e3d5e037574Jeff Tinker pattern.mSkipBlocks = 0; 1334e872ac45f79ca2c0b538df891d983e3d5e037574Jeff Tinker } else { 1335d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker pattern.mEncryptBlocks = env->GetIntField(patternObj, gFields.patternEncryptBlocksID); 1336d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker pattern.mSkipBlocks = env->GetIntField(patternObj, gFields.patternSkipBlocksID); 1337d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker } 133891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 13399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber status_t err = OK; 13409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::SubSample *subSamples = NULL; 13429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *key = NULL; 13439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *iv = NULL; 13449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numSubSamples <= 0) { 13469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 13479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj == NULL 13489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && numBytesOfEncryptedDataObj == NULL) { 13499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 13509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfEncryptedDataObj != NULL 13519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { 13529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 13539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj != NULL 13549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { 13559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 13567ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar // subSamples array may silently overflow if number of samples are too large. Use 13577ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms 13585f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } else if ( CC_UNLIKELY(numSubSamples >= (signed)(INT32_MAX / sizeof(*subSamples))) ) { 13597ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar err = -EINVAL; 13609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 13619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 13629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfClearData = 13649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearDataObj == NULL) 13659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 13669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); 13679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfEncryptedData = 13699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedDataObj == NULL) 13709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 13719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); 13729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = new CryptoPlugin::SubSample[numSubSamples]; 13749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber for (jint i = 0; i < numSubSamples; ++i) { 13769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfClearData = 13779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; 13789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfEncryptedData = 13809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedData == NULL) 13819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? 0 : numBytesOfEncryptedData[i]; 13829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfEncryptedData != NULL) { 13859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 13869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); 13879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedData = NULL; 13889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfClearData != NULL) { 13919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 13929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearDataObj, numBytesOfClearData, 0); 13939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearData = NULL; 13949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 13969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 13979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && keyObj != NULL) { 13989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(keyObj) != 16) { 13999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 14009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 14019e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 14029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = env->GetByteArrayElements(keyObj, &isCopy); 14039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 14069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && ivObj != NULL) { 14079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(ivObj) != 16) { 14089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 14099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 14109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 14119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = env->GetByteArrayElements(ivObj, &isCopy); 14129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1415bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 1416bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 14179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK) { 14189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = codec->queueSecureInputBuffer( 14199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, 14209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples, numSubSamples, 14219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (const uint8_t *)key, (const uint8_t *)iv, 1422d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker mode, 1423d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker pattern, 1424bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber timestampUs, 1425bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber flags, 1426bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber &errorDetailMsg); 14279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 14299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (iv != NULL) { 14309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(ivObj, iv, 0); 14319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = NULL; 14329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 14349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (key != NULL) { 14359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(keyObj, key, 0); 14369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = NULL; 14379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 14389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 14399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber delete[] subSamples; 14409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = NULL; 14419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1442bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 14435f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 14449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 14459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 144688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 144788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 144888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 144988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 145088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 145188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 145288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 14535f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 145488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 145588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 145688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 145788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 145888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 145988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 146088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 1461075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 146288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 146388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 146488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 146588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 146688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 146788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 146888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 146988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 147088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 147188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 147288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 147388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 14745f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 14750e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber return 0; 147688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 147788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 147888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 147988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 148088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 148188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 148288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 1483075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 148488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 148588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 148688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 148788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 148888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 148988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 14907c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar JNIEnv *env, jobject thiz, 14917c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar jint index, jboolean render, jboolean updatePTS, jlong timestampNs) { 149288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 149388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 149488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 149588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 149688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 14975f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 149888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 149988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 150088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15017c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs); 150288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 150388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 150488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 150588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15062621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env, 15072621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 15082621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_signalEndOfInputStream"); 15092621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 15102621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 15112621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 15125f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 15132621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return; 15142621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 15152621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 15162621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->signalEndOfInputStream(); 15172621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 15182621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 15192621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 15202621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1521d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getFormatNative( 1522d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input) { 1523d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getFormatNative"); 1524d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1525d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1526d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1527d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 15285f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1529d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1530d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1531d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1532d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject format; 1533d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getFormat(env, input, &format); 1534d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1535d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1536d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return format; 1537d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1538d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1539d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1540d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1541d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1542d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1543d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1544d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getOutputFormatForIndexNative( 1545d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jint index) { 1546d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getOutputFormatForIndexNative"); 154788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 154888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 154988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 155088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 15515f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 155288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 155388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 155488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 155588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 1556d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getOutputFormat(env, index, &format); 155788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 155888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 155988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 156088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 156188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 156288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 156388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 156488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 156588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 156688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 156788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 156888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 156988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 157088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 157188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 157288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 157388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 15745f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 157588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 157688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 157788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 157888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 157988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 158088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 158188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 158288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 158388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 158488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1585cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if we're out of memory, an exception was already thrown 1586cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (err != NO_MEMORY) { 1587cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen throwExceptionAsNecessary(env, err); 1588cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 158988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 159088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 159188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 159288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1593d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getBuffer( 1594d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input, jint index) { 1595d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getBuffer"); 1596d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1597d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1598d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1599d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 16005f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1601d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1602d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1603d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1604d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject buffer; 1605d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getBuffer(env, input, index, &buffer); 1606d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1607d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1608d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return buffer; 1609d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1610d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1611d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if we're out of memory, an exception was already thrown 1612d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != NO_MEMORY) { 1613d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1614d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1615d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1616d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1617d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1618d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1619d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getImage( 1620d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar JNIEnv *env, jobject thiz, jboolean input, jint index) { 1621d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar ALOGV("android_media_MediaCodec_getImage"); 1622d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1623d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1624d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1625d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (codec == NULL) { 16265f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1627d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1628d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1629d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1630d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar jobject image; 1631d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar status_t err = codec->getImage(env, input, index, &image); 1632d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1633d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err == OK) { 1634d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return image; 1635d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1636d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1637d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar // if we're out of memory, an exception was already thrown 1638d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar if (err != NO_MEMORY) { 1639d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar throwExceptionAsNecessary(env, err); 1640d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar } 1641d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1642d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar return NULL; 1643d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar} 1644d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1645056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName( 1646056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo JNIEnv *env, jobject thiz) { 1647056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo ALOGV("android_media_MediaCodec_getName"); 1648056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1649056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1650056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1651056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (codec == NULL) { 16525f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1653056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 1654056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 1655056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1656056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jstring name; 1657056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = codec->getName(env, &name); 1658056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1659056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err == OK) { 1660056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return name; 1661056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 1662056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1663056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo throwExceptionAsNecessary(env, err); 1664056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1665056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 1666056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 1667056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 16680e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essickstatic jobject 1669f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essickandroid_media_MediaCodec_native_getMetrics(JNIEnv *env, jobject thiz) 16700e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick{ 1671f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essick ALOGV("android_media_MediaCodec_native_getMetrics"); 16720e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 16730e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick sp<JMediaCodec> codec = getMediaCodec(env, thiz); 16740e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick if (codec == NULL ) { 16750e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick jniThrowException(env, "java/lang/IllegalStateException", NULL); 16760e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick return 0; 16770e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick } 16780e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 16790e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick // get what we have for the metrics from the codec 1680f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essick MediaAnalyticsItem *item = NULL; 1681f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essick 1682f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essick status_t err = codec->getMetrics(env, item); 16830e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick if (err != OK) { 16840e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick ALOGE("getMetrics failed"); 16850e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick return (jobject) NULL; 16860e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick } 16870e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 16880e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, item, NULL); 16890e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 16900e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick // housekeeping 16910e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick delete item; 16920e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick item = NULL; 16930e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 16940e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick return mybundle; 16950e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick} 16960e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 1697226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatic void android_media_MediaCodec_setParameters( 1698226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) { 1699226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber ALOGV("android_media_MediaCodec_setParameters"); 1700226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1701226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1702226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1703226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (codec == NULL) { 17045f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1705226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return; 1706226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 1707226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1708226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<AMessage> params; 1709226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, ¶ms); 1710226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1711226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (err == OK) { 1712226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber err = codec->setParameters(params); 1713226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 1714226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1715226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber throwExceptionAsNecessary(env, err); 1716226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 1717226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1718b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode( 1719b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber JNIEnv *env, jobject thiz, jint mode) { 1720b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 1721b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1722b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (codec == NULL) { 17235f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung throwExceptionAsNecessary(env, INVALID_OPERATION); 1724b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 1725b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 1726b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1727b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW 1728b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 1729b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/InvalidArgumentException", NULL); 1730b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 1731b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 1732b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 1733b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber codec->setVideoScalingMode(mode); 1734b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 1735b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 173688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 17378d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 17388d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec")); 17398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 174088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1741075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J"); 174288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 174391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 1744aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber gFields.postEventFromNativeID = 1745aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber env->GetMethodID( 1746aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V"); 1747aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 1748aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber CHECK(gFields.postEventFromNativeID != NULL); 1749aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 1750d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker jfieldID field; 1751d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_UNENCRYPTED", "I"); 1752d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(field != NULL); 1753d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gCryptoModes.Unencrypted = 1754d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker env->GetStaticIntField(clazz.get(), field); 1755d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1756d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CTR", "I"); 1757d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(field != NULL); 1758d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gCryptoModes.AesCtr = 1759d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker env->GetStaticIntField(clazz.get(), field); 1760d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1761d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CBC", "I"); 1762d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(field != NULL); 1763d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gCryptoModes.AesCbc = 1764d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker env->GetStaticIntField(clazz.get(), field); 1765d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 17668d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo")); 17678d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 176891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 176991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumSubSamplesID = 17708d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numSubSamples", "I"); 177191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumSubSamplesID != NULL); 177291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 177391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfClearDataID = 17748d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I"); 177591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL); 177691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 177791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfEncryptedDataID = 17788d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I"); 177991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL); 178091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 17818d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B"); 178291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoKeyID != NULL); 178391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 17848d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B"); 178591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoIVID != NULL); 178691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 17878d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I"); 178891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoModeID != NULL); 17893ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 1790d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gFields.cryptoInfoPatternID = env->GetFieldID(clazz.get(), "pattern", 1791d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker "Landroid/media/MediaCodec$CryptoInfo$Pattern;"); 1792d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(gFields.cryptoInfoPatternID != NULL); 1793d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1794d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo$Pattern")); 1795d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(clazz.get() != NULL); 1796d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1797d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gFields.patternEncryptBlocksID = env->GetFieldID(clazz.get(), "mEncryptBlocks", "I"); 1798d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(gFields.patternEncryptBlocksID != NULL); 1799d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 1800d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker gFields.patternSkipBlocksID = env->GetFieldID(clazz.get(), "mSkipBlocks", "I"); 1801d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker CHECK(gFields.patternSkipBlocksID != NULL); 1802d4ea5d3eb630476a43da2adb4ac518360bd64758Jeff Tinker 18038d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException")); 18048d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 18053ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 18068d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I"); 18073ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 18088d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorNoKey = 18098d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 18103ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 18118d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I"); 18123ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 18138d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorKeyExpired = 18148d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 18153ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 18168d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I"); 18173ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 18188d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorResourceBusy = 18198d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 18205f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 1821336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_OUTPUT_PROTECTION", "I"); 1822336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker CHECK(field != NULL); 1823336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection = 1824336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker env->GetStaticIntField(clazz.get(), field); 1825336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker 182696a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker field = env->GetStaticFieldID(clazz.get(), "ERROR_SESSION_NOT_OPENED", "I"); 182796a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker CHECK(field != NULL); 182896a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker gCryptoErrorCodes.cryptoErrorSessionNotOpened = 182996a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker env->GetStaticIntField(clazz.get(), field); 183096a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker 1831d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker field = env->GetStaticFieldID(clazz.get(), "ERROR_UNSUPPORTED_OPERATION", "I"); 1832d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker CHECK(field != NULL); 1833d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker gCryptoErrorCodes.cryptoErrorUnsupportedOperation = 1834d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker env->GetStaticIntField(clazz.get(), field); 1835d393216f8a2186eebdb8615c61787ae599c1432fJeff Tinker 18365f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung clazz.reset(env->FindClass("android/media/MediaCodec$CodecException")); 18375f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(clazz.get() != NULL); 18385f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I"); 18395f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(field != NULL); 18405f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung gCodecActionCodes.codecActionTransient = 18415f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->GetStaticIntField(clazz.get(), field); 18425f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 18435f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung field = env->GetStaticFieldID(clazz.get(), "ACTION_RECOVERABLE", "I"); 18445f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung CHECK(field != NULL); 18455f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung gCodecActionCodes.codecActionRecoverable = 18465f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->GetStaticIntField(clazz.get(), field); 18479e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 1848c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_RESOURCE", "I"); 18499e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu CHECK(field != NULL); 1850c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu gCodecErrorCodes.errorInsufficientResource = 18519e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu env->GetStaticIntField(clazz.get(), field); 18529e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu 1853c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu field = env->GetStaticFieldID(clazz.get(), "ERROR_RECLAIMED", "I"); 18549e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu CHECK(field != NULL); 1855c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu gCodecErrorCodes.errorReclaimed = 18569e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu env->GetStaticIntField(clazz.get(), field); 18578034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18588034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang clazz.reset(env->FindClass("android/view/Surface")); 18598034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(clazz.get() != NULL); 18608034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18618034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang field = env->GetFieldID(clazz.get(), "mLock", "Ljava/lang/Object;"); 18628034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(field != NULL); 18638034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mLock = field; 18648034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18658034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang jmethodID method = env->GetMethodID(clazz.get(), "setNativeObjectLocked", "(J)V"); 18668034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(method != NULL); 18678034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.setNativeObjectLocked = method; 18688034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18698034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang clazz.reset(env->FindClass("android/media/MediaCodec$PersistentSurface")); 18708034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(clazz.get() != NULL); 18718034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); 18728034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18738034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang method = env->GetMethodID(clazz.get(), "<init>", "()V"); 18748034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(method != NULL); 18758034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.ctor = method; 18768034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 18778034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang field = env->GetFieldID(clazz.get(), "mPersistentObject", "J"); 18788034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang CHECK(field != NULL); 18798034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang gPersistentSurfaceClassInfo.mPersistentObject = field; 188088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 188188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 188288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 188388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 188488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 188588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 18865f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/NullPointerException", NULL); 188788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 188888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 188988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 189088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 189188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 189288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 189388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 189488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 189588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 189688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 189788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18985f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung const status_t err = codec->initCheck(); 18995f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung if (err == NAME_NOT_FOUND) { 19005f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // fail and do not try again. 19015f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/lang/IllegalArgumentException", 19025f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung String8::format("Failed to initialize %s, error %#x", tmp, err)); 1903c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu env->ReleaseStringUTFChars(name, tmp); 1904c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu return; 1905c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu } if (err == NO_MEMORY) { 1906c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu throwCodecException(env, err, ACTION_CODE_TRANSIENT, 1907c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu String8::format("Failed to initialize %s, error %#x", tmp, err)); 19085f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 19095f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung return; 19105f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung } else if (err != OK) { 19115f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung // believed possible to try again 19125f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung jniThrowException(env, "java/io/IOException", 19135f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung String8::format("Failed to find matching codec %s, error %#x", tmp, err)); 19145f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 191588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 191688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 191788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19185f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung env->ReleaseStringUTFChars(name, tmp); 19195f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung 1920aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber codec->registerSelf(); 1921aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber 192288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 192388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 192488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 192588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 192688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 192788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 192888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 192988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 193076f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = { 1931d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_release", "()V", (void *)android_media_MediaCodec_release }, 193288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19331e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar { "native_reset", "()V", (void *)android_media_MediaCodec_reset }, 19341e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar 19358034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang { "native_releasePersistentInputSurface", 19368034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang "(Landroid/view/Surface;)V", 19378034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (void *)android_media_MediaCodec_releasePersistentInputSurface}, 19388034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 19398034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang { "native_createPersistentInputSurface", 19408034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang "()Landroid/media/MediaCodec$PersistentSurface;", 19418034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang (void *)android_media_MediaCodec_createPersistentInputSurface }, 19428034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 19439560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang { "native_setInputSurface", "(Landroid/view/Surface;)V", 19449560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang (void *)android_media_MediaCodec_setInputSurface }, 19458034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang 1946d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar { "native_enableOnFrameRenderedListener", "(Z)V", 1947d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar (void *)android_media_MediaCodec_native_enableOnFrameRenderedListener }, 1948d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar 19498d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang { "native_setCallback", 19508d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang "(Landroid/media/MediaCodec$Callback;)V", 19518d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang (void *)android_media_MediaCodec_native_setCallback }, 19528d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang 195388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 19548240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;" 1955d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang "Landroid/media/MediaCrypto;Landroid/os/IBinder;I)V", 195688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 195788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19585e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar { "native_setSurface", 19595e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar "(Landroid/view/Surface;)V", 19605e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar (void *)android_media_MediaCodec_native_setSurface }, 19615e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar 19622621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "createInputSurface", "()Landroid/view/Surface;", 19632621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_createInputSurface }, 19642621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1965d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_start", "()V", (void *)android_media_MediaCodec_start }, 1966aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber { "native_stop", "()V", (void *)android_media_MediaCodec_stop }, 1967d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_flush", "()V", (void *)android_media_MediaCodec_flush }, 196888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1969d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_queueInputBuffer", "(IIIJI)V", 197088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 197188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1972d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", 19739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (void *)android_media_MediaCodec_queueSecureInputBuffer }, 19749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 1975d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_dequeueInputBuffer", "(J)I", 197688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 197788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1978d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "native_dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 197988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 198088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19817c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar { "releaseOutputBuffer", "(IZZJ)V", 198288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 198388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "signalEndOfInputStream", "()V", 19852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_signalEndOfInputStream }, 19862621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 1987d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getFormatNative", "(Z)Ljava/util/Map;", 1988d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getFormatNative }, 1989d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1990d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getOutputFormatNative", "(I)Ljava/util/Map;", 1991d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getOutputFormatForIndexNative }, 199288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 199388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 199488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 199588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1996d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getBuffer", "(ZI)Ljava/nio/ByteBuffer;", 1997d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getBuffer }, 1998d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 1999d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar { "getImage", "(ZI)Landroid/media/Image;", 2000d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar (void *)android_media_MediaCodec_getImage }, 2001d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar 2002056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo { "getName", "()Ljava/lang/String;", 2003056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo (void *)android_media_MediaCodec_getName }, 2004056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 200510353e36018224b86ef2918d1d68107459d445cfRay Essick { "native_getMetrics", "()Landroid/os/PersistableBundle;", 2006f2d0e40bf01fa133dd6b36f3716005d53fa9776cRay Essick (void *)android_media_MediaCodec_native_getMetrics}, 20070e0fee1e3a04023c9ec122d3bd7da54e9565c3e7Ray Essick 2008226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V", 2009226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber (void *)android_media_MediaCodec_setParameters }, 2010226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 2011b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber { "setVideoScalingMode", "(I)V", 2012b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber (void *)android_media_MediaCodec_setVideoScalingMode }, 2013b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 201488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 201588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 201688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 201788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 201888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 201988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 202088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 202188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 202288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 202388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 202488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 202588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 202688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 2027