android_media_MediaCodec.cpp revision 3ed38266c1647c6219ae5ad89cb3f867cf66caaa
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 41b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber#include <system/window.h> 42b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 4388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android { 4488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!! 4688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum { 4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_TRY_AGAIN_LATER = -1, 4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED = -2, 4988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, 5088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 523ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinkerstruct CryptoErrorCodes { 533ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorNoKey; 543ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorKeyExpired; 553ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jint cryptoErrorResourceBusy; 563ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker} gCryptoErrorCodes; 573ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 5888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 5988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 6091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumSubSamplesID; 6191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfClearDataID; 6291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfEncryptedDataID; 6391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoKeyID; 6491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoIVID; 6591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoModeID; 6688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 6788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 6988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 7188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 7388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 7488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 7588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 7688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject(NULL) { 7788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 8188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 8288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 8488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 8588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // canCallJava 8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber PRIORITY_DEFAULT); 9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 9288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByType(mLooper, name, encoder); 9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByComponentName(mLooper, name); 9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 9988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec != NULL ? OK : NO_INIT; 10088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::~JMediaCodec() { 103d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo if (mCodec != NULL) { 104d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec->release(); 105d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec.clear(); 106d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo } 10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 11288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 118d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden const sp<IGraphicBufferProducer> &bufferProducer, 1198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const sp<ICrypto> &crypto, 12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 12152800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> client; 122d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden if (bufferProducer != NULL) { 12352800617946c456e78ed010c82d0ec4358368164Mathias Agopian mSurfaceTextureClient = new Surface(bufferProducer); 124b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } else { 125b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 127b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 128b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return mCodec->configure(format, mSurfaceTextureClient, crypto, flags); 12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 13088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1312621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface( 1322621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 1332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->createInputSurface(bufferProducer); 1342621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 1352621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 13688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 13788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->start(); 13888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 13988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 141b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 142b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 14388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->stop(); 14488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 14788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 14888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 152bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags, 153bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 154bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return mCodec->queueInputBuffer( 155bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timeUs, flags, errorDetailMsg); 15688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 15788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer( 1599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t index, 1609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t offset, 1619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const CryptoPlugin::SubSample *subSamples, 1629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t numSubSamples, 1639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t key[16], 1649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t iv[16], 1659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::Mode mode, 1669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber int64_t presentationTimeUs, 167bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber uint32_t flags, 168bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 1699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return mCodec->queueSecureInputBuffer( 1709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, subSamples, numSubSamples, key, iv, mode, 171bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber presentationTimeUs, flags, errorDetailMsg); 1729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 1739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->dequeueInputBuffer(index, timeoutUs); 17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 17788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 18288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 18388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->dequeueOutputBuffer( 185c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber index, &offset, &size, &timeUs, &flags, timeoutUs)) != OK) { 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 18788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec$BufferInfo"); 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID method = env->GetMethodID(clazz, "set", "(IIJI)V"); 19288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->CallVoidMethod(bufferInfo, method, offset, size, timeUs, flags); 19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::releaseOutputBuffer(size_t index, bool render) { 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 20188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2032621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() { 2042621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->signalEndOfInputStream(); 2052621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 2062621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 20788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, jobject *format) const { 20888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 20988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->getOutputFormat(&msg)) != OK) { 21188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber Vector<sp<ABuffer> > buffers; 22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 22488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 22888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 22988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass byteBufferClass = env->FindClass("java/nio/ByteBuffer"); 2313dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(byteBufferClass != NULL); 2323dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2333dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jmethodID orderID = env->GetMethodID( 2343dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber byteBufferClass, 2353dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber "order", 2363dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); 2373dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2383dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(orderID != NULL); 2393dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2403dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jclass byteOrderClass = env->FindClass("java/nio/ByteOrder"); 2413dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(byteOrderClass != NULL); 2423dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2433dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jmethodID nativeOrderID = env->GetStaticMethodID( 2443dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber byteOrderClass, "nativeOrder", "()Ljava/nio/ByteOrder;"); 2453dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(nativeOrderID != NULL); 2463dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2473dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jobject nativeByteOrderObj = 2483dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber env->CallStaticObjectMethod(byteOrderClass, nativeOrderID); 2493dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(nativeByteOrderObj != NULL); 25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffers.size(), byteBufferClass, NULL); 253cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (*bufArray == NULL) { 254cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen env->DeleteLocalRef(nativeByteOrderObj); 255cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 256cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 25988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ABuffer> &buffer = buffers.itemAt(i); 26088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 261cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if this is an ABuffer that doesn't actually hold any accessible memory, 262cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // use a null ByteBuffer 263cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (buffer->base() == NULL) { 264cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen continue; 265cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 26688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBuffer = 26788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->NewDirectByteBuffer( 26888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->base(), 26988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->capacity()); 270cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (byteBuffer == NULL) { 271cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen env->DeleteLocalRef(nativeByteOrderObj); 272cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 273cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 2743dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jobject me = env->CallObjectMethod( 2753dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber byteBuffer, orderID, nativeByteOrderObj); 2763dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber env->DeleteLocalRef(me); 2773dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber me = NULL; 2783dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 27988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetObjectArrayElement( 28088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray, i, byteBuffer); 28188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteBuffer); 28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteBuffer = NULL; 28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2863dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber env->DeleteLocalRef(nativeByteOrderObj); 2873dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber nativeByteOrderObj = NULL; 2883dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 292056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const { 293056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo AString name; 294056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 295056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = mCodec->getName(&name); 296056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 297056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err != OK) { 298056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return err; 299056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 300056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 301056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo *nameStr = env->NewStringUTF(name.c_str()); 302056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 303056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return OK; 304056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 305056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 306b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) { 307b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mSurfaceTextureClient != NULL) { 308b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode); 309b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 310b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 311b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> old = (JMediaCodec *)env->GetIntField(thiz, gFields.context); 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetIntField(thiz, gFields.context, (int)codec.get()); 32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return (JMediaCodec *)env->GetIntField(thiz, gFields.context); 33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 340bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { 341bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec$CryptoException"); 342bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(clazz != NULL); 343bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 344bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jmethodID constructID = 345bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V"); 346bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(constructID != NULL); 347bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 348bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error"); 349bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 3503ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker /* translate OS errors to Java API CryptoException errorCodes */ 3513ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker switch (err) { 3523ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_NO_LICENSE: 3533ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorNoKey; 3543ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3553ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_LICENSE_EXPIRED: 3563ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorKeyExpired; 3573ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3583ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_RESOURCE_BUSY: 3593ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker err = gCryptoErrorCodes.cryptoErrorResourceBusy; 3603ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3613ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker default: 3623ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3633ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker } 3643ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 365bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jthrowable exception = 366bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber (jthrowable)env->NewObject(clazz, constructID, err, msgObj); 367bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 368bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->Throw(exception); 369bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber} 370bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 371bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary( 372bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber JNIEnv *env, status_t err, const char *msg = NULL) { 3733ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) { 374bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber // We'll throw our custom MediaCodec.CryptoException 375bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwCryptoException(env, err, msg); 376bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return 0; 377bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber } 378bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 38488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3923ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_NO_LICENSE: 3933ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_LICENSE_EXPIRED: 3943ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker case ERROR_DRM_RESOURCE_BUSY: 3953ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker throwCryptoException(env, err, msg); 3963ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker break; 3973ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 39888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 400e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen jniThrowException(env, "java/lang/IllegalStateException", msg); 40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 40688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 40788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 4138240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jobject jcrypto, 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 41988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 42088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 42188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 42388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 42488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 42688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 42888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 42988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 430d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> bufferProducer; 43188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 43264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 43388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 43452800617946c456e78ed010c82d0ec4358368164Mathias Agopian bufferProducer = surface->getIGraphicBufferProducer(); 43588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 43688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 43788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 43888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 43988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 44088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 44188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 44388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4448240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto; 4458240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto != NULL) { 4468240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto = JCrypto::GetCrypto(env, jcrypto); 4478240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 4488240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 449d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden err = codec->configure(format, bufferProducer, crypto, flags); 45088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4542621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env, 4552621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 4562621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_createInputSurface"); 4572621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4582621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 4592621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 4602621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jniThrowException(env, "java/lang/IllegalStateException", NULL); 4612621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 4622621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 4632621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4642621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Tell the MediaCodec that we want to use a Surface as input. 4652621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer> bufferProducer; 4662621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->createInputSurface(&bufferProducer); 4672621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (err != NO_ERROR) { 4682621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 4692621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 4702621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 4712621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4722621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Wrap the IGBP in a Java-language Surface. 4732621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return android_view_Surface_createFromIGraphicBufferProducer(env, 4742621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden bufferProducer); 4752621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 4762621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 47788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 47888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 47988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 48188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 483e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen jniThrowException(env, "java/lang/IllegalStateException", "no codec found"); 48488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 48588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 48688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 48888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 489e20a6d5c479909f37af748a81a6e5a5deb7b6e2cMarco Nelissen throwExceptionAsNecessary(env, err, "start failed"); 49088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 49188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 49488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 49688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 49888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 49988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 50088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 50188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 50388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 50588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 50688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 50788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 50888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 50988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 51188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 51388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 51488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 51588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 51688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 51888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 51988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 52088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 52188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 52288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 52388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 52488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 52588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 52688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 52788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 52888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 52988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 53088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 53188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 53388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 53488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 53588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 53688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 53788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 53888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 539bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 540bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 54188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 542bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timestampUs, flags, &errorDetailMsg); 54388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 544bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 545bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 54688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 54788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer( 5499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber JNIEnv *env, 5509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jobject thiz, 5519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint index, 5529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint offset, 55391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jobject cryptoInfoObj, 5549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jlong timestampUs, 5559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint flags) { 5569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ALOGV("android_media_MediaCodec_queueSecureInputBuffer"); 5579e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 5599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (codec == NULL) { 5619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 5629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return; 5639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 56591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint numSubSamples = 56691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); 56791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 56891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfClearDataObj = 56991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 57091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); 57191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 57291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfEncryptedDataObj = 57391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 57491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); 57591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 57691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray keyObj = 57791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); 57891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 57991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray ivObj = 58091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); 58191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 58291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); 58391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 5849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber status_t err = OK; 5859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::SubSample *subSamples = NULL; 5879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *key = NULL; 5889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *iv = NULL; 5899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numSubSamples <= 0) { 5919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 5929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj == NULL 5939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && numBytesOfEncryptedDataObj == NULL) { 5949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 5959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfEncryptedDataObj != NULL 5969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { 5979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 5989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj != NULL 5999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { 6009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 6019e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 6029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 6039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfClearData = 6059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearDataObj == NULL) 6069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 6079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); 6089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfEncryptedData = 6109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedDataObj == NULL) 6119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 6129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); 6139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = new CryptoPlugin::SubSample[numSubSamples]; 6159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber for (jint i = 0; i < numSubSamples; ++i) { 6179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfClearData = 6189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; 6199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfEncryptedData = 6219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedData == NULL) 6229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? 0 : numBytesOfEncryptedData[i]; 6239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfEncryptedData != NULL) { 6269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 6279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); 6289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedData = NULL; 6299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfClearData != NULL) { 6329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 6339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearDataObj, numBytesOfClearData, 0); 6349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearData = NULL; 6359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && keyObj != NULL) { 6399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(keyObj) != 16) { 6409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 6419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 6429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 6439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = env->GetByteArrayElements(keyObj, &isCopy); 6449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && ivObj != NULL) { 6489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(ivObj) != 16) { 6499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 6509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 6519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 6529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = env->GetByteArrayElements(ivObj, &isCopy); 6539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 656bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 657bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 6589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK) { 6599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = codec->queueSecureInputBuffer( 6609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, 6619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples, numSubSamples, 6629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (const uint8_t *)key, (const uint8_t *)iv, 6639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (CryptoPlugin::Mode)mode, 664bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber timestampUs, 665bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber flags, 666bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber &errorDetailMsg); 6679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (iv != NULL) { 6709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(ivObj, iv, 0); 6719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = NULL; 6729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (key != NULL) { 6759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(keyObj, key, 0); 6769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = NULL; 6779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber delete[] subSamples; 6809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = NULL; 6819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 682bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 683bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 6849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 6859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 68688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 68788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 68888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 68988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 69088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 69188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 69288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 69388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 69488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 69588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 69688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 69788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 69888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 69988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 70188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return index; 70288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 70388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 70588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 70688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 70888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 70988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 71088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 71288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 71488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 7150e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber return 0; 71688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 71788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 71988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 72088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 72188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 72388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return index; 72488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 72588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 72788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 72888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 73088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jint index, jboolean render) { 73188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 73288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 73488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 73688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 73788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 73888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 73988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->releaseOutputBuffer(index, render); 74188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 74388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 74488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7452621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env, 7462621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 7472621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_signalEndOfInputStream"); 7482621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7492621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 7502621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 7512621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jniThrowException(env, "java/lang/IllegalStateException", NULL); 7522621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return; 7532621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 7542621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7552621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->signalEndOfInputStream(); 7562621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7572621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 7582621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 7592621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 76060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jobject android_media_MediaCodec_getOutputFormatNative( 76188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 76260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber ALOGV("android_media_MediaCodec_getOutputFormatNative"); 76388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 76488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 76588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 76688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 76788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 76888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 76988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 77088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 77288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getOutputFormat(env, &format); 77388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 77588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 77688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 77788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 77988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 78188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 78288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 78488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 78588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 78688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 78888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 79088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 79188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 79288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 79388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 79488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 79588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 79688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 79788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 79888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 79988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 80088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 801cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if we're out of memory, an exception was already thrown 802cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (err != NO_MEMORY) { 803cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen throwExceptionAsNecessary(env, err); 804cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 80588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 80688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 80788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 80888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 809056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName( 810056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo JNIEnv *env, jobject thiz) { 811056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo ALOGV("android_media_MediaCodec_getName"); 812056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 813056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo sp<JMediaCodec> codec = getMediaCodec(env, thiz); 814056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 815056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (codec == NULL) { 816056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jniThrowException(env, "java/lang/IllegalStateException", NULL); 817056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 818056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 819056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 820056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jstring name; 821056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = codec->getName(env, &name); 822056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 823056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err == OK) { 824056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return name; 825056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 826056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 827056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo throwExceptionAsNecessary(env, err); 828056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 829056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 830056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 831056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 832b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode( 833b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber JNIEnv *env, jobject thiz, jint mode) { 834b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 835b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 836b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (codec == NULL) { 837b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 838b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 839b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 840b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 841b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW 842b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 843b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/InvalidArgumentException", NULL); 844b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 845b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 846b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 847b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber codec->setVideoScalingMode(mode); 848b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 849b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 85088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 85188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec"); 85288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 85388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 85488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber gFields.context = env->GetFieldID(clazz, "mNativeContext", "I"); 85588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 85691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 85791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber clazz = env->FindClass("android/media/MediaCodec$CryptoInfo"); 85891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(clazz != NULL); 85991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 86091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumSubSamplesID = 86191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numSubSamples", "I"); 86291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumSubSamplesID != NULL); 86391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 86491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfClearDataID = 86591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numBytesOfClearData", "[I"); 86691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL); 86791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 86891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfEncryptedDataID = 86991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numBytesOfEncryptedData", "[I"); 87091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL); 87191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 87291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoKeyID = env->GetFieldID(clazz, "key", "[B"); 87391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoKeyID != NULL); 87491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 87591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoIVID = env->GetFieldID(clazz, "iv", "[B"); 87691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoIVID != NULL); 87791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 87891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoModeID = env->GetFieldID(clazz, "mode", "I"); 87991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoModeID != NULL); 8803ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 8813ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker clazz = env->FindClass("android/media/MediaCodec$CryptoException"); 8823ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(clazz != NULL); 8833ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 8843ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker jfieldID field; 8853ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker field = env->GetStaticFieldID(clazz, "ERROR_NO_KEY", "I"); 8863ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 8873ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker gCryptoErrorCodes.cryptoErrorNoKey = env->GetStaticIntField(clazz, field); 8883ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 8893ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker field = env->GetStaticFieldID(clazz, "ERROR_KEY_EXPIRED", "I"); 8903ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 8913ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker gCryptoErrorCodes.cryptoErrorKeyExpired = env->GetStaticIntField(clazz, field); 8923ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker 8933ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker field = env->GetStaticFieldID(clazz, "ERROR_RESOURCE_BUSY", "I"); 8943ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker CHECK(field != NULL); 8953ed38266c1647c6219ae5ad89cb3f867cf66caaaJeff Tinker gCryptoErrorCodes.cryptoErrorResourceBusy = env->GetStaticIntField(clazz, field); 89688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 89788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 89888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 89988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 90088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 90188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 90288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 90388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 90488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 90588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 90788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 90988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 91088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 91188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 91388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->initCheck(); 91588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars(name, tmp); 91788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 91888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 92088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 92188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 92288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/io/IOException", 92388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "Failed to allocate component instance"); 92488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 92588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 92688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 92788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 92888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 92988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 93088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 93188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 93288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 93388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 93488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 93588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = { 93688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "release", "()V", (void *)android_media_MediaCodec_release }, 93788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 93888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 9398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;" 94007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber "Landroid/media/MediaCrypto;I)V", 94188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 94288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9432621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "createInputSurface", "()Landroid/view/Surface;", 9442621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_createInputSurface }, 9452621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 94688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "start", "()V", (void *)android_media_MediaCodec_start }, 94788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "stop", "()V", (void *)android_media_MediaCodec_stop }, 94888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "flush", "()V", (void *)android_media_MediaCodec_flush }, 94988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "queueInputBuffer", "(IIIJI)V", 95188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 95288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber { "queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", 9549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (void *)android_media_MediaCodec_queueSecureInputBuffer }, 9559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 95688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueInputBuffer", "(J)I", 95788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 95888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 95988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 96088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 96188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 96288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "releaseOutputBuffer", "(IZ)V", 96388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 96488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9652621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "signalEndOfInputStream", "()V", 9662621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_signalEndOfInputStream }, 9672621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 96860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber { "getOutputFormatNative", "()Ljava/util/Map;", 96960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber (void *)android_media_MediaCodec_getOutputFormatNative }, 97088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 97188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 97288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 97388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 974056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo { "getName", "()Ljava/lang/String;", 975056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo (void *)android_media_MediaCodec_getName }, 976056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 977b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber { "setVideoScalingMode", "(I)V", 978b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber (void *)android_media_MediaCodec_setVideoScalingMode }, 979b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 98088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 98188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 98288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 98388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 98488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 98588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 98688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 98788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 98888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 98988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 99088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 99188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 99288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 993