android_media_MediaCodec.cpp revision 1e6e8018a4f914210b615bfca0f818fd13574228
188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber/*
288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Copyright 2012, The Android Open Source Project
388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * you may not use this file except in compliance with the License.
688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * You may obtain a copy of the License at
788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *
1088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * Unless required by applicable law or agreed to in writing, software
1188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * See the License for the specific language governing permissions and
1488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber * limitations under the License.
1588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber */
1688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//#define LOG_NDEBUG 0
1888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#define LOG_TAG "MediaCodec-JNI"
1988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <utils/Log.h>
2088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_MediaCodec.h"
2288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber#include "android_media_MediaCrypto.h"
2488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_media_Utils.h"
2588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/AndroidRuntime.h"
2688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "android_runtime/android_view_Surface.h"
2788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "jni.h"
2888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include "JNIHelp.h"
2988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
307ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar#include <cutils/compiler.h>
317ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar
328335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <gui/Surface.h>
338335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian
340e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber#include <media/ICrypto.h>
3588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaCodec.h>
3688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h>
3888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ALooper.h>
3988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h>
40bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber#include <media/stagefright/foundation/AString.h>
4188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h>
4288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
438d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber#include <nativehelper/ScopedLocalRef.h>
448d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber
45b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber#include <system/window.h>
46b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android {
4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
4988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!!
5088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum {
5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    DEQUEUE_INFO_TRY_AGAIN_LATER            = -1,
5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED      = -2,
5388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED     = -3,
5488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
5588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
56aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huberenum {
578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    EVENT_CALLBACK = 1,
588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    EVENT_SET_CALLBACK = 2,
59aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber};
60aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
613ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinkerstruct CryptoErrorCodes {
623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    jint cryptoErrorNoKey;
633ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    jint cryptoErrorKeyExpired;
643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    jint cryptoErrorResourceBusy;
653ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker} gCryptoErrorCodes;
663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
6788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t {
6888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jfieldID context;
69aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    jmethodID postEventFromNativeID;
7091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoNumSubSamplesID;
7191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoNumBytesOfClearDataID;
7291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoNumBytesOfEncryptedDataID;
7391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoKeyID;
7491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoIVID;
7591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jfieldID cryptoInfoModeID;
7688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
7788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields;
7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
8088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber////////////////////////////////////////////////////////////////////////////////
8188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
8288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec(
8388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz,
8488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        const char *name, bool nameIsType, bool encoder)
8588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    : mClass(NULL),
868d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang      mObject(NULL) {
8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jclass clazz = env->GetObjectClass(thiz);
8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(clazz != NULL);
8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mClass = (jclass)env->NewGlobalRef(clazz);
9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mObject = env->NewWeakGlobalRef(thiz);
9288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mLooper = new ALooper;
9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mLooper->setName("MediaCodec_looper");
9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mLooper->start(
9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            false,      // runOnCallingThread
98aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            true,       // canCallJava
998d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            PRIORITY_FOREGROUND);
10088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (nameIsType) {
10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        mCodec = MediaCodec::CreateByType(mLooper, name, encoder);
10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    } else {
10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        mCodec = MediaCodec::CreateByComponentName(mLooper, name);
10588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
10688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const {
10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mCodec != NULL ? OK : NO_INIT;
11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
112aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Hubervoid JMediaCodec::registerSelf() {
113aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    mLooper->registerHandler(this);
114aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}
115aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
116128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhangvoid JMediaCodec::release() {
117d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo    if (mCodec != NULL) {
118d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo        mCodec->release();
119d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo        mCodec.clear();
120d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo    }
12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
122128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang    if (mLooper != NULL) {
123128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        mLooper->unregisterHandler(id());
124128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        mLooper->stop();
125128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        mLooper.clear();
126128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang    }
127128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang}
128128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang
129128b012cc8c2369136bb8450bc91c81aebe18506Chong ZhangJMediaCodec::~JMediaCodec() {
130128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang    if (mCodec != NULL || mLooper != NULL) {
131128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        /* MediaCodec and looper should have been released explicitly already
132128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * in setMediaCodec() (see comments in setMediaCodec()).
133128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         *
134128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * Otherwise JMediaCodec::~JMediaCodec() might be called from within the
135128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * message handler, doing release() there risks deadlock as MediaCodec::
136128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * release() post synchronous message to the same looper.
137128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         *
138128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * Print a warning and try to proceed with releasing.
139128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         */
140128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()...");
141128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        release();
142128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec().");
143128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang    }
144128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang
14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
14688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
14788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->DeleteWeakGlobalRef(mObject);
14888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mObject = NULL;
14988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->DeleteGlobalRef(mClass);
15088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    mClass = NULL;
15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
15288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1538d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatus_t JMediaCodec::setCallback(jobject cb) {
1548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    if (cb != NULL) {
1558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        if (mCallbackNotification == NULL) {
1568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            mCallbackNotification = new AMessage(kWhatCallbackNotify, id());
1578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        }
1588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    } else {
1598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        mCallbackNotification.clear();
1608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    }
1618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
1628d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    return mCodec->setCallback(mCallbackNotification);
1638d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang}
1648d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
16588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure(
16688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        const sp<AMessage> &format,
167d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        const sp<IGraphicBufferProducer> &bufferProducer,
1688240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        const sp<ICrypto> &crypto,
16988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        int flags) {
17052800617946c456e78ed010c82d0ec4358368164Mathias Agopian    sp<Surface> client;
171d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    if (bufferProducer != NULL) {
172aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        mSurfaceTextureClient =
173aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            new Surface(bufferProducer, true /* controlledByApp */);
174b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    } else {
175b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        mSurfaceTextureClient.clear();
17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
177b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
178b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    return mCodec->configure(format, mSurfaceTextureClient, crypto, flags);
17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1812621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface(
1822621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
1832621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    return mCodec->createInputSurface(bufferProducer);
1842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden}
1852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() {
1878d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    return mCodec->start();
18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() {
191b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    mSurfaceTextureClient.clear();
192b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
1938d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    return mCodec->stop();
19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() {
19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return mCodec->flush();
19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2001e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatus_t JMediaCodec::reset() {
2011e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    return mCodec->reset();
2021e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar}
2031e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer(
20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        size_t index,
206bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        size_t offset, size_t size, int64_t timeUs, uint32_t flags,
207bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        AString *errorDetailMsg) {
208bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    return mCodec->queueInputBuffer(
209bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber            index, offset, size, timeUs, flags, errorDetailMsg);
21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
21188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer(
2139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        size_t index,
2149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        size_t offset,
2159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        const CryptoPlugin::SubSample *subSamples,
2169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        size_t numSubSamples,
2179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        const uint8_t key[16],
2189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        const uint8_t iv[16],
2199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        CryptoPlugin::Mode mode,
2209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        int64_t presentationTimeUs,
221bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        uint32_t flags,
222bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        AString *errorDetailMsg) {
2239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    return mCodec->queueSecureInputBuffer(
2249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            index, offset, subSamples, numSubSamples, key, iv, mode,
225bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber            presentationTimeUs, flags, errorDetailMsg);
2269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber}
2279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
22888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
2298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    return mCodec->dequeueInputBuffer(index, timeoutUs);
23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
23188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
23288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer(
23388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) {
23488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t size, offset;
23588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    int64_t timeUs;
23688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    uint32_t flags;
237aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    status_t err = mCodec->dequeueOutputBuffer(
238aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            index, &offset, &size, &timeUs, &flags, timeoutUs);
239aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
240aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    if (err != OK) {
24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
24288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2448d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    ScopedLocalRef<jclass> clazz(
2458d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            env, env->FindClass("android/media/MediaCodec$BufferInfo"));
24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2478d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V");
248fef85ef152ab176fd96dbe3047c8025136fa8560Ashok Bhat    env->CallVoidMethod(bufferInfo, method, (jint)offset, (jint)size, timeUs, flags);
24988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return OK;
25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2537c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnarstatus_t JMediaCodec::releaseOutputBuffer(
2547c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar        size_t index, bool render, bool updatePTS, int64_t timestampNs) {
2557c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar    if (updatePTS) {
2567c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar        return mCodec->renderOutputBufferAndRelease(index, timestampNs);
2577c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar    }
25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return render
25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        ? mCodec->renderOutputBufferAndRelease(index)
26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        : mCodec->releaseOutputBuffer(index);
26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
2632621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() {
2642621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    return mCodec->signalEndOfInputStream();
2652621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden}
2662621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
267d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getFormat(JNIEnv *env, bool input, jobject *format) const {
26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<AMessage> msg;
26988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err;
270d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    err = input ? mCodec->getInputFormat(&msg) : mCodec->getOutputFormat(&msg);
271d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != OK) {
272d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return err;
273d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
274d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
275d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return ConvertMessageToMap(env, msg, format);
276d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
277d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
278d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, size_t index, jobject *format) const {
279d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<AMessage> msg;
280d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err;
281d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if ((err = mCodec->getOutputFormat(index, &msg)) != OK) {
28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return ConvertMessageToMap(env, msg, format);
28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers(
28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, bool input, jobjectArray *bufArray) const {
29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    Vector<sp<ABuffer> > buffers;
29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err =
29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        input
29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            ? mCodec->getInputBuffers(&buffers)
29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            : mCodec->getOutputBuffers(&buffers);
29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return err;
29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3018d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    ScopedLocalRef<jclass> byteBufferClass(
3028d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            env, env->FindClass("java/nio/ByteBuffer"));
3038d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber
3048d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(byteBufferClass.get() != NULL);
3053dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber
3063dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber    jmethodID orderID = env->GetMethodID(
3078d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            byteBufferClass.get(),
3083dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber            "order",
3093dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber            "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
3103dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber
3113dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber    CHECK(orderID != NULL);
3123dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber
313d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jmethodID asReadOnlyBufferID = env->GetMethodID(
314d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteBufferClass.get(), "asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;");
315d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
316d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(asReadOnlyBufferID != NULL);
317d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
3188d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    ScopedLocalRef<jclass> byteOrderClass(
3198d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            env, env->FindClass("java/nio/ByteOrder"));
3208d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber
3218d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(byteOrderClass.get() != NULL);
3223dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber
3233dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber    jmethodID nativeOrderID = env->GetStaticMethodID(
3248d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;");
3253dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber    CHECK(nativeOrderID != NULL);
3263dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber
3273dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber    jobject nativeByteOrderObj =
3288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID);
3293dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber    CHECK(nativeByteOrderObj != NULL);
33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    *bufArray = (jobjectArray)env->NewObjectArray(
3328d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            buffers.size(), byteBufferClass.get(), NULL);
333cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    if (*bufArray == NULL) {
334cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        env->DeleteLocalRef(nativeByteOrderObj);
335cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        return NO_MEMORY;
336cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    }
33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    for (size_t i = 0; i < buffers.size(); ++i) {
33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        const sp<ABuffer> &buffer = buffers.itemAt(i);
34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
341cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        // if this is an ABuffer that doesn't actually hold any accessible memory,
342cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        // use a null ByteBuffer
343cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        if (buffer->base() == NULL) {
344cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen            continue;
345cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        }
34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject byteBuffer =
34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            env->NewDirectByteBuffer(
34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                buffer->base(),
34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                buffer->capacity());
350d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        if (!input && byteBuffer != NULL) {
351d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            jobject readOnlyBuffer = env->CallObjectMethod(
352d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar                    byteBuffer, asReadOnlyBufferID);
353d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            env->DeleteLocalRef(byteBuffer);
354d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteBuffer = readOnlyBuffer;
355d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        }
356cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        if (byteBuffer == NULL) {
357cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen            env->DeleteLocalRef(nativeByteOrderObj);
358cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen            return NO_MEMORY;
359cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        }
3603dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber        jobject me = env->CallObjectMethod(
3613dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber                byteBuffer, orderID, nativeByteOrderObj);
3623dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber        env->DeleteLocalRef(me);
3633dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber        me = NULL;
3643dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber
36588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        env->SetObjectArrayElement(
36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                *bufArray, i, byteBuffer);
36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        env->DeleteLocalRef(byteBuffer);
36988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        byteBuffer = NULL;
37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
37188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
3723dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber    env->DeleteLocalRef(nativeByteOrderObj);
3733dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber    nativeByteOrderObj = NULL;
3743dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber
37588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return OK;
37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
378d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getBuffer(
379d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, bool input, size_t index, jobject *buf) const {
380d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<ABuffer> buffer;
381d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
382d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err =
383d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        input
384d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            ? mCodec->getInputBuffer(index, &buffer)
385d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            : mCodec->getOutputBuffer(index, &buffer);
386d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
387d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != OK) {
388d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return err;
389d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
390d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
391d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ScopedLocalRef<jclass> byteBufferClass(
392d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            env, env->FindClass("java/nio/ByteBuffer"));
393d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
394d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(byteBufferClass.get() != NULL);
395d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
396d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jmethodID orderID = env->GetMethodID(
397d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteBufferClass.get(),
398d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            "order",
399d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
400d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
401d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(orderID != NULL);
402d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
403d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jmethodID asReadOnlyBufferID = env->GetMethodID(
404d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteBufferClass.get(), "asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;");
405d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
406d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(asReadOnlyBufferID != NULL);
407d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
408d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jmethodID positionID = env->GetMethodID(
409d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteBufferClass.get(), "position", "(I)Ljava/nio/Buffer;");
410d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
411d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(positionID != NULL);
412d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
413d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jmethodID limitID = env->GetMethodID(
414d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteBufferClass.get(), "limit", "(I)Ljava/nio/Buffer;");
415d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
416d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(limitID != NULL);
417d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
418d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ScopedLocalRef<jclass> byteOrderClass(
419d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            env, env->FindClass("java/nio/ByteOrder"));
420d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
421d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(byteOrderClass.get() != NULL);
422d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
423d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jmethodID nativeOrderID = env->GetStaticMethodID(
424d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;");
425d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(nativeOrderID != NULL);
426d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
427d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject nativeByteOrderObj =
428d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID);
429d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    CHECK(nativeByteOrderObj != NULL);
430d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
431d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // if this is an ABuffer that doesn't actually hold any accessible memory,
432d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // use a null ByteBuffer
433d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (buffer->base() == NULL) {
434d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        *buf = NULL;
435d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return OK;
436d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
437d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
438d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject byteBuffer =
439d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        env->NewDirectByteBuffer(
440d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            buffer->base(),
441d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            buffer->capacity());
442d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (!input && byteBuffer != NULL) {
443d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        jobject readOnlyBuffer = env->CallObjectMethod(
444d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar                byteBuffer, asReadOnlyBufferID);
445d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        env->DeleteLocalRef(byteBuffer);
446d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        byteBuffer = readOnlyBuffer;
447d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
448d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (byteBuffer == NULL) {
449d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        env->DeleteLocalRef(nativeByteOrderObj);
450d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return NO_MEMORY;
451d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
452d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject me = env->CallObjectMethod(
453d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteBuffer, orderID, nativeByteOrderObj);
454d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    env->DeleteLocalRef(me);
455d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    me = env->CallObjectMethod(
456d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            byteBuffer, limitID,
457d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            input ? buffer->capacity() : (buffer->offset() + buffer->size()));
458d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    env->DeleteLocalRef(me);
4597be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    me = env->CallObjectMethod(
4607be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar            byteBuffer, positionID,
4617be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar            input ? 0 : buffer->offset());
4627be24522ce2e1821ad45e7ada7c3f91e6814889aLajos Molnar    env->DeleteLocalRef(me);
463d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    me = NULL;
464d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
465d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    env->DeleteLocalRef(nativeByteOrderObj);
466d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    nativeByteOrderObj = NULL;
467d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
468d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    *buf = byteBuffer;
469d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return OK;
470d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
471d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
472d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatus_t JMediaCodec::getImage(
473d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, bool input, size_t index, jobject *buf) const {
474d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<ABuffer> buffer;
475d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
476d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err =
477d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        input
478d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            ? mCodec->getInputBuffer(index, &buffer)
479d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar            : mCodec->getOutputBuffer(index, &buffer);
480d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
481d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != OK) {
482d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return err;
483d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
484d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
485d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // if this is an ABuffer that doesn't actually hold any accessible memory,
486d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // use a null ByteBuffer
487d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    *buf = NULL;
488d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (buffer->base() == NULL) {
489d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return OK;
490d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
491d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
492d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // check if buffer is an image
493d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    AString imageData;
494d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (!buffer->meta()->findString("image-data", &imageData)) {
495d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return OK;
496d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
497d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
498d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return OK;
499d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
500d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
501d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
502056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const {
503056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    AString name;
504056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
505056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    status_t err = mCodec->getName(&name);
506056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
507056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    if (err != OK) {
508056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        return err;
509056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    }
510056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
511056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    *nameStr = env->NewStringUTF(name.c_str());
512056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
513056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    return OK;
514056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo}
515056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
516226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatus_t JMediaCodec::setParameters(const sp<AMessage> &msg) {
517226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    return mCodec->setParameters(msg);
518226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber}
519226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
520b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) {
521b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    if (mSurfaceTextureClient != NULL) {
522b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode);
523b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    }
524b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber}
525b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
5268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::handleCallback(const sp<AMessage> &msg) {
5278d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    int32_t arg1, arg2 = 0;
5288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    jobject obj = NULL;
5298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    CHECK(msg->findInt32("callbackID", &arg1));
5308d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    JNIEnv *env = AndroidRuntime::getJNIEnv();
5318d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
5328d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    switch (arg1) {
5338d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case MediaCodec::CB_INPUT_AVAILABLE:
534aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        {
5358d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt32("index", &arg2));
5368d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            break;
5378d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        }
5388d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
5398d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case MediaCodec::CB_OUTPUT_AVAILABLE:
5408d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        {
5418d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt32("index", &arg2));
5428d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
5438d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            size_t size, offset;
5448d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            int64_t timeUs;
5458d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            uint32_t flags;
5468d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findSize("size", &size));
5478d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findSize("offset", &offset));
5488d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt64("timeUs", &timeUs));
5498d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt32("flags", (int32_t *)&flags));
5508d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
5518d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            ScopedLocalRef<jclass> clazz(
5528d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                    env, env->FindClass("android/media/MediaCodec$BufferInfo"));
5538d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "()V");
5548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V");
5558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
5568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            obj = env->NewObject(clazz.get(), ctor);
5578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
5588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            if (obj == NULL) {
5598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                if (env->ExceptionCheck()) {
5608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                    ALOGE("Could not create MediaCodec.BufferInfo.");
5618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                    env->ExceptionClear();
5628d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                }
5638d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                jniThrowException(env, "java/lang/IllegalStateException", NULL);
5648d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                return;
565aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            }
566aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
5678d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            env->CallVoidMethod(obj, method, (jint)offset, (jint)size, timeUs, flags);
568aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            break;
569aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        }
570aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
5718d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case MediaCodec::CB_ERROR:
572aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        {
57394686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            int32_t err, actionCode;
57494686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            CHECK(msg->findInt32("err", &err));
5758d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findInt32("actionCode", &actionCode));
576aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
5778d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            // use Integer object to pass the action code
5788d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            ScopedLocalRef<jclass> clazz(
57994686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang                    env, env->FindClass("android/media/MediaCodec$CodecException"));
58094686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            jmethodID ctor = env->GetMethodID(clazz.get(), "<init>", "(IILjava/lang/String;)V");
58194686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang
58294686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            AString str;
58394686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            const char *detail = "Unknown error";
58494686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            if (msg->findString("detail", &str)) {
58594686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang                detail = str.c_str();
58694686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            }
58794686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            jstring msgObj = env->NewStringUTF(detail);
58894686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang
58994686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang            obj = env->NewObject(clazz.get(), ctor, err, actionCode, msgObj);
590aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
5918d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            if (obj == NULL) {
5928d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                if (env->ExceptionCheck()) {
59394686d13cacbec1ce7cf5fd0178fffb037d03cc1Chong Zhang                    ALOGE("Could not create CodecException object.");
5948d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                    env->ExceptionClear();
5958d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                }
5968d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                jniThrowException(env, "java/lang/IllegalStateException", NULL);
5978d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                return;
5988d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            }
599aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
600aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            break;
601aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        }
602aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
6038d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case MediaCodec::CB_OUTPUT_FORMAT_CHANGED:
604aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        {
6058d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            sp<AMessage> format;
6068d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            CHECK(msg->findMessage("format", &format));
607aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
6088d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            if (OK != ConvertMessageToMap(env, format, &obj)) {
6098d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                jniThrowException(env, "java/lang/IllegalStateException", NULL);
6108d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang                return;
6118d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            }
612aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
613aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            break;
614aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        }
615aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
616aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        default:
617aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber            TRESPASS();
618aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    }
6198d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
6208d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    env->CallVoidMethod(
6218d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            mObject,
6228d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            gFields.postEventFromNativeID,
6238d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            EVENT_CALLBACK,
6248d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            arg1,
6258d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            arg2,
6268d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            obj);
6278d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
6288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    env->DeleteLocalRef(obj);
629aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}
630aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
6318d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangvoid JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
6328d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    switch (msg->what()) {
6338d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        case kWhatCallbackNotify:
6348d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        {
6358d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            handleCallback(msg);
6368d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            break;
6378d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        }
6388d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        default:
6398d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang            TRESPASS();
6408d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    }
641aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber}
642aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
64388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}  // namespace android
64488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
64588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber////////////////////////////////////////////////////////////////////////////////
64688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
64788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android;
64888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
64988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec(
65088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) {
651075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    sp<JMediaCodec> old = (JMediaCodec *)env->GetLongField(thiz, gFields.context);
65288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec != NULL) {
65388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        codec->incStrong(thiz);
65488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
65588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (old != NULL) {
656128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        /* release MediaCodec and stop the looper now before decStrong.
657128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * otherwise JMediaCodec::~JMediaCodec() could be called from within
658128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * its message handler, doing release() from there will deadlock
659128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         * (as MediaCodec::release() post synchronous message to the same looper)
660128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang         */
661128b012cc8c2369136bb8450bc91c81aebe18506Chong Zhang        old->release();
66288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        old->decStrong(thiz);
66388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
664075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    env->SetLongField(thiz, gFields.context, (jlong)codec.get());
66588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
66688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return old;
66788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
66888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
66988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) {
670075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (JMediaCodec *)env->GetLongField(thiz, gFields.context);
67188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
67288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
67388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) {
67488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    setMediaCodec(env, thiz, NULL);
67588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
67688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
677bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) {
6788d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    ScopedLocalRef<jclass> clazz(
6798d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            env, env->FindClass("android/media/MediaCodec$CryptoException"));
6808d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(clazz.get() != NULL);
681bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
682bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    jmethodID constructID =
6838d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V");
684bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    CHECK(constructID != NULL);
685bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
686bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error");
687bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
6883ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    /* translate OS errors to Java API CryptoException errorCodes */
6893ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    switch (err) {
6903ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_NO_LICENSE:
6913ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            err = gCryptoErrorCodes.cryptoErrorNoKey;
6923ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
6933ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_LICENSE_EXPIRED:
6943ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            err = gCryptoErrorCodes.cryptoErrorKeyExpired;
6953ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
6963ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_RESOURCE_BUSY:
6973ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            err = gCryptoErrorCodes.cryptoErrorResourceBusy;
6983ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
6993ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        default:
7003ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
7013ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    }
7023ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
703bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    jthrowable exception =
7048d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj);
705bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
706bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    env->Throw(exception);
707bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber}
708bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
709bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary(
710bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        JNIEnv *env, status_t err, const char *msg = NULL) {
7113ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) {
712bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        // We'll throw our custom MediaCodec.CryptoException
713bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        throwCryptoException(env, err, msg);
714bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber        return 0;
715bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    }
716bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
71788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    switch (err) {
71888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        case OK:
71988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return 0;
72088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
72188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        case -EAGAIN:
72288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return DEQUEUE_INFO_TRY_AGAIN_LATER;
72388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
72488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        case INFO_FORMAT_CHANGED:
72588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED;
72688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
72788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        case INFO_OUTPUT_BUFFERS_CHANGED:
72888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED;
72988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
7303ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_NO_LICENSE:
7313ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_LICENSE_EXPIRED:
7323ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker        case ERROR_DRM_RESOURCE_BUSY:
7333ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            throwCryptoException(env, err, msg);
7343ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker            break;
7353ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
73688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        default:
73788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        {
738e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen            jniThrowException(env, "java/lang/IllegalStateException", msg);
73988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            break;
74088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        }
74188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
74288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
74388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return 0;
74488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
74588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
7468d5e556b2b76278000a506382fdf594c071e1fbdChong Zhangstatic void android_media_MediaCodec_native_setCallback(
7478d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        JNIEnv *env,
7488d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        jobject thiz,
7498d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        jobject cb) {
7508d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
7518d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
7528d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    if (codec == NULL) {
7538d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        jniThrowException(env, "java/lang/IllegalStateException", NULL);
7548d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang        return;
7558d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    }
7568d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
7578d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    status_t err = codec->setCallback(cb);
7588d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
7598d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    throwExceptionAsNecessary(env, err);
7608d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang}
7618d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
76288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure(
76388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env,
76488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject thiz,
76588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobjectArray keys, jobjectArray values,
76688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject jsurface,
7678240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        jobject jcrypto,
76888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint flags) {
76988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
77088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
77188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
77288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
77388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
77488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
77588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
77688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<AMessage> format;
77788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format);
77888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
77988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
78088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
78188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
78288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
78388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
784d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
78588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (jsurface != NULL) {
78664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
78788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        if (surface != NULL) {
78852800617946c456e78ed010c82d0ec4358368164Mathias Agopian            bufferProducer = surface->getIGraphicBufferProducer();
78988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        } else {
79088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            jniThrowException(
79188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                    env,
79288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                    "java/lang/IllegalArgumentException",
79388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                    "The surface has been released");
79488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            return;
79588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        }
79688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
79788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
7988240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    sp<ICrypto> crypto;
7998240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    if (jcrypto != NULL) {
8008240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber        crypto = JCrypto::GetCrypto(env, jcrypto);
8018240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber    }
8028240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber
803d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    err = codec->configure(format, bufferProducer, crypto, flags);
80488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
80588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
80688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
80788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
8082621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env,
8092621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        jobject thiz) {
8102621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    ALOGV("android_media_MediaCodec_createInputSurface");
8112621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
8122621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
8132621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    if (codec == NULL) {
8142621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        jniThrowException(env, "java/lang/IllegalStateException", NULL);
8152621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        return NULL;
8162621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    }
8172621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
8182621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    // Tell the MediaCodec that we want to use a Surface as input.
8192621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    sp<IGraphicBufferProducer> bufferProducer;
8202621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    status_t err = codec->createInputSurface(&bufferProducer);
8212621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    if (err != NO_ERROR) {
8222621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        throwExceptionAsNecessary(env, err);
8232621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        return NULL;
8242621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    }
8252621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
8262621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    // Wrap the IGBP in a Java-language Surface.
8272621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    return android_view_Surface_createFromIGraphicBufferProducer(env,
8282621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden            bufferProducer);
8292621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden}
8302621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
83188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) {
83288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_start");
83388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
83488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
83588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
83688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
837e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen        jniThrowException(env, "java/lang/IllegalStateException", "no codec found");
83888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
83988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
84088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
84188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->start();
84288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
843e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen    throwExceptionAsNecessary(env, err, "start failed");
84488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
84588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
84688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) {
84788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_stop");
84888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
84988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
85088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
85188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
85288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
85388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
85488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
85588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
85688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->stop();
85788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
85888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
85988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
86088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
8611e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnarstatic void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) {
8621e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    ALOGV("android_media_MediaCodec_reset");
8631e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
8641e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
8651e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
8661e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    if (codec == NULL) {
8671e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        // should never be here
8681e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        jniThrowException(env, "java/lang/IllegalStateException", NULL);
8691e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        return;
8701e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    }
8711e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
8721e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    status_t err = codec->reset();
8731e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    if (err != OK) {
8741e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        // treat all errors as fatal for now, though resource not available
8751e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        // errors could be treated as transient.
8761e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar        err = 0x80000000;
8771e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    }
8781e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    throwExceptionAsNecessary(env, err);
8791e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar}
8801e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
88188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) {
88288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_flush");
88388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
88488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
88588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
88688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
88788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
88888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
88988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
89088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
89188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->flush();
89288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
89388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
89488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
89588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
89688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer(
89788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env,
89888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jobject thiz,
89988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint index,
90088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint offset,
90188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint size,
90288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jlong timestampUs,
90388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jint flags) {
90488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_queueInputBuffer");
90588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
90688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
90788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
90888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
90988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
91088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
91188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
91288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
913bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    AString errorDetailMsg;
914bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
91588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->queueInputBuffer(
916bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber            index, offset, size, timestampUs, flags, &errorDetailMsg);
91788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
918bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    throwExceptionAsNecessary(
919bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber            env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
92088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
92188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
9229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer(
9239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        JNIEnv *env,
9249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jobject thiz,
9259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint index,
9269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint offset,
92791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        jobject cryptoInfoObj,
9289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jlong timestampUs,
9299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint flags) {
9309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    ALOGV("android_media_MediaCodec_queueSecureInputBuffer");
9319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
9339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (codec == NULL) {
9359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
9369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        return;
9379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
9389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
93991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jint numSubSamples =
94091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID);
94191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
94291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jintArray numBytesOfClearDataObj =
94391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (jintArray)env->GetObjectField(
94491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber                cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID);
94591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
94691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jintArray numBytesOfEncryptedDataObj =
94791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (jintArray)env->GetObjectField(
94891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber                cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID);
94991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
95091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jbyteArray keyObj =
95191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID);
95291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
95391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jbyteArray ivObj =
95491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber        (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID);
95591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
95691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
95791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
9589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    status_t err = OK;
9599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    CryptoPlugin::SubSample *subSamples = NULL;
9619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    jbyte *key = NULL;
9629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    jbyte *iv = NULL;
9639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (numSubSamples <= 0) {
9659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = -EINVAL;
9669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    } else if (numBytesOfClearDataObj == NULL
9679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            && numBytesOfEncryptedDataObj == NULL) {
9689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = -EINVAL;
9699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    } else if (numBytesOfEncryptedDataObj != NULL
9709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) {
9719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = -ERANGE;
9729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    } else if (numBytesOfClearDataObj != NULL
9739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) {
9749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = -ERANGE;
9757ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar    // subSamples array may silently overflow if number of samples are too large.  Use
9767ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar    // INT32_MAX as maximum allocation size may be less than SIZE_MAX on some platforms
9777ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar    } else if ( CC_UNLIKELY(numSubSamples >= INT32_MAX / sizeof(*subSamples)) ) {
9787ac4f560dfe754eb4fe0d279fa03c1d9b3a7a5afLajos Molnar        err = -EINVAL;
9799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    } else {
9809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jboolean isCopy;
9819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint *numBytesOfClearData =
9839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            (numBytesOfClearDataObj == NULL)
9849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                ? NULL
9859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy);
9869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        jint *numBytesOfEncryptedData =
9889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            (numBytesOfEncryptedDataObj == NULL)
9899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                ? NULL
9909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy);
9919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        subSamples = new CryptoPlugin::SubSample[numSubSamples];
9939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        for (jint i = 0; i < numSubSamples; ++i) {
9959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            subSamples[i].mNumBytesOfClearData =
9969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i];
9979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
9989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            subSamples[i].mNumBytesOfEncryptedData =
9999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                (numBytesOfEncryptedData == NULL)
10009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                    ? 0 : numBytesOfEncryptedData[i];
10019e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
10029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
10039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        if (numBytesOfEncryptedData != NULL) {
10049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            env->ReleaseIntArrayElements(
10059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                    numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0);
10069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            numBytesOfEncryptedData = NULL;
10079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
10089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
10099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        if (numBytesOfClearData != NULL) {
10109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            env->ReleaseIntArrayElements(
10119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                    numBytesOfClearDataObj, numBytesOfClearData, 0);
10129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            numBytesOfClearData = NULL;
10139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
10149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
10159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
10169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (err == OK && keyObj != NULL) {
10179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        if (env->GetArrayLength(keyObj) != 16) {
10189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            err = -EINVAL;
10199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        } else {
10209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            jboolean isCopy;
10219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            key = env->GetByteArrayElements(keyObj, &isCopy);
10229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
10239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
10249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
10259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (err == OK && ivObj != NULL) {
10269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        if (env->GetArrayLength(ivObj) != 16) {
10279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            err = -EINVAL;
10289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        } else {
10299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            jboolean isCopy;
10309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber            iv = env->GetByteArrayElements(ivObj, &isCopy);
10319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        }
10329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
10339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
1034bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    AString errorDetailMsg;
1035bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber
10369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (err == OK) {
10379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        err = codec->queueSecureInputBuffer(
10389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                index, offset,
10399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                subSamples, numSubSamples,
10409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                (const uint8_t *)key, (const uint8_t *)iv,
10419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber                (CryptoPlugin::Mode)mode,
1042bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber                timestampUs,
1043bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber                flags,
1044bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber                &errorDetailMsg);
10459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
10469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
10479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (iv != NULL) {
10489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        env->ReleaseByteArrayElements(ivObj, iv, 0);
10499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        iv = NULL;
10509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
10519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
10529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    if (key != NULL) {
10539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        env->ReleaseByteArrayElements(keyObj, key, 0);
10549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber        key = NULL;
10559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    }
10569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
10579e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    delete[] subSamples;
10589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber    subSamples = NULL;
10599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
1060bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber    throwExceptionAsNecessary(
1061bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber            env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
10629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber}
10639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
106488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer(
106588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jlong timeoutUs) {
106688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_dequeueInputBuffer");
106788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
106888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
106988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
107088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
107188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
107288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return -1;
107388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
107488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
107588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t index;
107688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->dequeueInputBuffer(&index, timeoutUs);
107788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
107888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == OK) {
1079075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return (jint) index;
108088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
108188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
108288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return throwExceptionAsNecessary(env, err);
108388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
108488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
108588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer(
108688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) {
108788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_dequeueOutputBuffer");
108888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
108988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
109088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
109188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
109288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
10930e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber        return 0;
109488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
109588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
109688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    size_t index;
109788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->dequeueOutputBuffer(
109888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber            env, bufferInfo, &index, timeoutUs);
109988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
110088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == OK) {
1101075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat        return (jint) index;
110288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
110388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
110488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return throwExceptionAsNecessary(env, err);
110588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
110688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
110788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer(
11087c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar        JNIEnv *env, jobject thiz,
11097c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar        jint index, jboolean render, jboolean updatePTS, jlong timestampNs) {
111088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease");
111188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
111288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
111388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
111488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
111588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
111688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
111788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
111888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
11197c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar    status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs);
112088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
112188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
112288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
112388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
11242621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env,
11252621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        jobject thiz) {
11262621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    ALOGV("android_media_MediaCodec_signalEndOfInputStream");
11272621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
11282621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
11292621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    if (codec == NULL) {
11302621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        jniThrowException(env, "java/lang/IllegalStateException", NULL);
11312621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden        return;
11322621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    }
11332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
11342621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    status_t err = codec->signalEndOfInputStream();
11352621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
11362621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    throwExceptionAsNecessary(env, err);
11372621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden}
11382621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
1139d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getFormatNative(
1140d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, jobject thiz, jboolean input) {
1141d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ALOGV("android_media_MediaCodec_getFormatNative");
1142d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1143d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1144d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1145d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (codec == NULL) {
1146d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        jniThrowException(env, "java/lang/IllegalStateException", NULL);
1147d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return NULL;
1148d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1149d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1150d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject format;
1151d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err = codec->getFormat(env, input, &format);
1152d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1153d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err == OK) {
1154d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return format;
1155d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1156d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1157d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    throwExceptionAsNecessary(env, err);
1158d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1159d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return NULL;
1160d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
1161d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1162d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getOutputFormatForIndexNative(
1163d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, jobject thiz, jint index) {
1164d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ALOGV("android_media_MediaCodec_getOutputFormatForIndexNative");
116588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
116688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
116788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
116888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
116988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
117088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return NULL;
117188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
117288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
117388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jobject format;
1174d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err = codec->getOutputFormat(env, index, &format);
117588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
117688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == OK) {
117788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return format;
117888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
117988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
118088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    throwExceptionAsNecessary(env, err);
118188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
118288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return NULL;
118388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
118488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
118588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers(
118688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz, jboolean input) {
118788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    ALOGV("android_media_MediaCodec_getBuffers");
118888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
118988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
119088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
119188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (codec == NULL) {
119288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
119388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return NULL;
119488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
119588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
119688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    jobjectArray buffers;
119788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->getBuffers(env, input, &buffers);
119888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
119988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err == OK) {
120088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return buffers;
120188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
120288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1203cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    // if we're out of memory, an exception was already thrown
1204cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    if (err != NO_MEMORY) {
1205cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen        throwExceptionAsNecessary(env, err);
1206cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen    }
120788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
120888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return NULL;
120988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
121088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1211d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getBuffer(
1212d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, jobject thiz, jboolean input, jint index) {
1213d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ALOGV("android_media_MediaCodec_getBuffer");
1214d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1215d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1216d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1217d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (codec == NULL) {
1218d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        jniThrowException(env, "java/lang/IllegalStateException", NULL);
1219d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return NULL;
1220d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1221d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1222d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject buffer;
1223d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err = codec->getBuffer(env, input, index, &buffer);
1224d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1225d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err == OK) {
1226d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return buffer;
1227d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1228d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1229d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // if we're out of memory, an exception was already thrown
1230d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != NO_MEMORY) {
1231d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        throwExceptionAsNecessary(env, err);
1232d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1233d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1234d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return NULL;
1235d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
1236d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1237d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnarstatic jobject android_media_MediaCodec_getImage(
1238d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        JNIEnv *env, jobject thiz, jboolean input, jint index) {
1239d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    ALOGV("android_media_MediaCodec_getImage");
1240d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1241d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1242d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1243d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (codec == NULL) {
1244d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        jniThrowException(env, "java/lang/IllegalStateException", NULL);
1245d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return NULL;
1246d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1247d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1248d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    jobject image;
1249d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    status_t err = codec->getImage(env, input, index, &image);
1250d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1251d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err == OK) {
1252d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        return image;
1253d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1254d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1255d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    // if we're out of memory, an exception was already thrown
1256d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    if (err != NO_MEMORY) {
1257d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar        throwExceptionAsNecessary(env, err);
1258d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    }
1259d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1260d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    return NULL;
1261d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar}
1262d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1263056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName(
1264056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        JNIEnv *env, jobject thiz) {
1265056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    ALOGV("android_media_MediaCodec_getName");
1266056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1267056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1268056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1269056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    if (codec == NULL) {
1270056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        jniThrowException(env, "java/lang/IllegalStateException", NULL);
1271056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        return NULL;
1272056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    }
1273056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1274056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    jstring name;
1275056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    status_t err = codec->getName(env, &name);
1276056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1277056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    if (err == OK) {
1278056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo        return name;
1279056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    }
1280056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1281056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    throwExceptionAsNecessary(env, err);
1282056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1283056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    return NULL;
1284056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo}
1285056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1286226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatic void android_media_MediaCodec_setParameters(
1287226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber        JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) {
1288226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    ALOGV("android_media_MediaCodec_setParameters");
1289226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1290226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1291226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1292226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    if (codec == NULL) {
1293226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
1294226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber        return;
1295226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    }
1296226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1297226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    sp<AMessage> params;
1298226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, &params);
1299226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1300226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    if (err == OK) {
1301226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber        err = codec->setParameters(params);
1302226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    }
1303226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1304226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    throwExceptionAsNecessary(env, err);
1305226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber}
1306226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1307b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode(
1308b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        JNIEnv *env, jobject thiz, jint mode) {
1309b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
1310b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
1311b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    if (codec == NULL) {
1312b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        jniThrowException(env, "java/lang/IllegalStateException", NULL);
1313b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        return;
1314b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    }
1315b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
1316b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW
1317b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber            && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) {
1318b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        jniThrowException(env, "java/lang/InvalidArgumentException", NULL);
1319b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber        return;
1320b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    }
1321b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
1322b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    codec->setVideoScalingMode(mode);
1323b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber}
1324b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
132588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) {
13268d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    ScopedLocalRef<jclass> clazz(
13278d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber            env, env->FindClass("android/media/MediaCodec"));
13288d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(clazz.get() != NULL);
132988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1330075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
133188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    CHECK(gFields.context != NULL);
133291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
1333aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    gFields.postEventFromNativeID =
1334aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber        env->GetMethodID(
1335aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber                clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V");
1336aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
1337aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    CHECK(gFields.postEventFromNativeID != NULL);
1338aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
13398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo"));
13408d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(clazz.get() != NULL);
134191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
134291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    gFields.cryptoInfoNumSubSamplesID =
13438d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetFieldID(clazz.get(), "numSubSamples", "I");
134491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoNumSubSamplesID != NULL);
134591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
134691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    gFields.cryptoInfoNumBytesOfClearDataID =
13478d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I");
134891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL);
134991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
135091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    gFields.cryptoInfoNumBytesOfEncryptedDataID =
13518d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I");
135291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL);
135391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
13548d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B");
135591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoKeyID != NULL);
135691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
13578d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B");
135891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoIVID != NULL);
135991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber
13608d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I");
136191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber    CHECK(gFields.cryptoInfoModeID != NULL);
13623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
13638d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException"));
13648d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    CHECK(clazz.get() != NULL);
13653ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
13663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    jfieldID field;
13678d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I");
13683ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    CHECK(field != NULL);
13698d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gCryptoErrorCodes.cryptoErrorNoKey =
13708d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetStaticIntField(clazz.get(), field);
13713ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
13728d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I");
13733ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    CHECK(field != NULL);
13748d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gCryptoErrorCodes.cryptoErrorKeyExpired =
13758d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetStaticIntField(clazz.get(), field);
13763ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker
13778d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I");
13783ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker    CHECK(field != NULL);
13798d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber    gCryptoErrorCodes.cryptoErrorResourceBusy =
13808d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber        env->GetStaticIntField(clazz.get(), field);
138188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
138288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
138388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup(
138488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz,
138588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jstring name, jboolean nameIsType, jboolean encoder) {
138688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (name == NULL) {
138788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
138888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
138988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
139088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
139188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    const char *tmp = env->GetStringUTFChars(name, NULL);
139288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
139388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (tmp == NULL) {
139488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
139588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
139688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
139788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder);
139888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
139988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    status_t err = codec->initCheck();
140088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
140188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    env->ReleaseStringUTFChars(name, tmp);
140288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    tmp = NULL;
140388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
140488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    if (err != OK) {
140588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        jniThrowException(
140688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                env,
140788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "java/io/IOException",
140888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "Failed to allocate component instance");
140988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        return;
141088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    }
141188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1412aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    codec->registerSelf();
1413aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber
141488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    setMediaCodec(env,thiz, codec);
141588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
141688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
141788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize(
141888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber        JNIEnv *env, jobject thiz) {
141988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    android_media_MediaCodec_release(env, thiz);
142088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
142188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
142288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = {
1423d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_release", "()V", (void *)android_media_MediaCodec_release },
142488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
14251e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar    { "native_reset", "()V", (void *)android_media_MediaCodec_reset },
14261e6e8018a4f914210b615bfca0f818fd13574228Lajos Molnar
14278d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang    { "native_setCallback",
14288d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang      "(Landroid/media/MediaCodec$Callback;)V",
14298d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang      (void *)android_media_MediaCodec_native_setCallback },
14308d5e556b2b76278000a506382fdf594c071e1fbdChong Zhang
143188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_configure",
14328240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber      "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;"
143307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber      "Landroid/media/MediaCrypto;I)V",
143488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_native_configure },
143588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
14362621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    { "createInputSurface", "()Landroid/view/Surface;",
14372621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden      (void *)android_media_MediaCodec_createInputSurface },
14382621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
1439d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_start", "()V", (void *)android_media_MediaCodec_start },
1440aba671392d6606e35726c350a28d0c9b36ebfe16Andreas Huber    { "native_stop", "()V", (void *)android_media_MediaCodec_stop },
1441d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_flush", "()V", (void *)android_media_MediaCodec_flush },
144288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1443d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_queueInputBuffer", "(IIIJI)V",
144488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_queueInputBuffer },
144588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1446d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V",
14479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber      (void *)android_media_MediaCodec_queueSecureInputBuffer },
14489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber
1449d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_dequeueInputBuffer", "(J)I",
145088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_dequeueInputBuffer },
145188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1452d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "native_dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I",
145388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_dequeueOutputBuffer },
145488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
14557c513b6bef8ed4dfc28e0af6c8594563fdb9f436Lajos Molnar    { "releaseOutputBuffer", "(IZZJ)V",
145688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_releaseOutputBuffer },
145788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
14582621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden    { "signalEndOfInputStream", "()V",
14592621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden      (void *)android_media_MediaCodec_signalEndOfInputStream },
14602621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden
1461d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "getFormatNative", "(Z)Ljava/util/Map;",
1462d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar      (void *)android_media_MediaCodec_getFormatNative },
1463d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1464d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "getOutputFormatNative", "(I)Ljava/util/Map;",
1465d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar      (void *)android_media_MediaCodec_getOutputFormatForIndexNative },
146688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
146788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;",
146888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_getBuffers },
146988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
1470d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "getBuffer", "(ZI)Ljava/nio/ByteBuffer;",
1471d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar      (void *)android_media_MediaCodec_getBuffer },
1472d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1473d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar    { "getImage", "(ZI)Landroid/media/Image;",
1474d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar      (void *)android_media_MediaCodec_getImage },
1475d4023114e8cf7ec7db4d07958a303699b658f2c0Lajos Molnar
1476056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo    { "getName", "()Ljava/lang/String;",
1477056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo      (void *)android_media_MediaCodec_getName },
1478056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo
1479226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber    { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V",
1480226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber      (void *)android_media_MediaCodec_setParameters },
1481226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber
1482b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber    { "setVideoScalingMode", "(I)V",
1483b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber      (void *)android_media_MediaCodec_setVideoScalingMode },
1484b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber
148588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_init", "()V", (void *)android_media_MediaCodec_native_init },
148688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
148788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_setup", "(Ljava/lang/String;ZZ)V",
148888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_native_setup },
148988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
149088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    { "native_finalize", "()V",
149188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber      (void *)android_media_MediaCodec_native_finalize },
149288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber};
149388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber
149488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) {
149588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber    return AndroidRuntime::registerNativeMethods(env,
149688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber                "android/media/MediaCodec", gMethods, NELEM(gMethods));
149788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}
1498