android_media_MediaCodec.cpp revision 2621e40d0e0a496a96575768b7e2b70e3b3be640
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 5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 5388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 5491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 5591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumSubSamplesID; 5691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfClearDataID; 5791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfEncryptedDataID; 5891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoKeyID; 5991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoIVID; 6091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoModeID; 6188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 6288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 6488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 6688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 6888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 6988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 7088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 7188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject(NULL) { 7288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 7388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 7488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 7688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 7788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 8088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 8288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 8388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // canCallJava 8488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber PRIORITY_DEFAULT); 8588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByType(mLooper, name, encoder); 8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByComponentName(mLooper, name); 9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 9288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec != NULL ? OK : NO_INIT; 9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::~JMediaCodec() { 98d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo if (mCodec != NULL) { 99d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec->release(); 100d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo mCodec.clear(); 101d932de9aff49d1d9f752ad479b42854d2557c881Martin Storsjo } 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 10688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 11088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 11288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 113d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden const sp<IGraphicBufferProducer> &bufferProducer, 1148240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const sp<ICrypto> &crypto, 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 11652800617946c456e78ed010c82d0ec4358368164Mathias Agopian sp<Surface> client; 117d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden if (bufferProducer != NULL) { 11852800617946c456e78ed010c82d0ec4358368164Mathias Agopian mSurfaceTextureClient = new Surface(bufferProducer); 119b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } else { 120b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 122b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 123b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return mCodec->configure(format, mSurfaceTextureClient, crypto, flags); 12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1262621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::createInputSurface( 1272621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 1282621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->createInputSurface(bufferProducer); 1292621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 1302621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->start(); 13388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 13488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 13588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 136b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber mSurfaceTextureClient.clear(); 137b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 13888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->stop(); 13988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 14288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 14388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 14488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 14588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 14688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 147bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags, 148bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 149bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return mCodec->queueInputBuffer( 150bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timeUs, flags, errorDetailMsg); 15188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 15288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer( 1549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t index, 1559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t offset, 1569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const CryptoPlugin::SubSample *subSamples, 1579e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t numSubSamples, 1589e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t key[16], 1599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t iv[16], 1609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::Mode mode, 1619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber int64_t presentationTimeUs, 162bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber uint32_t flags, 163bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 1649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return mCodec->queueSecureInputBuffer( 1659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, subSamples, numSubSamples, key, iv, mode, 166bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber presentationTimeUs, flags, errorDetailMsg); 1679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 1689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 16988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 17088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->dequeueInputBuffer(index, timeoutUs); 17188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 17288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 17788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 17888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->dequeueOutputBuffer( 180c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber index, &offset, &size, &timeUs, &flags, timeoutUs)) != OK) { 18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 18288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 18388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec$BufferInfo"); 18588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID method = env->GetMethodID(clazz, "set", "(IIJI)V"); 18788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->CallVoidMethod(bufferInfo, method, offset, size, timeUs, flags); 18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::releaseOutputBuffer(size_t index, bool render) { 19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1982621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatus_t JMediaCodec::signalEndOfInputStream() { 1992621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return mCodec->signalEndOfInputStream(); 2002621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 2012621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, jobject *format) const { 20388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->getOutputFormat(&msg)) != OK) { 20688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 20788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 20888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 21188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber Vector<sp<ABuffer> > buffers; 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 22488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass byteBufferClass = env->FindClass("java/nio/ByteBuffer"); 2263dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(byteBufferClass != NULL); 2273dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2283dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jmethodID orderID = env->GetMethodID( 2293dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber byteBufferClass, 2303dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber "order", 2313dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); 2323dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2333dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(orderID != NULL); 2343dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2353dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jclass byteOrderClass = env->FindClass("java/nio/ByteOrder"); 2363dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(byteOrderClass != NULL); 2373dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2383dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jmethodID nativeOrderID = env->GetStaticMethodID( 2393dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber byteOrderClass, "nativeOrder", "()Ljava/nio/ByteOrder;"); 2403dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(nativeOrderID != NULL); 2413dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 2423dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jobject nativeByteOrderObj = 2433dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber env->CallStaticObjectMethod(byteOrderClass, nativeOrderID); 2443dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber CHECK(nativeByteOrderObj != NULL); 24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffers.size(), byteBufferClass, NULL); 248cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (*bufArray == NULL) { 249cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen env->DeleteLocalRef(nativeByteOrderObj); 250cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 251cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 25488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ABuffer> &buffer = buffers.itemAt(i); 25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 256cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if this is an ABuffer that doesn't actually hold any accessible memory, 257cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // use a null ByteBuffer 258cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (buffer->base() == NULL) { 259cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen continue; 260cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 26188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBuffer = 26288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->NewDirectByteBuffer( 26388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->base(), 26488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->capacity()); 265cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (byteBuffer == NULL) { 266cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen env->DeleteLocalRef(nativeByteOrderObj); 267cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen return NO_MEMORY; 268cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 2693dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber jobject me = env->CallObjectMethod( 2703dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber byteBuffer, orderID, nativeByteOrderObj); 2713dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber env->DeleteLocalRef(me); 2723dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber me = NULL; 2733dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 27488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetObjectArrayElement( 27588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray, i, byteBuffer); 27688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 27788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteBuffer); 27888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteBuffer = NULL; 27988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 28088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 2813dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber env->DeleteLocalRef(nativeByteOrderObj); 2823dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber nativeByteOrderObj = NULL; 2833dd7fd08a8a1d658b0aac8590f1fd922e056f689Andreas Huber 28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 287056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatus_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const { 288056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo AString name; 289056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 290056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = mCodec->getName(&name); 291056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 292056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err != OK) { 293056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return err; 294056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 295056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 296056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo *nameStr = env->NewStringUTF(name.c_str()); 297056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 298056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return OK; 299056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 300056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 301b12a5390694e8525ac61d7377e266e31d124c815Andreas Hubervoid JMediaCodec::setVideoScalingMode(int mode) { 302b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mSurfaceTextureClient != NULL) { 303b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode); 304b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 305b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 306b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> old = (JMediaCodec *)env->GetIntField(thiz, gFields.context); 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetIntField(thiz, gFields.context, (int)codec.get()); 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return (JMediaCodec *)env->GetIntField(thiz, gFields.context); 32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 33288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 335bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { 336bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec$CryptoException"); 337bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(clazz != NULL); 338bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 339bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jmethodID constructID = 340bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V"); 341bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(constructID != NULL); 342bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 343bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error"); 344bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 345bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jthrowable exception = 346bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber (jthrowable)env->NewObject(clazz, constructID, err, msgObj); 347bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 348bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->Throw(exception); 349bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber} 350bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 351bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary( 352bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber JNIEnv *env, status_t err, const char *msg = NULL) { 353bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber if (err >= ERROR_DRM_WV_VENDOR_MIN && err <= ERROR_DRM_WV_VENDOR_MAX) { 354bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber // We'll throw our custom MediaCodec.CryptoException 355bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 356bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwCryptoException(env, err, msg); 357bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return 0; 358bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber } 359bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 36588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 36988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 37188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 37288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 37488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 37588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 37888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 38488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 3888240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jobject jcrypto, 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 39388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 39488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 39588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 39888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 405d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden sp<IGraphicBufferProducer> bufferProducer; 40688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 40764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 40952800617946c456e78ed010c82d0ec4358368164Mathias Agopian bufferProducer = surface->getIGraphicBufferProducer(); 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 41488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 41588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4198240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto; 4208240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto != NULL) { 4218240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto = JCrypto::GetCrypto(env, jcrypto); 4228240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 4238240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 424d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden err = codec->configure(format, bufferProducer, crypto, flags); 42588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 42688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 42788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 42888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4292621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic jobject android_media_MediaCodec_createInputSurface(JNIEnv* env, 4302621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 4312621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_createInputSurface"); 4322621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 4342621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 4352621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jniThrowException(env, "java/lang/IllegalStateException", NULL); 4362621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 4372621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 4382621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4392621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Tell the MediaCodec that we want to use a Surface as input. 4402621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<IGraphicBufferProducer> bufferProducer; 4412621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->createInputSurface(&bufferProducer); 4422621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (err != NO_ERROR) { 4432621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 4442621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return NULL; 4452621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 4462621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 4472621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden // Wrap the IGBP in a Java-language Surface. 4482621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return android_view_Surface_createFromIGraphicBufferProducer(env, 4492621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden bufferProducer); 4502621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 4512621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 45288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 45388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 45488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 45688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 45788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 45888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 45988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 46088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 46188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 46388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 46588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 46688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 46788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 46888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 46988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 47088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 47188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 47288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 47388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 47488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 47588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 47688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 47788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 47888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 47988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 48088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 48188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 48388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 48488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 48688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 48788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 48888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 48988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 49088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 49188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 49388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 49588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 49688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 49788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 49888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 49988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 50088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 50188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 50288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 50388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 50488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 50588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 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 514bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 515bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 51688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 517bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timestampUs, flags, &errorDetailMsg); 51888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 519bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 520bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 52188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 52288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer( 5249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber JNIEnv *env, 5259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jobject thiz, 5269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint index, 5279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint offset, 52891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jobject cryptoInfoObj, 5299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jlong timestampUs, 5309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint flags) { 5319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ALOGV("android_media_MediaCodec_queueSecureInputBuffer"); 5329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 5349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (codec == NULL) { 5369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 5379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return; 5389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 54091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint numSubSamples = 54191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); 54291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 54391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfClearDataObj = 54491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 54591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); 54691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 54791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfEncryptedDataObj = 54891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 54991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); 55091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 55191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray keyObj = 55291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); 55391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 55491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray ivObj = 55591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); 55691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 55791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); 55891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 5599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber status_t err = OK; 5609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::SubSample *subSamples = NULL; 5629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *key = NULL; 5639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *iv = NULL; 5649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numSubSamples <= 0) { 5669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 5679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj == NULL 5689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && numBytesOfEncryptedDataObj == NULL) { 5699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 5709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfEncryptedDataObj != NULL 5719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { 5729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 5739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj != NULL 5749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { 5759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 5769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 5779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 5789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfClearData = 5809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearDataObj == NULL) 5819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 5829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); 5839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfEncryptedData = 5859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedDataObj == NULL) 5869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 5879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); 5889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = new CryptoPlugin::SubSample[numSubSamples]; 5909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber for (jint i = 0; i < numSubSamples; ++i) { 5929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfClearData = 5939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; 5949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfEncryptedData = 5969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedData == NULL) 5979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? 0 : numBytesOfEncryptedData[i]; 5989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfEncryptedData != NULL) { 6019e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 6029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); 6039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedData = NULL; 6049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfClearData != NULL) { 6079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 6089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearDataObj, numBytesOfClearData, 0); 6099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearData = NULL; 6109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && keyObj != NULL) { 6149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(keyObj) != 16) { 6159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 6169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 6179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 6189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = env->GetByteArrayElements(keyObj, &isCopy); 6199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && ivObj != NULL) { 6239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(ivObj) != 16) { 6249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 6259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 6269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 6279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = env->GetByteArrayElements(ivObj, &isCopy); 6289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 631bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 632bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 6339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK) { 6349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = codec->queueSecureInputBuffer( 6359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, 6369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples, numSubSamples, 6379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (const uint8_t *)key, (const uint8_t *)iv, 6389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (CryptoPlugin::Mode)mode, 639bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber timestampUs, 640bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber flags, 641bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber &errorDetailMsg); 6429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (iv != NULL) { 6459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(ivObj, iv, 0); 6469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = NULL; 6479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (key != NULL) { 6509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(keyObj, key, 0); 6519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = NULL; 6529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 6539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 6549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber delete[] subSamples; 6559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = NULL; 6569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 657bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 658bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 6599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 6609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 66188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 66288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 66388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 66488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 66588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 66688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 66788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 66888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 66988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 67088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 67188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 67288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 67388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 67488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 67588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 67688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return index; 67788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 67888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 67988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 68088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 68188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 68288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 68388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 68488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 68588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 68688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 68788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 68888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 68988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 6900e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber return 0; 69188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 69288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 69388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 69488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 69588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 69688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 69788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 69888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return index; 69988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 70088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 70288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 70388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 70588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jint index, jboolean render) { 70688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 70788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 70988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 71188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 71288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 71388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 71488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->releaseOutputBuffer(index, render); 71688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 71888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 71988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7202621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFaddenstatic void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env, 7212621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jobject thiz) { 7222621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden ALOGV("android_media_MediaCodec_signalEndOfInputStream"); 7232621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7242621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden sp<JMediaCodec> codec = getMediaCodec(env, thiz); 7252621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden if (codec == NULL) { 7262621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden jniThrowException(env, "java/lang/IllegalStateException", NULL); 7272621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden return; 7282621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden } 7292621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7302621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden status_t err = codec->signalEndOfInputStream(); 7312621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 7322621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden throwExceptionAsNecessary(env, err); 7332621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden} 7342621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 73560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberstatic jobject android_media_MediaCodec_getOutputFormatNative( 73688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 73760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber ALOGV("android_media_MediaCodec_getOutputFormatNative"); 73888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 74088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 74288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 74388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 74488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 74588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 74788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getOutputFormat(env, &format); 74888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 75088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 75188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 75288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 75388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 75488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 75588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 75688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 75788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 75888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 75988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 76088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 76188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 76288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 76388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 76488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 76588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 76688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 76788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 76888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 76988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 77088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 77188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 77388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 77488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 77588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 776cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen // if we're out of memory, an exception was already thrown 777cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen if (err != NO_MEMORY) { 778cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen throwExceptionAsNecessary(env, err); 779cbbea8e651feb580f439e28359d72589709fb120Marco Nelissen } 78088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 78188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 78288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 78388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 784056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjostatic jobject android_media_MediaCodec_getName( 785056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo JNIEnv *env, jobject thiz) { 786056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo ALOGV("android_media_MediaCodec_getName"); 787056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 788056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo sp<JMediaCodec> codec = getMediaCodec(env, thiz); 789056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 790056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (codec == NULL) { 791056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jniThrowException(env, "java/lang/IllegalStateException", NULL); 792056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 793056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 794056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 795056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo jstring name; 796056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo status_t err = codec->getName(env, &name); 797056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 798056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo if (err == OK) { 799056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return name; 800056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo } 801056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 802056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo throwExceptionAsNecessary(env, err); 803056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 804056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo return NULL; 805056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo} 806056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 807b12a5390694e8525ac61d7377e266e31d124c815Andreas Huberstatic void android_media_MediaCodec_setVideoScalingMode( 808b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber JNIEnv *env, jobject thiz, jint mode) { 809b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 810b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 811b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (codec == NULL) { 812b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 813b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 814b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 815b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 816b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW 817b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber && mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 818b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber jniThrowException(env, "java/lang/InvalidArgumentException", NULL); 819b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber return; 820b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber } 821b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 822b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber codec->setVideoScalingMode(mode); 823b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber} 824b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 82588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 82688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec"); 82788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 82888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 82988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber gFields.context = env->GetFieldID(clazz, "mNativeContext", "I"); 83088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 83191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 83291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber clazz = env->FindClass("android/media/MediaCodec$CryptoInfo"); 83391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(clazz != NULL); 83491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 83591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumSubSamplesID = 83691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numSubSamples", "I"); 83791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumSubSamplesID != NULL); 83891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 83991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfClearDataID = 84091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numBytesOfClearData", "[I"); 84191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL); 84291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 84391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfEncryptedDataID = 84491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numBytesOfEncryptedData", "[I"); 84591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL); 84691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 84791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoKeyID = env->GetFieldID(clazz, "key", "[B"); 84891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoKeyID != NULL); 84991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 85091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoIVID = env->GetFieldID(clazz, "iv", "[B"); 85191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoIVID != NULL); 85291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 85391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoModeID = env->GetFieldID(clazz, "mode", "I"); 85491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoModeID != NULL); 85588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 85688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 85788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 85888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 85988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 86088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 86188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 86288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 86388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 86488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 86588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 86688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 86788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 86888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 86988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 87088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 87188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 87288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 87388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->initCheck(); 87488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 87588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars(name, tmp); 87688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 87788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 87888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 87988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 88088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 88188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/io/IOException", 88288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "Failed to allocate component instance"); 88388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 88488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 88588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 88688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 88788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 88888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 88988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 89088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 89188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 89288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 89388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 89488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = { 89588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "release", "()V", (void *)android_media_MediaCodec_release }, 89688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 89788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 8988240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;" 89907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber "Landroid/media/MediaCrypto;I)V", 90088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 90188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9022621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "createInputSurface", "()Landroid/view/Surface;", 9032621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_createInputSurface }, 9042621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 90588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "start", "()V", (void *)android_media_MediaCodec_start }, 90688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "stop", "()V", (void *)android_media_MediaCodec_stop }, 90788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "flush", "()V", (void *)android_media_MediaCodec_flush }, 90888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 90988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "queueInputBuffer", "(IIIJI)V", 91088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 91188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber { "queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", 9139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (void *)android_media_MediaCodec_queueSecureInputBuffer }, 9149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 91588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueInputBuffer", "(J)I", 91688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 91788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 91888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 91988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 92088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 92188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "releaseOutputBuffer", "(IZ)V", 92288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 92388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9242621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden { "signalEndOfInputStream", "()V", 9252621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden (void *)android_media_MediaCodec_signalEndOfInputStream }, 9262621e40d0e0a496a96575768b7e2b70e3b3be640Andy McFadden 92760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber { "getOutputFormatNative", "()Ljava/util/Map;", 92860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber (void *)android_media_MediaCodec_getOutputFormatNative }, 92988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 93088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 93188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 93288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 933056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo { "getName", "()Ljava/lang/String;", 934056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo (void *)android_media_MediaCodec_getName }, 935056ef2ed5ff92b742fe53f2498c596ec1f6bed3cMartin Storsjo 936b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber { "setVideoScalingMode", "(I)V", 937b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber (void *)android_media_MediaCodec_setVideoScalingMode }, 938b12a5390694e8525ac61d7377e266e31d124c815Andreas Huber 93988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 94088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 94188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 94288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 94388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 94488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 94588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 94688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 94788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 94888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 94988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 95088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 95188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 952