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, ¶ms); 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