android_media_MediaCodec.cpp revision e5b641e6effda54945577e9348df86213b38baeb
188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber/*
288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Copyright 2012, The Android Open Source Project
388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * you may not use this file except in compliance with the License.
688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * You may obtain a copy of the License at
788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
1088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Unless required by applicable law or agreed to in writing, software
1188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * See the License for the specific language governing permissions and
1488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * limitations under the License.
1588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber */
1688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//#define LOG_NDEBUG 0
1888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#define LOG_TAG "MediaCodec-JNI"
1988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <utils/Log.h>
2088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_MediaCodec.h"
2288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber#include "android_media_MediaCrypto.h"
2488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_Utils.h"
2588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/AndroidRuntime.h"
2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/android_view_Surface.h"
2788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "jni.h"
2888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "JNIHelp.h"
2988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
307ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar#include <cutils/compiler.h>
317ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar
328335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <gui/Surface.h>
338335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian
340e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber#include <media/ICrypto.h>
3588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaCodec.h>
3688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h>
3888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ALooper.h>
3988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h>
40bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber#include <media/stagefright/foundation/AString.h>
4188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h>
428034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang#include <media/stagefright/PersistentSurface.h>
438d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber#include <nativehelper/ScopedLocalRef.h>
448d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber
45b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber#include <system/window.h>
46b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android {
4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
4988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!!
5088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum {
5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    DEQUEUE_INFO_TRY_AGAIN_LATER            = -1,
5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED      = -2,
5388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED     = -3,
5488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
5588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
56aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huberenum {
578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    EVENT_CALLBACK = 1,
588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    EVENT_SET_CALLBACK = 2,
59d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    EVENT_FRAME_RENDERED = 3,
60aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber};
61aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
625f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic struct CryptoErrorCodes {
633ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    jint cryptoErrorNoKey;
643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    jint cryptoErrorKeyExpired;
653ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    jint cryptoErrorResourceBusy;
66336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker    jint cryptoErrorInsufficientOutputProtection;
6796a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker    jint cryptoErrorSessionNotOpened;
683ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker} gCryptoErrorCodes;
693ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
705f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic struct CodecActionCodes {
715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    jint codecActionTransient;
725f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    jint codecActionRecoverable;
735f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung} gCodecActionCodes;
745f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
75c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wustatic struct CodecErrorCodes {
76c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    jint errorInsufficientResource;
77c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    jint errorReclaimed;
78c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu} gCodecErrorCodes;
799e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu
808034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic struct {
818034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jclass clazz;
828034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jfieldID mLock;
838034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jfieldID mPersistentObject;
848034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jmethodID ctor;
858034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jmethodID setNativeObjectLocked;
868034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang} gPersistentSurfaceClassInfo;
878034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t {
8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jfieldID context;
90aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    jmethodID postEventFromNativeID;
9191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoNumSubSamplesID;
9291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoNumBytesOfClearDataID;
9391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoNumBytesOfEncryptedDataID;
9491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoKeyID;
9591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoIVID;
9691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoModeID;
9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
9988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields;
1008034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic const void *sRefBaseOwner;
10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber////////////////////////////////////////////////////////////////////////////////
10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec(
10588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz,
10688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        const char *name, bool nameIsType, bool encoder)
10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    : mClass(NULL),
1088d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang      mObject(NULL) {
10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jclass clazz = env->GetObjectClass(thiz);
11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(clazz != NULL);
11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
11288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mClass = (jclass)env->NewGlobalRef(clazz);
11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mObject = env->NewWeakGlobalRef(thiz);
11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1157de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    cacheJavaObjects(env);
1167de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mLooper = new ALooper;
11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mLooper->setName("MediaCodec_looper");
11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mLooper->start(
12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            false,      // runOnCallingThread
122aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            true,       // canCallJava
1238d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            PRIORITY_FOREGROUND);
12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (nameIsType) {
1265f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus);
12788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else {
1285f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus);
12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
1305f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    CHECK((mCodec != NULL) != (mInitStatus != OK));
13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::cacheJavaObjects(JNIEnv *env) {
1347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    jclass clazz = (jclass)env->FindClass("java/nio/ByteBuffer");
1357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferClass = (jclass)env->NewGlobalRef(clazz);
1367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(mByteBufferClass != NULL);
1377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
1387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    ScopedLocalRef<jclass> byteOrderClass(
1397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            env, env->FindClass("java/nio/ByteOrder"));
1407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(byteOrderClass.get() != NULL);
1417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
1427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    jmethodID nativeOrderID = env->GetStaticMethodID(
1437de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;");
1447de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(nativeOrderID != NULL);
1457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
1467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    jobject nativeByteOrderObj =
1477de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID);
1487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mNativeByteOrderObj = env->NewGlobalRef(nativeByteOrderObj);
1497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(mNativeByteOrderObj != NULL);
1507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    env->DeleteLocalRef(nativeByteOrderObj);
1517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    nativeByteOrderObj = NULL;
1527de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
1537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferOrderMethodID = env->GetMethodID(
1547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            mByteBufferClass,
1557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            "order",
1567de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
1577de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(mByteBufferOrderMethodID != NULL);
1587de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
1597de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferAsReadOnlyBufferMethodID = env->GetMethodID(
1607de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            mByteBufferClass, "asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;");
1617de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(mByteBufferAsReadOnlyBufferMethodID != NULL);
1627de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
1637de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferPositionMethodID = env->GetMethodID(
1647de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            mByteBufferClass, "position", "(I)Ljava/nio/Buffer;");
1657de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(mByteBufferPositionMethodID != NULL);
1667de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
1677de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferLimitMethodID = env->GetMethodID(
1687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            mByteBufferClass, "limit", "(I)Ljava/nio/Buffer;");
1697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(mByteBufferLimitMethodID != NULL);
1707de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar}
1717de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
17288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const {
1735f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    return mInitStatus;
17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
176aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Hubervoid JMediaCodec::registerSelf() {
177aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    mLooper->registerHandler(this);
178aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}
179aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
180128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhangvoid JMediaCodec::release() {
181d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo    if (mCodec != NULL) {
182d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo        mCodec->release();
183d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo        mCodec.clear();
1845f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        mInitStatus = NO_INIT;
185d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo    }
18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
187128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang    if (mLooper != NULL) {
188128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        mLooper->unregisterHandler(id());
189128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        mLooper->stop();
190128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        mLooper.clear();
191128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang    }
192128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang}
193128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang
194128b012cc8c2369136bb8450bc91c81aebe18506Chong ZhangJMediaCodec::~JMediaCodec() {
195128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang    if (mCodec != NULL || mLooper != NULL) {
196128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        /* MediaCodec and looper should have been released explicitly already
197128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * in setMediaCodec() (see comments in setMediaCodec()).
198128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         *
199128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * Otherwise JMediaCodec::~JMediaCodec() might be called from within the
200128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * message handler, doing release() there risks deadlock as MediaCodec::
201128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * release() post synchronous message to the same looper.
202128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         *
203128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * Print a warning and try to proceed with releasing.
204128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         */
205128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()...");
206128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        release();
207128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec().");
208128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang    }
209128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang
21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
21188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->DeleteWeakGlobalRef(mObject);
21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mObject = NULL;
21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->DeleteGlobalRef(mClass);
21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mClass = NULL;
2167de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    deleteJavaObjects(env);
2177de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar}
2187de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
2197de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarvoid JMediaCodec::deleteJavaObjects(JNIEnv *env) {
2207de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    env->DeleteGlobalRef(mByteBufferClass);
2217de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferClass = NULL;
2227de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    env->DeleteGlobalRef(mNativeByteOrderObj);
2237de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mNativeByteOrderObj = NULL;
2247de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
2257de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferOrderMethodID = NULL;
2267de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferAsReadOnlyBufferMethodID = NULL;
2277de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferPositionMethodID = NULL;
2287de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    mByteBufferLimitMethodID = NULL;
22988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
231d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarstatus_t JMediaCodec::enableOnFrameRenderedListener(jboolean enable) {
232d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    if (enable) {
233d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        if (mOnFrameRenderedNotification == NULL) {
234d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar            mOnFrameRenderedNotification = new AMessage(kWhatFrameRendered, this);
235d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        }
236d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    } else {
237d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        mOnFrameRenderedNotification.clear();
238d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    }
239d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
240d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    return mCodec->setOnFrameRenderedNotification(mOnFrameRenderedNotification);
241d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar}
242d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
2438d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatus_t JMediaCodec::setCallback(jobject cb) {
2448d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    if (cb != NULL) {
2458d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        if (mCallbackNotification == NULL) {
24663834f4d23a97b27d830a301328329c7ef682bd5Lajos Molnar            mCallbackNotification = new AMessage(kWhatCallbackNotify, this);
2478d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        }
2488d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    } else {
2498d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        mCallbackNotification.clear();
2508d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    }
2518d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
2528d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    return mCodec->setCallback(mCallbackNotification);
2538d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang}
2548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure(
25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        const sp<AMessage> &format,
257d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        const sp<IGraphicBufferProducer> &bufferProducer,
2588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        const sp<ICrypto> &crypto,
25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        int flags) {
26052800617946c456e78ed010c82d0ec4358368164Mathias Agopian    sp<Surface> client;
261d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    if (bufferProducer != NULL) {
262aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        mSurfaceTextureClient =
263aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            new Surface(bufferProducer, true /* controlledByApp */);
264b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    } else {
265b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        mSurfaceTextureClient.clear();
26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
267b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
268b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    return mCodec->configure(format, mSurfaceTextureClient, crypto, flags);
26988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
27088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2715e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnarstatus_t JMediaCodec::setSurface(
2725e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        const sp<IGraphicBufferProducer> &bufferProducer) {
2735e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    sp<Surface> client;
2745e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    if (bufferProducer != NULL) {
2755e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        client = new Surface(bufferProducer, true /* controlledByApp */);
2765e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    }
2775e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    status_t err = mCodec->setSurface(client);
2785e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    if (err == OK) {
2795e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        mSurfaceTextureClient = client;
2805e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    }
2815e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    return err;
2825e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar}
2835e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar
2842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface(
2852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
2862621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    return mCodec->createInputSurface(bufferProducer);
2872621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden}
2882621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
2899560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhangstatus_t JMediaCodec::setInputSurface(
2908034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        const sp<PersistentSurface> &surface) {
2919560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang    return mCodec->setInputSurface(surface);
2928034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang}
2938034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() {
2958d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    return mCodec->start();
29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() {
299b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    mSurfaceTextureClient.clear();
300b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
3018d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    return mCodec->stop();
30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() {
30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mCodec->flush();
30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3081e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatus_t JMediaCodec::reset() {
3091e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    return mCodec->reset();
3101e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar}
3111e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer(
31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        size_t index,
314bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        size_t offset, size_t size, int64_t timeUs, uint32_t flags,
315bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        AString *errorDetailMsg) {
316bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    return mCodec->queueInputBuffer(
317bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber            index, offset, size, timeUs, flags, errorDetailMsg);
31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer(
3219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        size_t index,
3229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        size_t offset,
3239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        const CryptoPlugin::SubSample *subSamples,
3249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        size_t numSubSamples,
3259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        const uint8_t key[16],
3269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        const uint8_t iv[16],
3279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        CryptoPlugin::Mode mode,
3289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        int64_t presentationTimeUs,
329bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        uint32_t flags,
330bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        AString *errorDetailMsg) {
3319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    return mCodec->queueSecureInputBuffer(
3329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            index, offset, subSamples, numSubSamples, key, iv, mode,
333bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber            presentationTimeUs, flags, errorDetailMsg);
3349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber}
3359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
3378d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    return mCodec->dequeueInputBuffer(index, timeoutUs);
33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer(
34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) {
34288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t size, offset;
34388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    int64_t timeUs;
34488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    uint32_t flags;
345aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    status_t err = mCodec->dequeueOutputBuffer(
346aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            index, &offset, &size, &timeUs, &flags, timeoutUs);
347aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
348aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    if (err != OK) {
34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3528d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    ScopedLocalRef<jclass> clazz(
3538d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            env, env->FindClass("android/media/MediaCodec$BufferInfo"));
35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3558d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V");
356fef85ef152ab176fd96dbe3047c8025136fa8560Ashok Bhat    env->CallVoidMethod(bufferInfo, method, (jint)offset, (jint)size, timeUs, flags);
35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return OK;
35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3617c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnarstatus_t JMediaCodec::releaseOutputBuffer(
3627c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar        size_t index, bool render, bool updatePTS, int64_t timestampNs) {
3637c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar    if (updatePTS) {
3647c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar        return mCodec->renderOutputBufferAndRelease(index, timestampNs);
3657c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar    }
36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return render
36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        ? mCodec->renderOutputBufferAndRelease(index)
36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        : mCodec->releaseOutputBuffer(index);
36988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3712621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() {
3722621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    return mCodec->signalEndOfInputStream();
3732621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden}
3742621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
375d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getFormat(JNIEnv *env, bool input, jobject *format) const {
37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<AMessage> msg;
37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err;
378d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    err = input ? mCodec->getInputFormat(&msg) : mCodec->getOutputFormat(&msg);
379d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != OK) {
380d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return err;
381d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
382d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
383d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return ConvertMessageToMap(env, msg, format);
384d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
385d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
386d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, size_t index, jobject *format) const {
387d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<AMessage> msg;
388d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err;
389d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if ((err = mCodec->getOutputFormat(index, &msg)) != OK) {
39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
39288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
39388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return ConvertMessageToMap(env, msg, format);
39488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
39588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
39688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers(
39788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, bool input, jobjectArray *bufArray) const {
39888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    Vector<sp<ABuffer> > buffers;
39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
40088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err =
40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        input
40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            ? mCodec->getInputBuffers(&buffers)
40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            : mCodec->getOutputBuffers(&buffers);
40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
40588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
40688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
40788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    *bufArray = (jobjectArray)env->NewObjectArray(
4107de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            buffers.size(), mByteBufferClass, NULL);
411cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    if (*bufArray == NULL) {
412cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        return NO_MEMORY;
413cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    }
41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    for (size_t i = 0; i < buffers.size(); ++i) {
41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        const sp<ABuffer> &buffer = buffers.itemAt(i);
41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
4187de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        jobject byteBuffer = NULL;
4197de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        err = createByteBufferFromABuffer(
4207de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar                env, !input /* readOnly */, true /* clearBuffer */, buffer, &byteBuffer);
4217de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        if (err != OK) {
4227de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            return err;
423cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        }
4247de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        if (byteBuffer != NULL) {
4257de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            env->SetObjectArrayElement(
4267de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar                    *bufArray, i, byteBuffer);
4277de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
428d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            env->DeleteLocalRef(byteBuffer);
4297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            byteBuffer = NULL;
430d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        }
43188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
43288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
43388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return OK;
43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
4367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar// static
4377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::createByteBufferFromABuffer(
4387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        JNIEnv *env, bool readOnly, bool clearBuffer, const sp<ABuffer> &buffer,
4397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        jobject *buf) const {
440d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // if this is an ABuffer that doesn't actually hold any accessible memory,
441d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // use a null ByteBuffer
4427de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    *buf = NULL;
443e5b641e6effda54945577e9348df86213b38baebAaron Vaage
444e5b641e6effda54945577e9348df86213b38baebAaron Vaage    if (buffer == NULL) {
445e5b641e6effda54945577e9348df86213b38baebAaron Vaage        ALOGV("createByteBufferFromABuffer - given NULL, returning NULL");
446e5b641e6effda54945577e9348df86213b38baebAaron Vaage        return OK;
447e5b641e6effda54945577e9348df86213b38baebAaron Vaage    }
448e5b641e6effda54945577e9348df86213b38baebAaron Vaage
449d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (buffer->base() == NULL) {
450d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return OK;
451d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
452d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
453d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject byteBuffer =
4547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        env->NewDirectByteBuffer(buffer->base(), buffer->capacity());
4557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (readOnly && byteBuffer != NULL) {
456d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        jobject readOnlyBuffer = env->CallObjectMethod(
4577de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar                byteBuffer, mByteBufferAsReadOnlyBufferMethodID);
458d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        env->DeleteLocalRef(byteBuffer);
459d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        byteBuffer = readOnlyBuffer;
460d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
461d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (byteBuffer == NULL) {
462d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return NO_MEMORY;
463d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
464d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject me = env->CallObjectMethod(
4657de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            byteBuffer, mByteBufferOrderMethodID, mNativeByteOrderObj);
466d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    env->DeleteLocalRef(me);
467d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    me = env->CallObjectMethod(
4687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            byteBuffer, mByteBufferLimitMethodID,
4697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            clearBuffer ? buffer->capacity() : (buffer->offset() + buffer->size()));
470d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    env->DeleteLocalRef(me);
4717be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    me = env->CallObjectMethod(
4727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            byteBuffer, mByteBufferPositionMethodID,
4737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            clearBuffer ? 0 : buffer->offset());
4747be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    env->DeleteLocalRef(me);
475d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    me = NULL;
476d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
477d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    *buf = byteBuffer;
478d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return OK;
479d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
480d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
4817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnarstatus_t JMediaCodec::getBuffer(
4827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        JNIEnv *env, bool input, size_t index, jobject *buf) const {
4837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    sp<ABuffer> buffer;
4847de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
4857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    status_t err =
4867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        input
4877de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            ? mCodec->getInputBuffer(index, &buffer)
4887de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            : mCodec->getOutputBuffer(index, &buffer);
4897de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
4907de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (err != OK) {
4917de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        return err;
4927de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    }
4937de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
4947de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    return createByteBufferFromABuffer(
4957de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            env, !input /* readOnly */, input /* clearBuffer */, buffer, buf);
4967de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar}
4977de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
498d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getImage(
499d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, bool input, size_t index, jobject *buf) const {
500d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<ABuffer> buffer;
501d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
502d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err =
503d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        input
504d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            ? mCodec->getInputBuffer(index, &buffer)
505d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            : mCodec->getOutputBuffer(index, &buffer);
506d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
507d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != OK) {
508d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return err;
509d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
510d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
511d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // if this is an ABuffer that doesn't actually hold any accessible memory,
512d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // use a null ByteBuffer
513d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    *buf = NULL;
514d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (buffer->base() == NULL) {
515d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return OK;
516d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
517d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
518d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // check if buffer is an image
5197de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    sp<ABuffer> imageData;
5207de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (!buffer->meta()->findBuffer("image-data", &imageData)) {
5217de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        return OK;
5227de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    }
5237de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5247de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    int64_t timestamp = 0;
5257de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (!input && buffer->meta()->findInt64("timeUs", &timestamp)) {
5267de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        timestamp *= 1000; // adjust to ns
5277de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    }
5287de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5297de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    jobject byteBuffer = NULL;
5307de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    err = createByteBufferFromABuffer(
5317de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            env, !input /* readOnly */, input /* clearBuffer */, buffer, &byteBuffer);
5327de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (err != OK) {
5337de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        return OK;
5347de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    }
5357de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5367de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    jobject infoBuffer = NULL;
5377de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    err = createByteBufferFromABuffer(
5387de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            env, true /* readOnly */, true /* clearBuffer */, imageData, &infoBuffer);
5397de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (err != OK) {
5407de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        env->DeleteLocalRef(byteBuffer);
5417de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        byteBuffer = NULL;
542d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return OK;
543d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
544d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
5457de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    jobject cropRect = NULL;
5467de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    int32_t left, top, right, bottom;
5477de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (buffer->meta()->findRect("crop-rect", &left, &top, &right, &bottom)) {
5487de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        ScopedLocalRef<jclass> rectClazz(
5497de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar                env, env->FindClass("android/graphics/Rect"));
5507de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        CHECK(rectClazz.get() != NULL);
5517de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5527de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        jmethodID rectConstructID = env->GetMethodID(
5537de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar                rectClazz.get(), "<init>", "(IIII)V");
5547de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5557de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        cropRect = env->NewObject(
5567de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar                rectClazz.get(), rectConstructID, left, top, right + 1, bottom + 1);
5577de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    }
5587de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5597de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    ScopedLocalRef<jclass> imageClazz(
5607de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            env, env->FindClass("android/media/MediaCodec$MediaImage"));
5617de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    CHECK(imageClazz.get() != NULL);
5627de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5637de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    jmethodID imageConstructID = env->GetMethodID(imageClazz.get(), "<init>",
5647de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;ZJIILandroid/graphics/Rect;)V");
5657de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5667de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    *buf = env->NewObject(imageClazz.get(), imageConstructID,
5677de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            byteBuffer, infoBuffer,
5687de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            (jboolean)!input /* readOnly */,
5697de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            (jlong)timestamp,
5707de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar            (jint)0 /* xOffset */, (jint)0 /* yOffset */, cropRect);
5717de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5727de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    // if MediaImage creation fails, return null
5737de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (env->ExceptionCheck()) {
5747de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        env->ExceptionDescribe();
5757de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        env->ExceptionClear();
5767de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        *buf = NULL;
5777de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    }
5787de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5797de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    if (cropRect != NULL) {
5807de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        env->DeleteLocalRef(cropRect);
5817de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar        cropRect = NULL;
5827de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    }
5837de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5847de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    env->DeleteLocalRef(byteBuffer);
5857de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    byteBuffer = NULL;
5867de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
5877de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    env->DeleteLocalRef(infoBuffer);
5887de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar    infoBuffer = NULL;
5897de28d34f1ca3a727a8325cf3304f2fe03d2ac59Lajos Molnar
590d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return OK;
591d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
592d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
593056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const {
594056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    AString name;
595056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
596056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    status_t err = mCodec->getName(&name);
597056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
598056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    if (err != OK) {
599056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        return err;
600056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    }
601056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
602056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    *nameStr = env->NewStringUTF(name.c_str());
603056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
604056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    return OK;
605056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo}
606056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
607226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatus_t JMediaCodec::setParameters(const sp<AMessage> &msg) {
608226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    return mCodec->setParameters(msg);
609226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber}
610226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
611b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) {
612b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    if (mSurfaceTextureClient != NULL) {
613b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode);
614b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    }
615b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber}
616b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
6175f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic jthrowable createCodecException(
6185f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) {
6195f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    ScopedLocalRef<jclass> clazz(
6205f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            env, env->FindClass("android/media/MediaCodec$CodecException"));
6215f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    CHECK(clazz.get() != NULL);
6225f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
623c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    const jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(IILjava/lang/String;)V");
6245f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    CHECK(ctor != NULL);
6255f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
6265f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    ScopedLocalRef<jstring> msgObj(
6275f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            env, env->NewStringUTF(msg != NULL ? msg : String8::format("Error %#x", err)));
6285f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
6295f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    // translate action code to Java equivalent
6305f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    switch (actionCode) {
6315f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    case ACTION_CODE_TRANSIENT:
6325f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        actionCode = gCodecActionCodes.codecActionTransient;
6335f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        break;
6345f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    case ACTION_CODE_RECOVERABLE:
6355f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        actionCode = gCodecActionCodes.codecActionRecoverable;
6365f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        break;
6375f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    default:
6385f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        actionCode = 0;  // everything else is fatal
6395f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        break;
6405f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    }
6415f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
642c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    /* translate OS errors to Java API CodecException errorCodes */
643c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    switch (err) {
644c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu        case NO_MEMORY:
645c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu            err = gCodecErrorCodes.errorInsufficientResource;
646c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu            break;
647c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu        case DEAD_OBJECT:
648c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu            err = gCodecErrorCodes.errorReclaimed;
649c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu            break;
650c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu        default:  /* Other error codes go out as is. */
651c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu            break;
652c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    }
653c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu
654c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    return (jthrowable)env->NewObject(clazz.get(), ctor, err, actionCode, msgObj.get());
6555f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung}
6565f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
6578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::handleCallback(const sp<AMessage> &msg) {
6588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    int32_t arg1, arg2 = 0;
6598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    jobject obj = NULL;
6608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    CHECK(msg->findInt32("callbackID", &arg1));
6618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    JNIEnv *env = AndroidRuntime::getJNIEnv();
6628d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
6638d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    switch (arg1) {
6648d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case MediaCodec::CB_INPUT_AVAILABLE:
665aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        {
6668d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt32("index", &arg2));
6678d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            break;
6688d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        }
6698d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
6708d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case MediaCodec::CB_OUTPUT_AVAILABLE:
6718d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        {
6728d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt32("index", &arg2));
6738d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
6748d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            size_t size, offset;
6758d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            int64_t timeUs;
6768d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            uint32_t flags;
6778d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findSize("size", &size));
6788d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findSize("offset", &offset));
6798d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt64("timeUs", &timeUs));
6808d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt32("flags", (int32_t *)&flags));
6818d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
6828d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            ScopedLocalRef<jclass> clazz(
6838d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                    env, env->FindClass("android/media/MediaCodec$BufferInfo"));
6848d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "()V");
6858d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V");
6868d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
6878d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            obj = env->NewObject(clazz.get(), ctor);
6888d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
6898d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            if (obj == NULL) {
6908d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                if (env->ExceptionCheck()) {
6918d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                    ALOGE("Could not create MediaCodec.BufferInfo.");
6928d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                    env->ExceptionClear();
6938d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                }
6948d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                jniThrowException(env, "java/lang/IllegalStateException", NULL);
6958d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                return;
696aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            }
697aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
6988d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            env->CallVoidMethod(obj, method, (jint)offset, (jint)size, timeUs, flags);
699aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            break;
700aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        }
701aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
7028d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case MediaCodec::CB_ERROR:
703aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        {
70494686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            int32_t err, actionCode;
70594686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            CHECK(msg->findInt32("err", &err));
7068d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt32("actionCode", &actionCode));
707aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
7085f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            // note that DRM errors could conceivably alias into a CodecException
7095f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            obj = (jobject)createCodecException(env, err, actionCode);
710aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
7118d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            if (obj == NULL) {
7128d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                if (env->ExceptionCheck()) {
71394686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang                    ALOGE("Could not create CodecException object.");
7148d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                    env->ExceptionClear();
7158d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                }
7168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                jniThrowException(env, "java/lang/IllegalStateException", NULL);
7178d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                return;
7188d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            }
719aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
720aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            break;
721aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        }
722aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
7238d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
724aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        {
7258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            sp<AMessage> format;
7268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findMessage("format", &format));
727aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
7288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            if (OK != ConvertMessageToMap(env, format, &obj)) {
7298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                jniThrowException(env, "java/lang/IllegalStateException", NULL);
7308d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                return;
7318d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            }
732aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
733aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            break;
734aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        }
735aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
736aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        default:
737aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            TRESPASS();
738aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    }
7398d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
7408d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    env->CallVoidMethod(
7418d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            mObject,
7428d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            gFields.postEventFromNativeID,
7438d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            EVENT_CALLBACK,
7448d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            arg1,
7458d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            arg2,
7468d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            obj);
7478d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
7488d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    env->DeleteLocalRef(obj);
749aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}
750aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
751d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarvoid JMediaCodec::handleFrameRenderedNotification(const sp<AMessage> &msg) {
752d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    int32_t arg1 = 0, arg2 = 0;
753d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    jobject obj = NULL;
754d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    JNIEnv *env = AndroidRuntime::getJNIEnv();
755d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
756d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    sp<AMessage> data;
757d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    CHECK(msg->findMessage("data", &data));
758d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
759d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    status_t err = ConvertMessageToMap(env, data, &obj);
760d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    if (err != OK) {
761d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        jniThrowException(env, "java/lang/IllegalStateException", NULL);
762d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        return;
763d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    }
764d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
765d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    env->CallVoidMethod(
766d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar            mObject, gFields.postEventFromNativeID,
767d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar            EVENT_FRAME_RENDERED, arg1, arg2, obj);
768d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
769d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    env->DeleteLocalRef(obj);
770d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar}
771d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
7728d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
7738d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    switch (msg->what()) {
7748d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case kWhatCallbackNotify:
7758d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        {
7768d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            handleCallback(msg);
7778d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            break;
7788d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        }
779d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        case kWhatFrameRendered:
780d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        {
781d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar            handleFrameRenderedNotification(msg);
782d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar            break;
783d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        }
7848d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        default:
7858d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            TRESPASS();
7868d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    }
787aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}
788aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
78988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}  // namespace android
79088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
79188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber////////////////////////////////////////////////////////////////////////////////
79288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
79388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android;
79488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
79588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec(
79688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) {
797075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    sp<JMediaCodec> old = (JMediaCodec *)env->GetLongField(thiz, gFields.context);
79888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec != NULL) {
79988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        codec->incStrong(thiz);
80088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
80188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (old != NULL) {
802128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        /* release MediaCodec and stop the looper now before decStrong.
803128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * otherwise JMediaCodec::~JMediaCodec() could be called from within
804128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * its message handler, doing release() from there will deadlock
805128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * (as MediaCodec::release() post synchronous message to the same looper)
806128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         */
807128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        old->release();
80888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        old->decStrong(thiz);
80988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
810075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    env->SetLongField(thiz, gFields.context, (jlong)codec.get());
81188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
81288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return old;
81388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
81488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
81588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) {
816075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (JMediaCodec *)env->GetLongField(thiz, gFields.context);
81788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
81888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
81988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) {
82088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    setMediaCodec(env, thiz, NULL);
82188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
82288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
8235f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hungstatic void throwCodecException(JNIEnv *env, status_t err, int32_t actionCode, const char *msg) {
8245f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    jthrowable exception = createCodecException(env, err, actionCode, msg);
8255f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    env->Throw(exception);
8265f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung}
8275f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
828bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) {
8298d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    ScopedLocalRef<jclass> clazz(
8308d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            env, env->FindClass("android/media/MediaCodec$CryptoException"));
8318d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(clazz.get() != NULL);
832bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
833bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    jmethodID constructID =
8348d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V");
835bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    CHECK(constructID != NULL);
836bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
837bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error");
838bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
8395f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    /* translate OS errors to Java API CryptoException errorCodes (which are positive) */
8403ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    switch (err) {
8413ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_NO_LICENSE:
8423ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            err = gCryptoErrorCodes.cryptoErrorNoKey;
8433ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
8443ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_LICENSE_EXPIRED:
8453ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            err = gCryptoErrorCodes.cryptoErrorKeyExpired;
8463ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
8473ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_RESOURCE_BUSY:
8483ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            err = gCryptoErrorCodes.cryptoErrorResourceBusy;
8493ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
850336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker        case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
851336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker            err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection;
852336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker            break;
85396a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker        case ERROR_DRM_SESSION_NOT_OPENED:
85496a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker            err = gCryptoErrorCodes.cryptoErrorSessionNotOpened;
85596a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker            break;
8565f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        default:  /* Other negative DRM error codes go out as is. */
8573ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
8583ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    }
8593ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
860bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    jthrowable exception =
8618d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj);
862bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
863bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    env->Throw(exception);
864bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber}
865bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
866bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary(
8675f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        JNIEnv *env, status_t err, int32_t actionCode = ACTION_CODE_FATAL,
8685f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        const char *msg = NULL) {
86988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    switch (err) {
87088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        case OK:
87188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return 0;
87288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
87388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        case -EAGAIN:
87488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return DEQUEUE_INFO_TRY_AGAIN_LATER;
87588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
87688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        case INFO_FORMAT_CHANGED:
87788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED;
87888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
87988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        case INFO_OUTPUT_BUFFERS_CHANGED:
88088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED;
88188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
8825f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        case INVALID_OPERATION:
8835f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            jniThrowException(env, "java/lang/IllegalStateException", msg);
8845f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            return 0;
8853ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
8865e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        case BAD_VALUE:
8875e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar            jniThrowException(env, "java/lang/IllegalArgumentException", msg);
8885e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar            return 0;
8895e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar
89088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        default:
8915f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            if (isCryptoError(err)) {
8925f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung                throwCryptoException(env, err, msg);
8935f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung                return 0;
8945f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            }
8955f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            throwCodecException(env, err, actionCode, msg);
8965f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            return 0;
89788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
89888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
89988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
900d8578577b02cf6360402eb8726e964d18b46434dLajos Molnarstatic void android_media_MediaCodec_native_enableOnFrameRenderedListener(
901d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        JNIEnv *env,
902d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        jobject thiz,
903d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        jboolean enabled) {
904d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
905d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
906d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    if (codec == NULL) {
907d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        throwExceptionAsNecessary(env, INVALID_OPERATION);
908d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar        return;
909d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    }
910d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
911d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    status_t err = codec->enableOnFrameRenderedListener(enabled);
912d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
913d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    throwExceptionAsNecessary(env, err);
914d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar}
915d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
9168d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatic void android_media_MediaCodec_native_setCallback(
9178d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        JNIEnv *env,
9188d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        jobject thiz,
9198d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        jobject cb) {
9208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
9218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
9228d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    if (codec == NULL) {
9235f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
9248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        return;
9258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    }
9268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
9278d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    status_t err = codec->setCallback(cb);
9288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
9298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    throwExceptionAsNecessary(env, err);
9308d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang}
9318d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
93288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure(
93388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env,
93488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject thiz,
93588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobjectArray keys, jobjectArray values,
93688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject jsurface,
9378240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jobject jcrypto,
93888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint flags) {
93988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
94088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
94188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
9425f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
94388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
94488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
94588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
94688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<AMessage> format;
94788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format);
94888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
94988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
95088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
95188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
95288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
95388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
954d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
95588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (jsurface != NULL) {
95664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
95788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        if (surface != NULL) {
95852800617946c456e78ed010c82d0ec4358368164Mathias Agopian            bufferProducer = surface->getIGraphicBufferProducer();
95988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        } else {
96088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            jniThrowException(
96188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                    env,
96288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                    "java/lang/IllegalArgumentException",
96388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                    "The surface has been released");
96488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return;
96588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        }
96688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
96788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
9688240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<ICrypto> crypto;
9698240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (jcrypto != NULL) {
9708240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        crypto = JCrypto::GetCrypto(env, jcrypto);
9718240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
9728240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
973d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    err = codec->configure(format, bufferProducer, crypto, flags);
97488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
97588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
97688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
97788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
9785e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnarstatic void android_media_MediaCodec_native_setSurface(
9795e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        JNIEnv *env,
9805e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        jobject thiz,
9815e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        jobject jsurface) {
9825e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
9835e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar
9845e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    if (codec == NULL) {
9855e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        throwExceptionAsNecessary(env, INVALID_OPERATION);
9865e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        return;
9875e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    }
9885e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar
9895e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    sp<IGraphicBufferProducer> bufferProducer;
9905e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    if (jsurface != NULL) {
9915e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
9925e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        if (surface != NULL) {
9935e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar            bufferProducer = surface->getIGraphicBufferProducer();
9945e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        } else {
9955e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar            jniThrowException(
9965e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar                    env,
9975e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar                    "java/lang/IllegalArgumentException",
9985e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar                    "The surface has been released");
9995e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar            return;
10005e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar        }
10015e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    }
10025e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar
10035e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    status_t err = codec->setSurface(bufferProducer);
10045e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    throwExceptionAsNecessary(env, err);
10055e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar}
10065e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar
10078034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangsp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface(
10088034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        JNIEnv* env, jobject object) {
10098034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    sp<PersistentSurface> persistentSurface;
10108034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10118034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jobject lock = env->GetObjectField(
10128034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            object, gPersistentSurfaceClassInfo.mLock);
10138034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (env->MonitorEnter(lock) == JNI_OK) {
10148034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        persistentSurface = reinterpret_cast<PersistentSurface *>(
10158034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                env->GetLongField(object,
10168034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                        gPersistentSurfaceClassInfo.mPersistentObject));
10178034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        env->MonitorExit(lock);
10188034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
10198034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    env->DeleteLocalRef(lock);
10208034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10218034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    return persistentSurface;
10228034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang}
10238034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10248034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic jobject android_media_MediaCodec_createPersistentInputSurface(
10258034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        JNIEnv* env, jclass /* clazz */) {
10268034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    ALOGV("android_media_MediaCodec_createPersistentInputSurface");
10278034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    sp<PersistentSurface> persistentSurface =
10288034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        MediaCodec::CreatePersistentInputSurface();
10298034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10308034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (persistentSurface == NULL) {
10318034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        return NULL;
10328034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
10338034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10348034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    sp<Surface> surface = new Surface(
10358034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            persistentSurface->getBufferProducer(), true);
10368034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (surface == NULL) {
10378034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        return NULL;
10388034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
10398034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10408034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jobject object = env->NewObject(
10418034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            gPersistentSurfaceClassInfo.clazz,
10428034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            gPersistentSurfaceClassInfo.ctor);
10438034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10448034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (object == NULL) {
10458034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        if (env->ExceptionCheck()) {
10468034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            ALOGE("Could not create PersistentSurface.");
10478034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            env->ExceptionClear();
10488034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        }
10498034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        return NULL;
10508034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
10518034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10528034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jobject lock = env->GetObjectField(
10538034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            object, gPersistentSurfaceClassInfo.mLock);
10548034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (env->MonitorEnter(lock) == JNI_OK) {
10558034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        env->CallVoidMethod(
10568034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                object,
10578034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                gPersistentSurfaceClassInfo.setNativeObjectLocked,
10588034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                (jlong)surface.get());
10598034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        env->SetLongField(
10608034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                object,
10618034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                gPersistentSurfaceClassInfo.mPersistentObject,
10628034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                (jlong)persistentSurface.get());
10638034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        env->MonitorExit(lock);
10648034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    } else {
10658034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        env->DeleteLocalRef(object);
10668034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        object = NULL;
10678034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
10688034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    env->DeleteLocalRef(lock);
10698034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10708034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (object != NULL) {
10718034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        surface->incStrong(&sRefBaseOwner);
10728034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        persistentSurface->incStrong(&sRefBaseOwner);
10738034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
10748034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10758034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    return object;
10768034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang}
10778034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10788034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhangstatic void android_media_MediaCodec_releasePersistentInputSurface(
10798034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        JNIEnv* env, jclass /* clazz */, jobject object) {
10808034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    sp<PersistentSurface> persistentSurface;
10818034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10828034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jobject lock = env->GetObjectField(
10838034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            object, gPersistentSurfaceClassInfo.mLock);
10848034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (env->MonitorEnter(lock) == JNI_OK) {
10858034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        persistentSurface = reinterpret_cast<PersistentSurface *>(
10868034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang            env->GetLongField(
10878034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                    object, gPersistentSurfaceClassInfo.mPersistentObject));
10888034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        env->SetLongField(
10898034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                object,
10908034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                gPersistentSurfaceClassInfo.mPersistentObject,
10918034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang                (jlong)0);
10928034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        env->MonitorExit(lock);
10938034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
10948034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    env->DeleteLocalRef(lock);
10958034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
10968034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (persistentSurface != NULL) {
10978034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        persistentSurface->decStrong(&sRefBaseOwner);
10988034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
10998034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    // no need to release surface as it will be released by Surface's jni
11008034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang}
11018034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
11029560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhangstatic void android_media_MediaCodec_setInputSurface(
11038034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        JNIEnv* env, jobject thiz, jobject object) {
11049560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang    ALOGV("android_media_MediaCodec_setInputSurface");
11058034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
11068034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
11078034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (codec == NULL) {
11088034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        throwExceptionAsNecessary(env, INVALID_OPERATION);
11098034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        return;
11108034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
11118034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
11128034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    sp<PersistentSurface> persistentSurface =
11138034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        android_media_MediaCodec_getPersistentInputSurface(env, object);
11148034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
11159560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang    status_t err = codec->setInputSurface(persistentSurface);
11168034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    if (err != NO_ERROR) {
11178034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang        throwExceptionAsNecessary(env, err);
11188034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    }
11198034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang}
11208034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
11212621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env,
11222621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        jobject thiz) {
11232621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    ALOGV("android_media_MediaCodec_createInputSurface");
11242621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
11252621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
11262621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    if (codec == NULL) {
11275f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
11282621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        return NULL;
11292621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    }
11302621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
11312621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    // Tell the MediaCodec that we want to use a Surface as input.
11322621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    sp<IGraphicBufferProducer> bufferProducer;
11332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    status_t err = codec->createInputSurface(&bufferProducer);
11342621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    if (err != NO_ERROR) {
11352621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        throwExceptionAsNecessary(env, err);
11362621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        return NULL;
11372621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    }
11382621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
11392621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    // Wrap the IGBP in a Java-language Surface.
11402621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    return android_view_Surface_createFromIGraphicBufferProducer(env,
11412621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden            bufferProducer);
11422621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden}
11432621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
114488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) {
114588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_start");
114688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
114788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
114888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
114988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
11505f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
115188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
115288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
115388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
115488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->start();
115588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
11565f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, "start failed");
115788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
115888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
115988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) {
116088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_stop");
116188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
116288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
116388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
116488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
11655f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
116688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
116788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
116888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
116988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->stop();
117088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
117188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
117288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
117388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
11741e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatic void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) {
11751e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    ALOGV("android_media_MediaCodec_reset");
11761e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
11771e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
11781e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
11791e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    if (codec == NULL) {
11805f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
11811e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        return;
11821e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    }
11831e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
11841e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    status_t err = codec->reset();
11851e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    if (err != OK) {
11861e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        // treat all errors as fatal for now, though resource not available
11871e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        // errors could be treated as transient.
11885f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        // we also should avoid sending INVALID_OPERATION here due to
11895f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        // the transitory nature of reset(), it should not inadvertently
11905f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        // trigger an IllegalStateException.
11915f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        err = UNKNOWN_ERROR;
11921e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    }
11931e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    throwExceptionAsNecessary(env, err);
11941e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar}
11951e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
119688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) {
119788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_flush");
119888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
119988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
120088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
120188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
12025f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
120388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
120488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
120588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
120688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->flush();
120788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
120888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
120988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
121088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
121188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer(
121288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env,
121388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject thiz,
121488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint index,
121588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint offset,
121688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint size,
121788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jlong timestampUs,
121888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint flags) {
121988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_queueInputBuffer");
122088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
122188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
122288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
122388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
12245f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
122588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
122688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
122788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1228bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    AString errorDetailMsg;
1229bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
123088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->queueInputBuffer(
1231bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber            index, offset, size, timestampUs, flags, &errorDetailMsg);
123288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1233bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    throwExceptionAsNecessary(
12345f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
123588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
123688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
12379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer(
12389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        JNIEnv *env,
12399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jobject thiz,
12409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint index,
12419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint offset,
124291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jobject cryptoInfoObj,
12439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jlong timestampUs,
12449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint flags) {
12459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    ALOGV("android_media_MediaCodec_queueSecureInputBuffer");
12469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
12479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
12489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
12499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (codec == NULL) {
12505f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
12519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        return;
12529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
12539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
125491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jint numSubSamples =
125591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID);
125691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
125791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jintArray numBytesOfClearDataObj =
125891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (jintArray)env->GetObjectField(
125991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber                cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID);
126091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
126191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jintArray numBytesOfEncryptedDataObj =
126291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (jintArray)env->GetObjectField(
126391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber                cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID);
126491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
126591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jbyteArray keyObj =
126691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID);
126791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
126891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jbyteArray ivObj =
126991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID);
127091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
127191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
127291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
12739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    status_t err = OK;
12749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
12759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    CryptoPlugin::SubSample *subSamples = NULL;
12769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    jbyte *key = NULL;
12779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    jbyte *iv = NULL;
12789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
12799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (numSubSamples <= 0) {
12809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = -EINVAL;
12819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    } else if (numBytesOfClearDataObj == NULL
12829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            && numBytesOfEncryptedDataObj == NULL) {
12839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = -EINVAL;
12849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    } else if (numBytesOfEncryptedDataObj != NULL
12859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) {
12869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = -ERANGE;
12879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    } else if (numBytesOfClearDataObj != NULL
12889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) {
12899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = -ERANGE;
12907ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar    // subSamples array may silently overflow if number of samples are too large.  Use
12917ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar    // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms
12925f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    } else if ( CC_UNLIKELY(numSubSamples >= (signed)(INT32_MAX / sizeof(*subSamples))) ) {
12937ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar        err = -EINVAL;
12949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    } else {
12959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jboolean isCopy;
12969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
12979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint *numBytesOfClearData =
12989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            (numBytesOfClearDataObj == NULL)
12999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                ? NULL
13009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy);
13019e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint *numBytesOfEncryptedData =
13039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            (numBytesOfEncryptedDataObj == NULL)
13049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                ? NULL
13059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);
13069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        subSamples = new CryptoPlugin::SubSample[numSubSamples];
13089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        for (jint i = 0; i < numSubSamples; ++i) {
13109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            subSamples[i].mNumBytesOfClearData =
13119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i];
13129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            subSamples[i].mNumBytesOfEncryptedData =
13149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                (numBytesOfEncryptedData == NULL)
13159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                    ? 0 : numBytesOfEncryptedData[i];
13169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
13179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        if (numBytesOfEncryptedData != NULL) {
13199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            env->ReleaseIntArrayElements(
13209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                    numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0);
13219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            numBytesOfEncryptedData = NULL;
13229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
13239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        if (numBytesOfClearData != NULL) {
13259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            env->ReleaseIntArrayElements(
13269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                    numBytesOfClearDataObj, numBytesOfClearData, 0);
13279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            numBytesOfClearData = NULL;
13289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
13299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
13309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (err == OK && keyObj != NULL) {
13329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        if (env->GetArrayLength(keyObj) != 16) {
13339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            err = -EINVAL;
13349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        } else {
13359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            jboolean isCopy;
13369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            key = env->GetByteArrayElements(keyObj, &isCopy);
13379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
13389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
13399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (err == OK && ivObj != NULL) {
13419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        if (env->GetArrayLength(ivObj) != 16) {
13429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            err = -EINVAL;
13439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        } else {
13449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            jboolean isCopy;
13459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            iv = env->GetByteArrayElements(ivObj, &isCopy);
13469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
13479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
13489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
1349bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    AString errorDetailMsg;
1350bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
13519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (err == OK) {
13529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = codec->queueSecureInputBuffer(
13539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                index, offset,
13549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                subSamples, numSubSamples,
13559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                (const uint8_t *)key, (const uint8_t *)iv,
13569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                (CryptoPlugin::Mode)mode,
1357bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber                timestampUs,
1358bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber                flags,
1359bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber                &errorDetailMsg);
13609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
13619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (iv != NULL) {
13639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        env->ReleaseByteArrayElements(ivObj, iv, 0);
13649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        iv = NULL;
13659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
13669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (key != NULL) {
13689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        env->ReleaseByteArrayElements(keyObj, key, 0);
13699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        key = NULL;
13709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
13719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
13729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    delete[] subSamples;
13739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    subSamples = NULL;
13749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
1375bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    throwExceptionAsNecessary(
13765f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung            env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
13779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber}
13789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
137988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer(
138088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jlong timeoutUs) {
138188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_dequeueInputBuffer");
138288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
138388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
138488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
138588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
13865f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
138788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
138888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
138988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
139088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t index;
139188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->dequeueInputBuffer(&index, timeoutUs);
139288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
139388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == OK) {
1394075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return (jint) index;
139588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
139688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
139788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return throwExceptionAsNecessary(env, err);
139888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
139988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
140088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer(
140188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) {
140288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_dequeueOutputBuffer");
140388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
140488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
140588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
140688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
14075f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
14080e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber        return 0;
140988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
141088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
141188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t index;
141288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->dequeueOutputBuffer(
141388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            env, bufferInfo, &index, timeoutUs);
141488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
141588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == OK) {
1416075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return (jint) index;
141788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
141888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
141988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return throwExceptionAsNecessary(env, err);
142088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
142188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
142288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer(
14237c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar        JNIEnv *env, jobject thiz,
14247c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar        jint index, jboolean render, jboolean updatePTS, jlong timestampNs) {
142588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease");
142688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
142788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
142888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
142988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
14305f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
143188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
143288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
143388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
14347c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar    status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs);
143588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
143688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
143788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
143888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
14392621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env,
14402621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        jobject thiz) {
14412621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    ALOGV("android_media_MediaCodec_signalEndOfInputStream");
14422621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
14432621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
14442621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    if (codec == NULL) {
14455f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
14462621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        return;
14472621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    }
14482621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
14492621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    status_t err = codec->signalEndOfInputStream();
14502621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
14512621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    throwExceptionAsNecessary(env, err);
14522621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden}
14532621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
1454d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getFormatNative(
1455d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, jobject thiz, jboolean input) {
1456d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ALOGV("android_media_MediaCodec_getFormatNative");
1457d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1458d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1459d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1460d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (codec == NULL) {
14615f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
1462d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return NULL;
1463d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1464d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1465d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject format;
1466d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err = codec->getFormat(env, input, &format);
1467d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1468d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err == OK) {
1469d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return format;
1470d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1471d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1472d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    throwExceptionAsNecessary(env, err);
1473d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1474d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return NULL;
1475d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
1476d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1477d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getOutputFormatForIndexNative(
1478d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, jobject thiz, jint index) {
1479d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ALOGV("android_media_MediaCodec_getOutputFormatForIndexNative");
148088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
148188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
148288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
148388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
14845f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
148588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return NULL;
148688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
148788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
148888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jobject format;
1489d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err = codec->getOutputFormat(env, index, &format);
149088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
149188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == OK) {
149288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return format;
149388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
149488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
149588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
149688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
149788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return NULL;
149888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
149988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
150088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers(
150188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jboolean input) {
150288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_getBuffers");
150388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
150488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
150588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
150688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
15075f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
150888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return NULL;
150988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
151088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
151188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jobjectArray buffers;
151288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->getBuffers(env, input, &buffers);
151388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
151488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == OK) {
151588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return buffers;
151688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
151788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1518cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    // if we're out of memory, an exception was already thrown
1519cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    if (err != NO_MEMORY) {
1520cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        throwExceptionAsNecessary(env, err);
1521cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    }
152288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
152388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return NULL;
152488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
152588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1526d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getBuffer(
1527d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, jobject thiz, jboolean input, jint index) {
1528d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ALOGV("android_media_MediaCodec_getBuffer");
1529d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1530d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1531d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1532d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (codec == NULL) {
15335f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
1534d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return NULL;
1535d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1536d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1537d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject buffer;
1538d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err = codec->getBuffer(env, input, index, &buffer);
1539d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1540d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err == OK) {
1541d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return buffer;
1542d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1543d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1544d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // if we're out of memory, an exception was already thrown
1545d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != NO_MEMORY) {
1546d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        throwExceptionAsNecessary(env, err);
1547d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1548d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1549d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return NULL;
1550d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
1551d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1552d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getImage(
1553d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, jobject thiz, jboolean input, jint index) {
1554d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ALOGV("android_media_MediaCodec_getImage");
1555d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1556d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1557d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1558d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (codec == NULL) {
15595f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
1560d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return NULL;
1561d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1562d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1563d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject image;
1564d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err = codec->getImage(env, input, index, &image);
1565d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1566d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err == OK) {
1567d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return image;
1568d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1569d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1570d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // if we're out of memory, an exception was already thrown
1571d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != NO_MEMORY) {
1572d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        throwExceptionAsNecessary(env, err);
1573d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1574d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1575d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return NULL;
1576d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
1577d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1578056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName(
1579056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        JNIEnv *env, jobject thiz) {
1580056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    ALOGV("android_media_MediaCodec_getName");
1581056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1582056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1583056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1584056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    if (codec == NULL) {
15855f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
1586056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        return NULL;
1587056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    }
1588056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1589056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    jstring name;
1590056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    status_t err = codec->getName(env, &name);
1591056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1592056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    if (err == OK) {
1593056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        return name;
1594056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    }
1595056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1596056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    throwExceptionAsNecessary(env, err);
1597056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1598056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    return NULL;
1599056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo}
1600056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1601226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatic void android_media_MediaCodec_setParameters(
1602226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber        JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) {
1603226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    ALOGV("android_media_MediaCodec_setParameters");
1604226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1605226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1606226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1607226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    if (codec == NULL) {
16085f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
1609226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber        return;
1610226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    }
1611226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1612226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    sp<AMessage> params;
1613226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, &params);
1614226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1615226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    if (err == OK) {
1616226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber        err = codec->setParameters(params);
1617226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    }
1618226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1619226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    throwExceptionAsNecessary(env, err);
1620226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber}
1621226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1622b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode(
1623b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        JNIEnv *env, jobject thiz, jint mode) {
1624b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1625b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
1626b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    if (codec == NULL) {
16275f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        throwExceptionAsNecessary(env, INVALID_OPERATION);
1628b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        return;
1629b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    }
1630b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
1631b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW
1632b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber            && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) {
1633b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        jniThrowException(env, "java/lang/InvalidArgumentException", NULL);
1634b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        return;
1635b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    }
1636b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
1637b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    codec->setVideoScalingMode(mode);
1638b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber}
1639b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
164088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) {
16418d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    ScopedLocalRef<jclass> clazz(
16428d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            env, env->FindClass("android/media/MediaCodec"));
16438d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(clazz.get() != NULL);
164488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1645075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
164688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(gFields.context != NULL);
164791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
1648aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    gFields.postEventFromNativeID =
1649aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        env->GetMethodID(
1650aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber                clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V");
1651aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
1652aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    CHECK(gFields.postEventFromNativeID != NULL);
1653aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
16548d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo"));
16558d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(clazz.get() != NULL);
165691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
165791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    gFields.cryptoInfoNumSubSamplesID =
16588d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetFieldID(clazz.get(), "numSubSamples", "I");
165991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoNumSubSamplesID != NULL);
166091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
166191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    gFields.cryptoInfoNumBytesOfClearDataID =
16628d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I");
166391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL);
166491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
166591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    gFields.cryptoInfoNumBytesOfEncryptedDataID =
16668d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I");
166791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL);
166891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
16698d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B");
167091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoKeyID != NULL);
167191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
16728d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B");
167391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoIVID != NULL);
167491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
16758d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I");
167691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoModeID != NULL);
16773ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
16788d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException"));
16798d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(clazz.get() != NULL);
16803ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
16813ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    jfieldID field;
16828d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I");
16833ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    CHECK(field != NULL);
16848d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gCryptoErrorCodes.cryptoErrorNoKey =
16858d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetStaticIntField(clazz.get(), field);
16863ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
16878d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I");
16883ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    CHECK(field != NULL);
16898d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gCryptoErrorCodes.cryptoErrorKeyExpired =
16908d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetStaticIntField(clazz.get(), field);
16913ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
16928d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I");
16933ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    CHECK(field != NULL);
16948d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gCryptoErrorCodes.cryptoErrorResourceBusy =
16958d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetStaticIntField(clazz.get(), field);
16965f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
1697336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker    field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_OUTPUT_PROTECTION", "I");
1698336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker    CHECK(field != NULL);
1699336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker    gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection =
1700336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker        env->GetStaticIntField(clazz.get(), field);
1701336d3eabc0d57fd2d1b8a9aa4ade7a0450cf183eJeff Tinker
170296a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker    field = env->GetStaticFieldID(clazz.get(), "ERROR_SESSION_NOT_OPENED", "I");
170396a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker    CHECK(field != NULL);
170496a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker    gCryptoErrorCodes.cryptoErrorSessionNotOpened =
170596a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker        env->GetStaticIntField(clazz.get(), field);
170696a2a957e42e04be817b60bb27199f3846f00fc9Jeff Tinker
17075f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    clazz.reset(env->FindClass("android/media/MediaCodec$CodecException"));
17085f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    CHECK(clazz.get() != NULL);
17095f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I");
17105f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    CHECK(field != NULL);
17115f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    gCodecActionCodes.codecActionTransient =
17125f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        env->GetStaticIntField(clazz.get(), field);
17135f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
17145f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    field = env->GetStaticFieldID(clazz.get(), "ACTION_RECOVERABLE", "I");
17155f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    CHECK(field != NULL);
17165f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    gCodecActionCodes.codecActionRecoverable =
17175f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        env->GetStaticIntField(clazz.get(), field);
17189e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu
1719c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_RESOURCE", "I");
17209e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu    CHECK(field != NULL);
1721c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    gCodecErrorCodes.errorInsufficientResource =
17229e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu        env->GetStaticIntField(clazz.get(), field);
17239e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu
1724c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    field = env->GetStaticFieldID(clazz.get(), "ERROR_RECLAIMED", "I");
17259e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu    CHECK(field != NULL);
1726c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    gCodecErrorCodes.errorReclaimed =
17279e9ec943ce7620bbfcadc2f8986a80ac58003e47Ronghua Wu        env->GetStaticIntField(clazz.get(), field);
17288034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
17298034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    clazz.reset(env->FindClass("android/view/Surface"));
17308034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    CHECK(clazz.get() != NULL);
17318034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
17328034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    field = env->GetFieldID(clazz.get(), "mLock", "Ljava/lang/Object;");
17338034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    CHECK(field != NULL);
17348034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    gPersistentSurfaceClassInfo.mLock = field;
17358034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
17368034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    jmethodID method = env->GetMethodID(clazz.get(), "setNativeObjectLocked", "(J)V");
17378034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    CHECK(method != NULL);
17388034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    gPersistentSurfaceClassInfo.setNativeObjectLocked = method;
17398034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
17408034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    clazz.reset(env->FindClass("android/media/MediaCodec$PersistentSurface"));
17418034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    CHECK(clazz.get() != NULL);
17428034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    gPersistentSurfaceClassInfo.clazz = (jclass)env->NewGlobalRef(clazz.get());
17438034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
17448034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    method = env->GetMethodID(clazz.get(), "<init>", "()V");
17458034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    CHECK(method != NULL);
17468034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    gPersistentSurfaceClassInfo.ctor = method;
17478034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
17488034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    field = env->GetFieldID(clazz.get(), "mPersistentObject", "J");
17498034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    CHECK(field != NULL);
17508034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    gPersistentSurfaceClassInfo.mPersistentObject = field;
175188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
175288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
175388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup(
175488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz,
175588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jstring name, jboolean nameIsType, jboolean encoder) {
175688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (name == NULL) {
17575f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        jniThrowException(env, "java/lang/NullPointerException", NULL);
175888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
175988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
176088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
176188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    const char *tmp = env->GetStringUTFChars(name, NULL);
176288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
176388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (tmp == NULL) {
176488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
176588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
176688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
176788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder);
176888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
17695f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    const status_t err = codec->initCheck();
17705f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    if (err == NAME_NOT_FOUND) {
17715f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        // fail and do not try again.
17725f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        jniThrowException(env, "java/lang/IllegalArgumentException",
17735f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung                String8::format("Failed to initialize %s, error %#x", tmp, err));
1774c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu        env->ReleaseStringUTFChars(name, tmp);
1775c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu        return;
1776c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu    } if (err == NO_MEMORY) {
1777c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu        throwCodecException(env, err, ACTION_CODE_TRANSIENT,
1778c53ad69bcc920cdbdb15685ddad1d864631bb4f7Ronghua Wu                String8::format("Failed to initialize %s, error %#x", tmp, err));
17795f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        env->ReleaseStringUTFChars(name, tmp);
17805f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        return;
17815f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    } else if (err != OK) {
17825f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        // believed possible to try again
17835f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        jniThrowException(env, "java/io/IOException",
17845f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung                String8::format("Failed to find matching codec %s, error %#x", tmp, err));
17855f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung        env->ReleaseStringUTFChars(name, tmp);
178688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
178788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
178888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
17895f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung    env->ReleaseStringUTFChars(name, tmp);
17905f9aa0bcea8be860fdf5a35476435616cb5f44f3Andy Hung
1791aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    codec->registerSelf();
1792aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
179388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    setMediaCodec(env,thiz, codec);
179488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
179588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
179688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize(
179788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
179888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    android_media_MediaCodec_release(env, thiz);
179988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
180088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
180188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = {
1802d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_release", "()V", (void *)android_media_MediaCodec_release },
180388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
18041e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    { "native_reset", "()V", (void *)android_media_MediaCodec_reset },
18051e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
18068034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    { "native_releasePersistentInputSurface",
18078034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang      "(Landroid/view/Surface;)V",
18088034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang       (void *)android_media_MediaCodec_releasePersistentInputSurface},
18098034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
18108034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang    { "native_createPersistentInputSurface",
18118034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang      "()Landroid/media/MediaCodec$PersistentSurface;",
18128034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang      (void *)android_media_MediaCodec_createPersistentInputSurface },
18138034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
18149560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang    { "native_setInputSurface", "(Landroid/view/Surface;)V",
18159560ddb48af0e2da7743452f8d9d6d9cd34d8438Chong Zhang      (void *)android_media_MediaCodec_setInputSurface },
18168034d60f6e044deafe48501dfbfe17c31284bc17Chong Zhang
1817d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar    { "native_enableOnFrameRenderedListener", "(Z)V",
1818d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar      (void *)android_media_MediaCodec_native_enableOnFrameRenderedListener },
1819d8578577b02cf6360402eb8726e964d18b46434dLajos Molnar
18208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    { "native_setCallback",
18218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang      "(Landroid/media/MediaCodec$Callback;)V",
18228d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang      (void *)android_media_MediaCodec_native_setCallback },
18238d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
182488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_configure",
18258240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber      "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;"
182607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      "Landroid/media/MediaCrypto;I)V",
182788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_native_configure },
182888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
18295e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar    { "native_setSurface",
18305e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar      "(Landroid/view/Surface;)V",
18315e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar      (void *)android_media_MediaCodec_native_setSurface },
18325e02ba977ede1e38c9f206057ec3f0f1e89ba943Lajos Molnar
18332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    { "createInputSurface", "()Landroid/view/Surface;",
18342621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden      (void *)android_media_MediaCodec_createInputSurface },
18352621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
1836d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_start", "()V", (void *)android_media_MediaCodec_start },
1837aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    { "native_stop", "()V", (void *)android_media_MediaCodec_stop },
1838d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_flush", "()V", (void *)android_media_MediaCodec_flush },
183988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1840d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_queueInputBuffer", "(IIIJI)V",
184188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_queueInputBuffer },
184288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1843d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V",
18449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber      (void *)android_media_MediaCodec_queueSecureInputBuffer },
18459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
1846d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_dequeueInputBuffer", "(J)I",
184788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_dequeueInputBuffer },
184888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1849d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I",
185088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_dequeueOutputBuffer },
185188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
18527c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar    { "releaseOutputBuffer", "(IZZJ)V",
185388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_releaseOutputBuffer },
185488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
18552621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    { "signalEndOfInputStream", "()V",
18562621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden      (void *)android_media_MediaCodec_signalEndOfInputStream },
18572621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
1858d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "getFormatNative", "(Z)Ljava/util/Map;",
1859d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar      (void *)android_media_MediaCodec_getFormatNative },
1860d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1861d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "getOutputFormatNative", "(I)Ljava/util/Map;",
1862d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar      (void *)android_media_MediaCodec_getOutputFormatForIndexNative },
186388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
186488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;",
186588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_getBuffers },
186688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1867d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "getBuffer", "(ZI)Ljava/nio/ByteBuffer;",
1868d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar      (void *)android_media_MediaCodec_getBuffer },
1869d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1870d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "getImage", "(ZI)Landroid/media/Image;",
1871d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar      (void *)android_media_MediaCodec_getImage },
1872d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1873056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    { "getName", "()Ljava/lang/String;",
1874056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo      (void *)android_media_MediaCodec_getName },
1875056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1876226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V",
1877226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber      (void *)android_media_MediaCodec_setParameters },
1878226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1879b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    { "setVideoScalingMode", "(I)V",
1880b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber      (void *)android_media_MediaCodec_setVideoScalingMode },
1881b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
188288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_init", "()V", (void *)android_media_MediaCodec_native_init },
188388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
188488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_setup", "(Ljava/lang/String;ZZ)V",
188588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_native_setup },
188688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
188788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_finalize", "()V",
188888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_native_finalize },
188988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
189088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
189188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) {
189288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return AndroidRuntime::registerNativeMethods(env,
189388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "android/media/MediaCodec", gMethods, NELEM(gMethods));
189488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
1895