android_media_MediaCodec.cpp revision 075e9a19ce645752f8282bc19c91b25978a7dc52
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 308335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <gui/Surface.h> 318335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian 320e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber#include <media/ICrypto.h> 3388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaCodec.h> 3488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 3588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 3688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ALooper.h> 3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 38bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber#include <media/stagefright/foundation/AString.h> 3988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h> 4088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 418d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber#include <nativehelper/ScopedLocalRef.h> 428d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 43b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber#include <system/window.h> 44b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 4588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android { 4688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!! 4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum { 4988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_TRY_AGAIN_LATER = -1, 5088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED = -2, 5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, 5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 5388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 543ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinkerstruct CryptoErrorCodes { 553ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorNoKey; 563ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorKeyExpired; 573ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorResourceBusy; 583ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker} gCryptoErrorCodes; 593ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 6088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 6188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 6291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumSubSamplesID; 6391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfClearDataID; 6491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfEncryptedDataID; 6591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoKeyID; 6691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoIVID; 6791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoModeID; 6888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 6988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 7188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 7388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 7588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 7688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 7788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject(NULL) { 7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 8088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 8188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 8388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 8488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 8688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // canCallJava 918d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber PRIORITY_FOREGROUND); 9288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByType(mLooper, name, encoder); 9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByComponentName(mLooper, name); 9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 9988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec != NULL ? OK : NO_INIT; 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::~JMediaCodec() { 105d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo if (mCodec != NULL) { 106d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec->release(); 107d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec.clear(); 108d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo } 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 120d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden const sp<IGraphicBufferProducer> &bufferProducer, 1218240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const sp<ICrypto> &crypto, 12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 12352800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> client; 124d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden if (bufferProducer != NULL) { 125fd2e50086c4f4e2bb064c76a1de73e10c172f387Marco Nelissen mSurfaceTextureClient = new Surface(bufferProducer, true /* controlledByApp */); 126b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } else { 127b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 12888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 129b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 130b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return mCodec->configure(format, mSurfaceTextureClient, crypto, flags); 13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface( 1342621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 1352621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->createInputSurface(bufferProducer); 1362621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 1372621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 13888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 13988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->start(); 14088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 143b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 144b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->stop(); 14688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 14988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 15088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 15388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 154bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags, 155bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 156bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return mCodec->queueInputBuffer( 157bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timeUs, flags, errorDetailMsg); 15888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer( 1619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t index, 1629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t offset, 1639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const CryptoPlugin::SubSample *subSamples, 1649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t numSubSamples, 1659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t key[16], 1669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t iv[16], 1679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::Mode mode, 1689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber int64_t presentationTimeUs, 169bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber uint32_t flags, 170bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 1719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return mCodec->queueSecureInputBuffer( 1729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, subSamples, numSubSamples, key, iv, mode, 173bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber presentationTimeUs, flags, errorDetailMsg); 1749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 1759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 17788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->dequeueInputBuffer(index, timeoutUs); 17888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 18288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 18388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 18588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->dequeueOutputBuffer( 187c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber index, &offset, &size, &timeUs, &flags, timeoutUs)) != OK) { 18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1918d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 1928d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$BufferInfo")); 19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1948d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V"); 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->CallVoidMethod(bufferInfo, method, offset, size, timeUs, flags); 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::releaseOutputBuffer(size_t index, bool render) { 20188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 20388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2062621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() { 2072621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->signalEndOfInputStream(); 2082621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 2092621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, jobject *format) const { 21188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->getOutputFormat(&msg)) != OK) { 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 22188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber Vector<sp<ABuffer> > buffers; 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 22888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 23188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 23288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2338d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> byteBufferClass( 2348d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("java/nio/ByteBuffer")); 2358d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 2368d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(byteBufferClass.get() != NULL); 2373dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2383dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jmethodID orderID = env->GetMethodID( 2398d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber byteBufferClass.get(), 2403dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber "order", 2413dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); 2423dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2433dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(orderID != NULL); 2443dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2458d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> byteOrderClass( 2468d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("java/nio/ByteOrder")); 2478d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber 2488d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(byteOrderClass.get() != NULL); 2493dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2503dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jmethodID nativeOrderID = env->GetStaticMethodID( 2518d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;"); 2523dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(nativeOrderID != NULL); 2533dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2543dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jobject nativeByteOrderObj = 2558d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID); 2563dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(nativeByteOrderObj != NULL); 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 2598d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber buffers.size(), byteBufferClass.get(), NULL); 260cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (*bufArray == NULL) { 261cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen env->DeleteLocalRef(nativeByteOrderObj); 262cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 263cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 26588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ABuffer> &buffer = buffers.itemAt(i); 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 268cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if this is an ABuffer that doesn't actually hold any accessible memory, 269cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // use a null ByteBuffer 270cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (buffer->base() == NULL) { 271cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen continue; 272cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 27388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBuffer = 27488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->NewDirectByteBuffer( 27588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->base(), 27688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->capacity()); 277cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (byteBuffer == NULL) { 278cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen env->DeleteLocalRef(nativeByteOrderObj); 279cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 280cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 2813dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jobject me = env->CallObjectMethod( 2823dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber byteBuffer, orderID, nativeByteOrderObj); 2833dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber env->DeleteLocalRef(me); 2843dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber me = NULL; 2853dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetObjectArrayElement( 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray, i, byteBuffer); 28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteBuffer); 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteBuffer = NULL; 29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2933dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber env->DeleteLocalRef(nativeByteOrderObj); 2943dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber nativeByteOrderObj = NULL; 2953dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 299056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const { 300056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo AString name; 301056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 302056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = mCodec->getName(&name); 303056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 304056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err != OK) { 305056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return err; 306056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 307056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 308056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo *nameStr = env->NewStringUTF(name.c_str()); 309056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 310056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return OK; 311056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 312056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 313226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatus_t JMediaCodec::setParameters(const sp<AMessage> &msg) { 314226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return mCodec->setParameters(msg); 315226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 316226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 317b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) { 318b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mSurfaceTextureClient != NULL) { 319b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode); 320b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 321b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 322b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 331075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat sp<JMediaCodec> old = (JMediaCodec *)env->GetLongField(thiz, gFields.context); 33288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 338075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat env->SetLongField(thiz, gFields.context, (jlong)codec.get()); 33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 34288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 344075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (JMediaCodec *)env->GetLongField(thiz, gFields.context); 34588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 34688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 351bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { 3528d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 3538d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec$CryptoException")); 3548d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 355bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 356bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jmethodID constructID = 3578d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V"); 358bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(constructID != NULL); 359bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 360bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error"); 361bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 3623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker /* translate OS errors to Java API CryptoException errorCodes */ 3633ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker switch (err) { 3643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_NO_LICENSE: 3653ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorNoKey; 3663ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3673ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_LICENSE_EXPIRED: 3683ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorKeyExpired; 3693ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3703ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_RESOURCE_BUSY: 3713ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorResourceBusy; 3723ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3733ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker default: 3743ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3753ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker } 3763ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 377bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jthrowable exception = 3788d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj); 379bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 380bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->Throw(exception); 381bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber} 382bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 383bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary( 384bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber JNIEnv *env, status_t err, const char *msg = NULL) { 3853ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) { 386bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber // We'll throw our custom MediaCodec.CryptoException 387bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwCryptoException(env, err, msg); 388bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return 0; 389bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber } 390bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 39288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 39388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 39488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 39688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 39788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 40088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4043ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_NO_LICENSE: 4053ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_LICENSE_EXPIRED: 4063ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_RESOURCE_BUSY: 4073ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker throwCryptoException(env, err, msg); 4083ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 4093ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 412e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen jniThrowException(env, "java/lang/IllegalStateException", msg); 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 41988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 42188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 42288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 42388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 42488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 4258240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jobject jcrypto, 42688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 42888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 43088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 43188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 43288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 43388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 43688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 43788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 43888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 43988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 44088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 442d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> bufferProducer; 44388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 44464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 44588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 44652800617946c456e78ed010c82d0ec4358368164Mathias Agopian bufferProducer = surface->getIGraphicBufferProducer(); 44788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 44888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 44988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 45488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 45588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4568240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto; 4578240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto != NULL) { 4588240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto = JCrypto::GetCrypto(env, jcrypto); 4598240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 4608240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 461d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden err = codec->configure(format, bufferProducer, crypto, flags); 46288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 46488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 46588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4662621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env, 4672621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 4682621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_createInputSurface"); 4692621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4702621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 4712621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 4722621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jniThrowException(env, "java/lang/IllegalStateException", NULL); 4732621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 4742621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 4752621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4762621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Tell the MediaCodec that we want to use a Surface as input. 4772621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer> bufferProducer; 4782621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->createInputSurface(&bufferProducer); 4792621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (err != NO_ERROR) { 4802621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 4812621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 4822621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 4832621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4842621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Wrap the IGBP in a Java-language Surface. 4852621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return android_view_Surface_createFromIGraphicBufferProducer(env, 4862621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden bufferProducer); 4872621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 4882621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 48988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 49088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 49188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 495e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen jniThrowException(env, "java/lang/IllegalStateException", "no codec found"); 49688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 49788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 49888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 50088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 501e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen throwExceptionAsNecessary(env, err, "start failed"); 50288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 50388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 50588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 50688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 50888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 51088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 51188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 51288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 51388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 51588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 51788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 51888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 52088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 52188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 52388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 52588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 52688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 52788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 52888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 53088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 53288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 53388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 53588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 53688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 53788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 53888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 53988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 54088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 54188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 54288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 54388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 54488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 54588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 54688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 54788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 54888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 54988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 55088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 551bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 552bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 55388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 554bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timestampUs, flags, &errorDetailMsg); 55588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 556bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 557bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 55888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 55988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer( 5619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber JNIEnv *env, 5629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jobject thiz, 5639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint index, 5649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint offset, 56591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jobject cryptoInfoObj, 5669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jlong timestampUs, 5679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint flags) { 5689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ALOGV("android_media_MediaCodec_queueSecureInputBuffer"); 5699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 5719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (codec == NULL) { 5739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 5749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return; 5759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 57791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint numSubSamples = 57891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); 57991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 58091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfClearDataObj = 58191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 58291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); 58391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 58491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfEncryptedDataObj = 58591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 58691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); 58791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 58891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray keyObj = 58991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); 59091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 59191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray ivObj = 59291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); 59391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 59491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); 59591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 5969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber status_t err = OK; 5979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::SubSample *subSamples = NULL; 5999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *key = NULL; 6009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *iv = NULL; 6019e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numSubSamples <= 0) { 6039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 6049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj == NULL 6059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && numBytesOfEncryptedDataObj == NULL) { 6069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 6079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfEncryptedDataObj != NULL 6089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { 6099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 6109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj != NULL 6119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { 6129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 6139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 6149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 6159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfClearData = 6179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearDataObj == NULL) 6189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 6199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); 6209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfEncryptedData = 6229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedDataObj == NULL) 6239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 6249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); 6259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = new CryptoPlugin::SubSample[numSubSamples]; 6279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber for (jint i = 0; i < numSubSamples; ++i) { 6299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfClearData = 6309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; 6319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfEncryptedData = 6339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedData == NULL) 6349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? 0 : numBytesOfEncryptedData[i]; 6359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfEncryptedData != NULL) { 6389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 6399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); 6409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedData = NULL; 6419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfClearData != NULL) { 6449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 6459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearDataObj, numBytesOfClearData, 0); 6469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearData = NULL; 6479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && keyObj != NULL) { 6519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(keyObj) != 16) { 6529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 6539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 6549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 6559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = env->GetByteArrayElements(keyObj, &isCopy); 6569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6579e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && ivObj != NULL) { 6609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(ivObj) != 16) { 6619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 6629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 6639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 6649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = env->GetByteArrayElements(ivObj, &isCopy); 6659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 668bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 669bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 6709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK) { 6719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = codec->queueSecureInputBuffer( 6729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, 6739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples, numSubSamples, 6749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (const uint8_t *)key, (const uint8_t *)iv, 6759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (CryptoPlugin::Mode)mode, 676bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber timestampUs, 677bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber flags, 678bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber &errorDetailMsg); 6799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (iv != NULL) { 6829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(ivObj, iv, 0); 6839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = NULL; 6849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (key != NULL) { 6879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(keyObj, key, 0); 6889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = NULL; 6899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber delete[] subSamples; 6929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = NULL; 6939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 694bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 695bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 6969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 6979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 69888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 69988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 70088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 70188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 70388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 70588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 70688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 70788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 70888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 71088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 71188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 713075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 71488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 71588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 71788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 71888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 72088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 72188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 72288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 72488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 72688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 7270e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber return 0; 72888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 72988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 73188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 73288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 73388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 735075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat return (jint) index; 73688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 73788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 73988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 74088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 74288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jint index, jboolean render) { 74388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 74488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 74688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 74888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 74988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 75088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 75188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 75288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->releaseOutputBuffer(index, render); 75388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 75488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 75588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 75688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7572621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env, 7582621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 7592621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_signalEndOfInputStream"); 7602621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7612621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 7622621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 7632621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jniThrowException(env, "java/lang/IllegalStateException", NULL); 7642621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return; 7652621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 7662621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7672621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->signalEndOfInputStream(); 7682621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7692621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 7702621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 7712621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 77260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jobject android_media_MediaCodec_getOutputFormatNative( 77388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 77460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber ALOGV("android_media_MediaCodec_getOutputFormatNative"); 77588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 77788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 77988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 78088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 78188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 78288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 78488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getOutputFormat(env, &format); 78588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 78788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 78888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 78988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 79088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 79188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 79288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 79388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 79488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 79588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 79688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 79788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 79888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 79988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 80088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 80188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 80288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 80388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 80488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 80588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 80688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 80788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 80888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 80988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 81088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 81188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 81288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 813cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if we're out of memory, an exception was already thrown 814cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (err != NO_MEMORY) { 815cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen throwExceptionAsNecessary(env, err); 816cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 81788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 81888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 81988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 82088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 821056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName( 822056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo JNIEnv *env, jobject thiz) { 823056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo ALOGV("android_media_MediaCodec_getName"); 824056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 825056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo sp<JMediaCodec> codec = getMediaCodec(env, thiz); 826056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 827056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (codec == NULL) { 828056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jniThrowException(env, "java/lang/IllegalStateException", NULL); 829056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 830056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 831056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 832056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jstring name; 833056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = codec->getName(env, &name); 834056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 835056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err == OK) { 836056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return name; 837056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 838056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 839056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo throwExceptionAsNecessary(env, err); 840056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 841056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 842056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 843056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 844226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huberstatic void android_media_MediaCodec_setParameters( 845226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) { 846226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber ALOGV("android_media_MediaCodec_setParameters"); 847226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 848226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 849226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 850226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (codec == NULL) { 851226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 852226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber return; 853226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 854226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 855226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber sp<AMessage> params; 856226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, ¶ms); 857226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 858226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber if (err == OK) { 859226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber err = codec->setParameters(params); 860226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber } 861226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 862226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber throwExceptionAsNecessary(env, err); 863226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber} 864226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 865b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode( 866b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber JNIEnv *env, jobject thiz, jint mode) { 867b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 868b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 869b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (codec == NULL) { 870b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 871b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 872b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 873b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 874b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW 875b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 876b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/InvalidArgumentException", NULL); 877b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 878b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 879b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 880b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber codec->setVideoScalingMode(mode); 881b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 882b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 88388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 8848d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber ScopedLocalRef<jclass> clazz( 8858d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env, env->FindClass("android/media/MediaCodec")); 8868d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 88788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 888075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J"); 88988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 89091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 8918d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo")); 8928d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 89391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 89491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumSubSamplesID = 8958d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numSubSamples", "I"); 89691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumSubSamplesID != NULL); 89791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 89891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfClearDataID = 8998d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I"); 90091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL); 90191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 90291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfEncryptedDataID = 9038d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I"); 90491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL); 90591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 9068d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B"); 90791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoKeyID != NULL); 90891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 9098d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B"); 91091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoIVID != NULL); 91191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 9128d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I"); 91391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoModeID != NULL); 9143ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 9158d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException")); 9168d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber CHECK(clazz.get() != NULL); 9173ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 9183ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jfieldID field; 9198d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I"); 9203ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 9218d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorNoKey = 9228d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 9233ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 9248d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I"); 9253ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 9268d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorKeyExpired = 9278d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 9283ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 9298d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I"); 9303ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 9318d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber gCryptoErrorCodes.cryptoErrorResourceBusy = 9328d5f3e31c914e29129f50fe9830d71adf52ab5cfAndreas Huber env->GetStaticIntField(clazz.get(), field); 93388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 93488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 93588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 93688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 93788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 93888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 93988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 94088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 94188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 94288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 94388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 94488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 94588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 94688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 94788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 94888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 94988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 95088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->initCheck(); 95288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars(name, tmp); 95488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 95588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 95788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 95888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 95988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/io/IOException", 96088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "Failed to allocate component instance"); 96188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 96288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 96388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 96488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 96588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 96688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 96788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 96888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 96988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 97088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 97188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 97288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = { 97388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "release", "()V", (void *)android_media_MediaCodec_release }, 97488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 97588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 9768240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;" 97707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber "Landroid/media/MediaCrypto;I)V", 97888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 97988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9802621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "createInputSurface", "()Landroid/view/Surface;", 9812621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_createInputSurface }, 9822621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 98388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "start", "()V", (void *)android_media_MediaCodec_start }, 98488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "stop", "()V", (void *)android_media_MediaCodec_stop }, 98588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "flush", "()V", (void *)android_media_MediaCodec_flush }, 98688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 98788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "queueInputBuffer", "(IIIJI)V", 98888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 98988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 99091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber { "queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", 9919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (void *)android_media_MediaCodec_queueSecureInputBuffer }, 9929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 99388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueInputBuffer", "(J)I", 99488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 99588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 99688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 99788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 99888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 99988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "releaseOutputBuffer", "(IZ)V", 100088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 100188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10022621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "signalEndOfInputStream", "()V", 10032621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_signalEndOfInputStream }, 10042621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 100560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber { "getOutputFormatNative", "()Ljava/util/Map;", 100660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber (void *)android_media_MediaCodec_getOutputFormatNative }, 100788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 100888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 100988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 101088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1011056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo { "getName", "()Ljava/lang/String;", 1012056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo (void *)android_media_MediaCodec_getName }, 1013056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 1014226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V", 1015226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber (void *)android_media_MediaCodec_setParameters }, 1016226065bbe60cf32b33a5f86d27e2db88138e4486Andreas Huber 1017b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber { "setVideoScalingMode", "(I)V", 1018b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber (void *)android_media_MediaCodec_setVideoScalingMode }, 1019b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 102088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 102188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 102288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 102388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 102488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 102588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 102688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 102788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 102888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 102988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 103088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 103188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 103288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 1033