android_media_MediaCodec.cpp revision bfc56f497de0d18125366a02a93e61cdc0891be4
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#include <gui/SurfaceTextureClient.h> 328335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian 330e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber#include <media/ICrypto.h> 3488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaCodec.h> 3588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 3688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ADebug.h> 3788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/ALooper.h> 3888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/foundation/AMessage.h> 39bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber#include <media/stagefright/foundation/AString.h> 4088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber#include <media/stagefright/MediaErrors.h> 4188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Hubernamespace android { 4388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber// Keep these in sync with their equivalents in MediaCodec.java !!! 4588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberenum { 4688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_TRY_AGAIN_LATER = -1, 4788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED = -2, 4888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, 4988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 5088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 5188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstruct fields_t { 5288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jfieldID context; 5391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 5491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumSubSamplesID; 5591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfClearDataID; 5691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoNumBytesOfEncryptedDataID; 5791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoKeyID; 5891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoIVID; 5991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jfieldID cryptoInfoModeID; 6088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 6188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic fields_t gFields; 6388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 6588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 6688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::JMediaCodec( 6788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 6888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *name, bool nameIsType, bool encoder) 6988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mClass(NULL), 7088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject(NULL) { 7188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->GetObjectClass(thiz); 7288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 7388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = (jclass)env->NewGlobalRef(clazz); 7588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = env->NewWeakGlobalRef(thiz); 7688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 7788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper = new ALooper; 7888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->setName("MediaCodec_looper"); 7988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mLooper->start( 8188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // runOnCallingThread 8288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber false, // canCallJava 8388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber PRIORITY_DEFAULT); 8488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 8588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (nameIsType) { 8688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByType(mLooper, name, encoder); 8788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 8888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mCodec = MediaCodec::CreateByComponentName(mLooper, name); 8988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 9088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 9188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::initCheck() const { 9388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec != NULL ? OK : NO_INIT; 9488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 9588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas HuberJMediaCodec::~JMediaCodec() { 974484bdd2f99a753b0801f0c13ca8a2b7bc38695aAndreas Huber mCodec->release(); 9888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 9988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env = AndroidRuntime::getJNIEnv(); 10088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteWeakGlobalRef(mObject); 10288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mObject = NULL; 10388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteGlobalRef(mClass); 10488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber mClass = NULL; 10588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 10688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 10788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::configure( 10888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<AMessage> &format, 10988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ISurfaceTexture> &surfaceTexture, 1108240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber const sp<ICrypto> &crypto, 11188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int flags) { 11288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<SurfaceTextureClient> client; 11388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surfaceTexture != NULL) { 11488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber client = new SurfaceTextureClient(surfaceTexture); 11588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 1168240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber return mCodec->configure(format, client, crypto, flags); 11788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 11888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 11988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::start() { 12088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->start(); 12188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 12288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::stop() { 12488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->stop(); 12588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 12688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 12788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::flush() { 12888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->flush(); 12988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 13088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 13188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::queueInputBuffer( 13288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index, 133bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber size_t offset, size_t size, int64_t timeUs, uint32_t flags, 134bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 135bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return mCodec->queueInputBuffer( 136bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timeUs, flags, errorDetailMsg); 13788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 13888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 1399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatus_t JMediaCodec::queueSecureInputBuffer( 1409e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t index, 1419e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t offset, 1429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const CryptoPlugin::SubSample *subSamples, 1439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber size_t numSubSamples, 1449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t key[16], 1459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber const uint8_t iv[16], 1469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::Mode mode, 1479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber int64_t presentationTimeUs, 148bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber uint32_t flags, 149bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString *errorDetailMsg) { 1509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return mCodec->queueSecureInputBuffer( 1519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, subSamples, numSubSamples, key, iv, mode, 152bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber presentationTimeUs, flags, errorDetailMsg); 1539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 1549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 15588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 15688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return mCodec->dequeueInputBuffer(index, timeoutUs); 15788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 15888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 15988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::dequeueOutputBuffer( 16088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) { 16188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t size, offset; 16288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber int64_t timeUs; 16388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber uint32_t flags; 16488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 16588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->dequeueOutputBuffer( 166c52b980277f08aee7981b1fdbca7a89464cf66d9Andreas Huber index, &offset, &size, &timeUs, &flags, timeoutUs)) != OK) { 16788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 16888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 16988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec$BufferInfo"); 17188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jmethodID method = env->GetMethodID(clazz, "set", "(IIJI)V"); 17388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->CallVoidMethod(bufferInfo, method, offset, size, timeUs, flags); 17488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 17688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 17788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 17888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::releaseOutputBuffer(size_t index, bool render) { 17988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return render 18088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->renderOutputBufferAndRelease(index) 18188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->releaseOutputBuffer(index); 18288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 18388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 18488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getOutputFormat(JNIEnv *env, jobject *format) const { 18588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> msg; 18688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err; 18788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if ((err = mCodec->getOutputFormat(&msg)) != OK) { 18888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 18988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 19088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return ConvertMessageToMap(env, msg, format); 19288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 19388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatus_t JMediaCodec::getBuffers( 19588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, bool input, jobjectArray *bufArray) const { 19688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber Vector<sp<ABuffer> > buffers; 19788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 19888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = 19988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber input 20088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ? mCodec->getInputBuffers(&buffers) 20188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber : mCodec->getOutputBuffers(&buffers); 20288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 20488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return err; 20588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 20688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass byteBufferClass = env->FindClass("java/nio/ByteBuffer"); 20888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 20988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray = (jobjectArray)env->NewObjectArray( 21088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffers.size(), byteBufferClass, NULL); 21188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber for (size_t i = 0; i < buffers.size(); ++i) { 21388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const sp<ABuffer> &buffer = buffers.itemAt(i); 21488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 21588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject byteBuffer = 21688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->NewDirectByteBuffer( 21788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->base(), 21888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber buffer->capacity()); 21988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetObjectArrayElement( 22188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber *bufArray, i, byteBuffer); 22288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->DeleteLocalRef(byteBuffer); 22488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber byteBuffer = NULL; 22588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 22688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 22788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return OK; 22888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 22988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} // namespace android 23188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber//////////////////////////////////////////////////////////////////////////////// 23388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberusing namespace android; 23588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 23688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> setMediaCodec( 23788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { 23888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> old = (JMediaCodec *)env->GetIntField(thiz, gFields.context); 23988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec != NULL) { 24088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber codec->incStrong(thiz); 24188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 24288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (old != NULL) { 24388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber old->decStrong(thiz); 24488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 24588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->SetIntField(thiz, gFields.context, (int)codec.get()); 24688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 24788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return old; 24888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 24988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { 25188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return (JMediaCodec *)env->GetIntField(thiz, gFields.context); 25288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 25388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 25488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { 25588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env, thiz, NULL); 25688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 25788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 258bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { 259bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec$CryptoException"); 260bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(clazz != NULL); 261bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 262bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jmethodID constructID = 263bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V"); 264bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber CHECK(constructID != NULL); 265bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 266bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error"); 267bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 268bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber jthrowable exception = 269bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber (jthrowable)env->NewObject(clazz, constructID, err, msgObj); 270bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 271bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env->Throw(exception); 272bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber} 273bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 274bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huberstatic jint throwExceptionAsNecessary( 275bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber JNIEnv *env, status_t err, const char *msg = NULL) { 276bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber if (err >= ERROR_DRM_WV_VENDOR_MIN && err <= ERROR_DRM_WV_VENDOR_MAX) { 277bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber // We'll throw our custom MediaCodec.CryptoException 278bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 279bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwCryptoException(env, err, msg); 280bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber return 0; 281bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber } 282bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 28388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber switch (err) { 28488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case OK: 28588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 28688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 28788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case -EAGAIN: 28888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_TRY_AGAIN_LATER; 28988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_FORMAT_CHANGED: 29188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED; 29288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber case INFO_OUTPUT_BUFFERS_CHANGED: 29488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED; 29588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 29688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber default: 29788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { 29888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 29988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber break; 30088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 30288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return 0; 30488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 30588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 30688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_configure( 30788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 30888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 30988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray keys, jobjectArray values, 31088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject jsurface, 3118240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber jobject jcrypto, 31288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 31388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 31488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 31588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 31688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 31788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 31888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 31988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<AMessage> format; 32188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format); 32288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 32488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 32588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 32688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 32788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 32888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<ISurfaceTexture> surfaceTexture; 32988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (jsurface != NULL) { 33088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<Surface> surface(Surface_getSurface(env, jsurface)); 33188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (surface != NULL) { 33288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber surfaceTexture = surface->getSurfaceTexture(); 33388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } else { 33488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 33588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 33688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/lang/IllegalArgumentException", 33788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "The surface has been released"); 33888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 33988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 34088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 34188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 3428240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber sp<ICrypto> crypto; 3438240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber if (jcrypto != NULL) { 3448240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber crypto = JCrypto::GetCrypto(env, jcrypto); 3458240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber } 3468240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber 3478240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber err = codec->configure(format, surfaceTexture, crypto, flags); 34888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 34988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 35088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 35188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) { 35388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_start"); 35488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 35688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 35788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 35888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 35988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 36088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 36188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->start(); 36388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 36588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 36688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 36788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) { 36888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_stop"); 36988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 37188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 37388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 37488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 37588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 37688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->stop(); 37888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 37988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 38088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 38188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) { 38388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_flush"); 38488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 38688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 38788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 38888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 38988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 39088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 39188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->flush(); 39388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 39588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 39688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 39788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_queueInputBuffer( 39888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, 39988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject thiz, 40088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint index, 40188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint offset, 40288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint size, 40388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jlong timestampUs, 40488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jint flags) { 40588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_queueInputBuffer"); 40688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 40888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 40988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 41088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 41188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 41288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 41388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 414bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 415bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 41688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->queueInputBuffer( 417bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber index, offset, size, timestampUs, flags, &errorDetailMsg); 41888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 419bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 420bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 42188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 42288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 4239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huberstatic void android_media_MediaCodec_queueSecureInputBuffer( 4249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber JNIEnv *env, 4259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jobject thiz, 4269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint index, 4279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint offset, 42891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jobject cryptoInfoObj, 4299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jlong timestampUs, 4309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint flags) { 4319e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ALOGV("android_media_MediaCodec_queueSecureInputBuffer"); 4329e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 4349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (codec == NULL) { 4369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 4379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber return; 4389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 4399e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 44091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint numSubSamples = 44191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID); 44291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 44391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfClearDataObj = 44491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 44591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID); 44691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 44791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jintArray numBytesOfEncryptedDataObj = 44891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jintArray)env->GetObjectField( 44991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID); 45091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 45191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray keyObj = 45291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID); 45391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 45491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jbyteArray ivObj = 45591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber (jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID); 45691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 45791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID); 45891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 4599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber status_t err = OK; 4609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4619e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber CryptoPlugin::SubSample *subSamples = NULL; 4629e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *key = NULL; 4639e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jbyte *iv = NULL; 4649e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4659e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numSubSamples <= 0) { 4669e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 4679e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj == NULL 4689e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && numBytesOfEncryptedDataObj == NULL) { 4699e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 4709e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfEncryptedDataObj != NULL 4719e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfEncryptedDataObj) < numSubSamples) { 4729e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 4739e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else if (numBytesOfClearDataObj != NULL 4749e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber && env->GetArrayLength(numBytesOfClearDataObj) < numSubSamples) { 4759e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -ERANGE; 4769e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 4779e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 4789e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4799e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfClearData = 4809e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearDataObj == NULL) 4819e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 4829e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfClearDataObj, &isCopy); 4839e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4849e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jint *numBytesOfEncryptedData = 4859e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedDataObj == NULL) 4869e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? NULL 4879e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber : env->GetIntArrayElements(numBytesOfEncryptedDataObj, &isCopy); 4889e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4899e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = new CryptoPlugin::SubSample[numSubSamples]; 4909e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4919e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber for (jint i = 0; i < numSubSamples; ++i) { 4929e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfClearData = 4939e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfClearData == NULL) ? 0 : numBytesOfClearData[i]; 4949e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 4959e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples[i].mNumBytesOfEncryptedData = 4969e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (numBytesOfEncryptedData == NULL) 4979e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber ? 0 : numBytesOfEncryptedData[i]; 4989e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 4999e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5009e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfEncryptedData != NULL) { 5019e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 5029e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedDataObj, numBytesOfEncryptedData, 0); 5039e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfEncryptedData = NULL; 5049e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5059e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5069e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (numBytesOfClearData != NULL) { 5079e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseIntArrayElements( 5089e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearDataObj, numBytesOfClearData, 0); 5099e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber numBytesOfClearData = NULL; 5109e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5119e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5129e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5139e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && keyObj != NULL) { 5149e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(keyObj) != 16) { 5159e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 5169e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 5179e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 5189e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = env->GetByteArrayElements(keyObj, &isCopy); 5199e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5209e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5219e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5229e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK && ivObj != NULL) { 5239e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (env->GetArrayLength(ivObj) != 16) { 5249e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = -EINVAL; 5259e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } else { 5269e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber jboolean isCopy; 5279e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = env->GetByteArrayElements(ivObj, &isCopy); 5289e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5299e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5309e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 531bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber AString errorDetailMsg; 532bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber 5339e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (err == OK) { 5349e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber err = codec->queueSecureInputBuffer( 5359e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber index, offset, 5369e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples, numSubSamples, 5379e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (const uint8_t *)key, (const uint8_t *)iv, 5389e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (CryptoPlugin::Mode)mode, 539bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber timestampUs, 540bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber flags, 541bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber &errorDetailMsg); 5429e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5439e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5449e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (iv != NULL) { 5459e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(ivObj, iv, 0); 5469e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber iv = NULL; 5479e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5489e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5499e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber if (key != NULL) { 5509e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber env->ReleaseByteArrayElements(keyObj, key, 0); 5519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber key = NULL; 5529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber } 5539e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 5549e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber delete[] subSamples; 5559e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber subSamples = NULL; 5569e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 557bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber throwExceptionAsNecessary( 558bfc56f497de0d18125366a02a93e61cdc0891be4Andreas Huber env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); 5599e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber} 5609e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 56188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueInputBuffer( 56288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jlong timeoutUs) { 56388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueInputBuffer"); 56488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 56588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 56688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 56788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 56888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 56988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return -1; 57088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 57188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 57288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 57388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueInputBuffer(&index, timeoutUs); 57488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 57588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 57688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return index; 57788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 57888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 57988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 58088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 58188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 58288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jint android_media_MediaCodec_dequeueOutputBuffer( 58388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) { 58488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_dequeueOutputBuffer"); 58588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 58688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 58788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 58888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 58988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 5900e97fc248eaea7b4c95053618ddedf0af638110eAndreas Huber return 0; 59188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 59288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 59388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber size_t index; 59488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->dequeueOutputBuffer( 59588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, bufferInfo, &index, timeoutUs); 59688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 59788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 59888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return index; 59988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 60088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 60188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return throwExceptionAsNecessary(env, err); 60288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 60388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 60488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_releaseOutputBuffer( 60588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jint index, jboolean render) { 60688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease"); 60788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 60888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 60988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 61088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 61188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 61288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 61388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 61488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 61588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->releaseOutputBuffer(index, render); 61688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 61788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 61888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 61988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 62088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobject android_media_MediaCodec_getOutputFormat( 62188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 62288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getOutputFormat"); 62388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 62488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 62588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 62688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 62788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 62888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 62988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 63088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 63188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobject format; 63288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getOutputFormat(env, &format); 63388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 63488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 63588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return format; 63688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 63788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 63888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 63988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 64088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 64188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 64288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 64388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic jobjectArray android_media_MediaCodec_getBuffers( 64488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, jboolean input) { 64588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber ALOGV("android_media_MediaCodec_getBuffers"); 64688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 64788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = getMediaCodec(env, thiz); 64888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 64988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (codec == NULL) { 65088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalStateException", NULL); 65188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 65288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 65388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 65488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jobjectArray buffers; 65588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->getBuffers(env, input, &buffers); 65688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 65788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err == OK) { 65888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return buffers; 65988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 66088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 66188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber throwExceptionAsNecessary(env, err); 66288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 66388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return NULL; 66488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 66588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 66688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_init(JNIEnv *env) { 66788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jclass clazz = env->FindClass("android/media/MediaCodec"); 66888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(clazz != NULL); 66988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 67088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber gFields.context = env->GetFieldID(clazz, "mNativeContext", "I"); 67188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber CHECK(gFields.context != NULL); 67291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 67391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber clazz = env->FindClass("android/media/MediaCodec$CryptoInfo"); 67491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(clazz != NULL); 67591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 67691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumSubSamplesID = 67791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numSubSamples", "I"); 67891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumSubSamplesID != NULL); 67991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 68091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfClearDataID = 68191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numBytesOfClearData", "[I"); 68291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL); 68391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 68491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoNumBytesOfEncryptedDataID = 68591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber env->GetFieldID(clazz, "numBytesOfEncryptedData", "[I"); 68691befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL); 68791befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 68891befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoKeyID = env->GetFieldID(clazz, "key", "[B"); 68991befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoKeyID != NULL); 69091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 69191befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoIVID = env->GetFieldID(clazz, "iv", "[B"); 69291befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoIVID != NULL); 69391befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber 69491befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber gFields.cryptoInfoModeID = env->GetFieldID(clazz, "mode", "I"); 69591befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber CHECK(gFields.cryptoInfoModeID != NULL); 69688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 69788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 69888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_setup( 69988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz, 70088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jstring name, jboolean nameIsType, jboolean encoder) { 70188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (name == NULL) { 70288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 70388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 70488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 70588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber const char *tmp = env->GetStringUTFChars(name, NULL); 70788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 70888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (tmp == NULL) { 70988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 71088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 71188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder); 71388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber status_t err = codec->initCheck(); 71588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env->ReleaseStringUTFChars(name, tmp); 71788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber tmp = NULL; 71888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 71988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber if (err != OK) { 72088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber jniThrowException( 72188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber env, 72288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "java/io/IOException", 72388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "Failed to allocate component instance"); 72488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return; 72588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber } 72688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 72788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber setMediaCodec(env,thiz, codec); 72888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 72988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic void android_media_MediaCodec_native_finalize( 73188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber JNIEnv *env, jobject thiz) { 73288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber android_media_MediaCodec_release(env, thiz); 73388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 73488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberstatic JNINativeMethod gMethods[] = { 73688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "release", "()V", (void *)android_media_MediaCodec_release }, 73788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 73888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_configure", 7398240d9239d9aabed75c49f9d4d69fd8a5fe4c899Andreas Huber "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;" 74007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber "Landroid/media/MediaCrypto;I)V", 74188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_configure }, 74288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "start", "()V", (void *)android_media_MediaCodec_start }, 74488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "stop", "()V", (void *)android_media_MediaCodec_stop }, 74588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "flush", "()V", (void *)android_media_MediaCodec_flush }, 74688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 74788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "queueInputBuffer", "(IIIJI)V", 74888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_queueInputBuffer }, 74988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 75091befdc0c4710234840cdfd853e7d30e8f9de62cAndreas Huber { "queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V", 7519e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber (void *)android_media_MediaCodec_queueSecureInputBuffer }, 7529e6bcce17d13bd4f7bba5f8fbcc2e6a0d695274bAndreas Huber 75388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueInputBuffer", "(J)I", 75488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueInputBuffer }, 75588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 75688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", 75788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_dequeueOutputBuffer }, 75888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 75988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "releaseOutputBuffer", "(IZ)V", 76088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_releaseOutputBuffer }, 76188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 76288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getOutputFormat", "()Ljava/util/Map;", 76388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getOutputFormat }, 76488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 76588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;", 76688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_getBuffers }, 76788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 76888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, 76988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_setup", "(Ljava/lang/String;ZZ)V", 77188572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_setup }, 77288572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77388572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber { "native_finalize", "()V", 77488572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber (void *)android_media_MediaCodec_native_finalize }, 77588572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber}; 77688572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber 77788572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huberint register_android_media_MediaCodec(JNIEnv *env) { 77888572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber return AndroidRuntime::registerNativeMethods(env, 77988572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber "android/media/MediaCodec", gMethods, NELEM(gMethods)); 78088572f7a3e9d7ef85c26865a0150f3c2041561c2Andreas Huber} 781