Commit 9364e4cf authored by Erwan Croze's avatar Erwan Croze 👋🏻
Browse files

Adding MediaCodec reset + Refactoring android_mediacodec.cpp

parent 2b8b1c13
......@@ -32,13 +32,59 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
struct AMediaCodec {
jobject jcodec;
// mediaBufferInfo Class
jmethodID _init_mediaBufferInfoClass;
// MediaCodec Class
jmethodID configure;
jmethodID reset;
jmethodID start;
jmethodID release;
jmethodID flush;
jmethodID stop;
jmethodID getInputBuffers;
jmethodID getOutputBuffers;
jmethodID dequeueInputBuffer;
jmethodID queueInputBuffer;
jmethodID dequeueOutputBuffer;
jmethodID getOutputFormat;
jmethodID getOutputImageMethod;
jmethodID getInputImageMethod;
jmethodID releaseOutputBuffer;
jmethodID setParameters;
// image Class
jmethodID getFormatMethod;
jmethodID getWidthMethod;
jmethodID getHeightMethod;
jmethodID getTimestrampMethod;
jmethodID getPlanesMethod;
jmethodID getCropRectMethod;
// plane Class
jmethodID getPixelStrideMethod;
jmethodID getRowStrideMethod;
jmethodID getBufferMethod;
// Bundle Class
jmethodID _init_BundleClass;
jmethodID putIntId;
// rect Class
jfieldID bottomField;
jfieldID leftField;
jfieldID rightField;
jfieldID topField;
// mediaBufferInfo Class
jfieldID size;
jfieldID flags;
jfieldID offset;
};
struct AMediaFormat {
jobject jformat;
// mediaFormat Class
jmethodID setInteger;
jmethodID getInteger;
jmethodID setString;
};
int handle_java_exception(){
int handle_java_exception() {
JNIEnv *env = ms_get_jni_env();
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
......@@ -48,197 +94,192 @@ int handle_java_exception(){
return 0;
}
AMediaCodec * AMediaCodec_createDecoderByType(const char *mime_type){
AMediaCodec *codec=ms_new0(AMediaCodec,1);
JNIEnv *env = ms_get_jni_env();
jobject jcodec = NULL;
static bool _loadClass(JNIEnv *env, const char *className, jclass *_class) {
*_class = env->FindClass(className);
if(handle_java_exception() == -1 || *_class == NULL) {
ms_error("Could not load Java class [%s]", className);
return false;
}
return true;
}
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return NULL;
static bool _getMethodID(JNIEnv *env, jclass _class, const char *name, const char *sig, jmethodID *method) {
*method = env->GetMethodID(_class, name, sig);
if(handle_java_exception() == -1 || *method == NULL) {
ms_error("Could not get method %s[%s]", name, sig);
return false;
}
return true;
}
jmethodID methodID = env->GetStaticMethodID(mediaCodecClass, "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;");
if (methodID != NULL){
jstring msg = env->NewStringUTF(mime_type);
jcodec = env->CallStaticObjectMethod(mediaCodecClass, methodID, msg);
handle_java_exception();
if (jcodec){
jcodec=env->NewGlobalRef(jcodec);
ms_message("Codec %s successfully created.", mime_type);
}else{
ms_error("Failed to create codec !");
return NULL;
}
env->DeleteLocalRef(msg);
}else{
ms_error("createDecoderByType() not found in class mediaCodec !");
env->ExceptionClear();
return NULL;
static bool _getStaticMethodID(JNIEnv *env, jclass _class, const char *name, const char *sig, jmethodID *method) {
*method = env->GetStaticMethodID(_class, name, sig);
if(handle_java_exception() == -1 || *method == NULL) {
ms_error("Could not get static method %s[%s]", name, sig);
return false;
}
env->DeleteLocalRef(mediaCodecClass);
codec->jcodec = jcodec;
return codec;
return true;
}
static bool _getFieldID(JNIEnv *env, jclass _class, const char *name, const char *sig, jfieldID *field) {
*field = env->GetFieldID(_class, name, sig);
if(handle_java_exception() == -1 || *field == NULL) {
ms_error("Could not get field %s[%s]", name, sig);
return false;
}
return true;
}
AMediaCodec* AMediaCodec_createEncoderByType(const char *mime_type){
AMediaCodec *codec=ms_new0(AMediaCodec,1);
bool AMediaCodec_loadMethodID(const char *createName, AMediaCodec *codec, const char *mime_type) {
JNIEnv *env = ms_get_jni_env();
jobject jcodec = NULL;
jclass mediaCodecClass = NULL, imageClass = NULL, planeClass = NULL, rectClass = NULL, mediaBufferInfoClass = NULL, BundleClass = NULL;
jmethodID createMethod = NULL;
jstring msg = NULL;
bool success = true;
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return NULL;
success &= _loadClass(env, "android/media/MediaCodec", &mediaCodecClass);
success &= _loadClass(env, "android/media/Image", &imageClass);
success &= _loadClass(env, "android/media/Image$Plane", &planeClass);
success &= _loadClass(env, "android/graphics/Rect", &rectClass);
success &= _loadClass(env, "android/media/MediaCodec$BufferInfo", &mediaBufferInfoClass);
success &= _loadClass(env, "android/os/Bundle", &BundleClass);
if (!success) {
ms_error("%s(): one class could not be found", __FUNCTION__);
goto error;
}
success &= _getStaticMethodID(env, mediaCodecClass, createName, "(Ljava/lang/String;)Landroid/media/MediaCodec;", &createMethod);
success &= _getMethodID(env, mediaCodecClass, "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", &(codec->configure));
success &= _getMethodID(env, mediaCodecClass, "reset", "()V", &(codec->reset));
success &= _getMethodID(env, mediaCodecClass, "start", "()V", &(codec->start));
success &= _getMethodID(env, mediaCodecClass, "release", "()V", &(codec->release));
success &= _getMethodID(env, mediaCodecClass, "flush", "()V", &(codec->flush));
success &= _getMethodID(env, mediaCodecClass, "stop", "()V", &(codec->stop));
success &= _getMethodID(env, mediaCodecClass, "getInputBuffers", "()[Ljava/nio/ByteBuffer;", &(codec->getInputBuffers));
success &= _getMethodID(env, mediaCodecClass, "getOutputBuffers","()[Ljava/nio/ByteBuffer;", &(codec->getOutputBuffers));
success &= _getMethodID(env, mediaCodecClass, "dequeueInputBuffer", "(J)I", &(codec->dequeueInputBuffer));
success &= _getMethodID(env, mediaCodecClass, "queueInputBuffer", "(IIIJI)V", &(codec->queueInputBuffer));
success &= _getMethodID(env, mediaCodecClass, "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", &(codec->dequeueOutputBuffer));
success &= _getMethodID(env, mediaCodecClass, "getOutputFormat", "()Landroid/media/MediaFormat;", &(codec->getOutputFormat));
success &= _getMethodID(env, mediaCodecClass, "getInputImage", "(I)Landroid/media/Image;", &(codec->getInputImageMethod));
success &= _getMethodID(env, mediaCodecClass, "getOutputImage", "(I)Landroid/media/Image;", &(codec->getOutputImageMethod));
success &= _getMethodID(env, mediaCodecClass, "releaseOutputBuffer", "(IZ)V", &(codec->releaseOutputBuffer));
success &= _getMethodID(env, mediaCodecClass, "setParameters", "(Landroid/os/Bundle;)V", &(codec->setParameters));
success &= _getMethodID(env, imageClass, "getFormat", "()I", &(codec->getFormatMethod));
success &= _getMethodID(env, imageClass, "getWidth", "()I", &(codec->getWidthMethod));
success &= _getMethodID(env, imageClass, "getHeight", "()I", &(codec->getHeightMethod));
success &= _getMethodID(env, imageClass, "getTimestamp", "()J", &(codec->getTimestrampMethod));
success &= _getMethodID(env, imageClass, "getPlanes", "()[Landroid/media/Image$Plane;", &(codec->getPlanesMethod));
success &= _getMethodID(env, imageClass, "getCropRect", "()Landroid/graphics/Rect;", &(codec->getCropRectMethod));
success &= _getMethodID(env, planeClass, "getPixelStride", "()I", &(codec->getPixelStrideMethod));
success &= _getMethodID(env, planeClass, "getRowStride", "()I", &(codec->getRowStrideMethod));
success &= _getMethodID(env, planeClass, "getBuffer", "()Ljava/nio/ByteBuffer;", &(codec->getBufferMethod));
success &= _getMethodID(env, mediaBufferInfoClass, "<init>", "()V", &(codec->_init_mediaBufferInfoClass));
success &= _getMethodID(env, BundleClass,"<init>","()V", &(codec->_init_BundleClass));
success &= _getMethodID(env, BundleClass,"putInt","(Ljava/lang/String;I)V", &(codec->putIntId));
success &= _getFieldID(env, rectClass, "bottom", "I", &(codec->bottomField));
success &= _getFieldID(env, rectClass, "left", "I", &(codec->leftField));
success &= _getFieldID(env, rectClass, "right", "I", &(codec->rightField));
success &= _getFieldID(env, rectClass, "top", "I", &(codec->topField));
success &= _getFieldID(env, mediaBufferInfoClass, "size" , "I", &(codec->size));
success &= _getFieldID(env, mediaBufferInfoClass, "flags" , "I", &(codec->flags));
success &= _getFieldID(env, mediaBufferInfoClass, "offset" , "I", &(codec->offset));
if(!success) {
ms_error("%s(): one method or field could not be found", __FUNCTION__);
goto error;
}
jmethodID methodID = env->GetStaticMethodID(mediaCodecClass, "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;");
if (methodID != NULL){
jstring msg = env->NewStringUTF(mime_type);
jcodec = env->CallStaticObjectMethod(mediaCodecClass, methodID, msg);
handle_java_exception();
if (jcodec){
jcodec=env->NewGlobalRef(jcodec);
ms_message("Codec %s successfully created.", mime_type);
}else{
ms_error("Failed to create codec !");
return NULL;
}
env->DeleteLocalRef(msg);
}else{
ms_error("createEncoderByType() not found in class MediaCodec !");
env->ExceptionClear();
return NULL;
msg = env->NewStringUTF(mime_type);
jcodec = env->CallStaticObjectMethod(mediaCodecClass, createMethod, msg);
handle_java_exception();
if (!jcodec) {
ms_error("Failed to create codec !");
goto error;
}
codec->jcodec = env->NewGlobalRef(jcodec);
ms_message("Codec %s successfully created.", mime_type);
env->DeleteLocalRef(mediaCodecClass);
codec->jcodec = jcodec;
return codec;
env->DeleteLocalRef(jcodec);
env->DeleteLocalRef(imageClass);
env->DeleteLocalRef(planeClass);
env->DeleteLocalRef(rectClass);
env->DeleteLocalRef(BundleClass);
env->DeleteLocalRef(msg);
return true;
error:
if (mediaCodecClass) env->DeleteLocalRef(mediaCodecClass);
if (jcodec) env->DeleteLocalRef(jcodec);
if (imageClass) env->DeleteLocalRef(imageClass);
if (planeClass) env->DeleteLocalRef(planeClass);
if (rectClass) env->DeleteLocalRef(rectClass);
if (BundleClass) env->DeleteLocalRef(BundleClass);
if (msg) env->DeleteLocalRef(msg);
return false;
}
media_status_t AMediaCodec_configure(AMediaCodec *codec, const AMediaFormat* format, ANativeWindow* surface, AMediaCrypto *crypto, uint32_t flags){
JNIEnv *env = ms_get_jni_env();
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return AMEDIA_ERROR_BASE;
AMediaCodec * AMediaCodec_createDecoderByType(const char *mime_type) {
AMediaCodec *codec = ms_new0(AMediaCodec, 1);
if (!AMediaCodec_loadMethodID("createDecoderByType", codec, mime_type)) {
ms_free(codec);
codec = NULL;
}
return codec;
}
jmethodID methodID = env->GetMethodID(mediaCodecClass, "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V");
if (methodID != NULL){
env->CallVoidMethod(codec->jcodec, methodID, format->jformat, NULL, NULL, flags);
if(handle_java_exception() == -1){
return AMEDIA_ERROR_BASE;
}
} else {
ms_error("configure() not found in class MediaCodec !");
env->ExceptionClear();
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_ERROR_BASE;
AMediaCodec* AMediaCodec_createEncoderByType(const char *mime_type) {
AMediaCodec *codec = ms_new0(AMediaCodec, 1);
if (!AMediaCodec_loadMethodID("createEncoderByType", codec, mime_type)) {
ms_free(codec);
codec = NULL;
}
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_OK;
return codec;
}
media_status_t AMediaCodec_delete(AMediaCodec *codec){
media_status_t AMediaCodec_configure(AMediaCodec *codec, const AMediaFormat* format, ANativeWindow* surface, AMediaCrypto *crypto, uint32_t flags) {
JNIEnv *env = ms_get_jni_env();
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return AMEDIA_ERROR_BASE;
}
jmethodID methodID = env->GetMethodID(mediaCodecClass, "release","()V");
if (methodID != NULL){
env->CallVoidMethod(codec->jcodec, methodID);
handle_java_exception();
} else {
ms_error("release() not found in class MediaCodec !");
env->ExceptionClear();
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_ERROR_BASE;
}
env->DeleteLocalRef(mediaCodecClass);
env->CallVoidMethod(codec->jcodec, codec->configure, format->jformat, NULL, NULL, flags);
return (handle_java_exception() == -1) ? AMEDIA_ERROR_BASE : AMEDIA_OK;
}
media_status_t AMediaCodec_delete(AMediaCodec *codec) {
JNIEnv *env = ms_get_jni_env();
env->CallVoidMethod(codec->jcodec, codec->release);
env->DeleteGlobalRef(codec->jcodec);
return AMEDIA_OK;
ms_free(codec);
return (handle_java_exception() == -1) ? AMEDIA_ERROR_BASE : AMEDIA_OK;
}
media_status_t AMediaCodec_start(AMediaCodec *codec){
media_status_t AMediaCodec_start(AMediaCodec *codec) {
JNIEnv *env = ms_get_jni_env();
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return AMEDIA_ERROR_BASE;
}
jmethodID methodID = env->GetMethodID(mediaCodecClass, "start", "()V");
if (methodID != NULL){
env->CallVoidMethod(codec->jcodec, methodID);
if (handle_java_exception()==-1) {
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_ERROR_BASE;
}
} else {
ms_error("start() not found in class MediaCodec !");
env->ExceptionClear();
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_ERROR_BASE;
}
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_OK;
env->CallVoidMethod(codec->jcodec, codec->start);
return (handle_java_exception() == -1) ? AMEDIA_ERROR_BASE : AMEDIA_OK;
}
media_status_t AMediaCodec_flush(AMediaCodec *codec){
media_status_t AMediaCodec_flush(AMediaCodec *codec) {
JNIEnv *env = ms_get_jni_env();
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return AMEDIA_ERROR_BASE;
}
jmethodID methodID = env->GetMethodID(mediaCodecClass, "flush", "()V");
if (methodID != NULL){
env->CallVoidMethod(codec->jcodec, methodID);
handle_java_exception();
} else {
ms_error("stop() not found in class MediaCodec !");
env->ExceptionClear();
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_ERROR_BASE;
}
env->CallVoidMethod(codec->jcodec, codec->flush);
handle_java_exception();
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_OK;
}
media_status_t AMediaCodec_stop(AMediaCodec *codec){
media_status_t AMediaCodec_stop(AMediaCodec *codec) {
JNIEnv *env = ms_get_jni_env();
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return AMEDIA_ERROR_BASE;
}
jmethodID methodID = env->GetMethodID(mediaCodecClass, "stop", "()V");
if (methodID != NULL){
env->CallVoidMethod(codec->jcodec, methodID);
handle_java_exception();
} else {
ms_error("stop() not found in class MediaCodec !");
env->ExceptionClear();
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_ERROR_BASE;
}
env->CallVoidMethod(codec->jcodec, codec->stop);
env->DeleteLocalRef(mediaCodecClass);
return AMEDIA_OK;
return (handle_java_exception() == -1) ? AMEDIA_ERROR_BASE : AMEDIA_OK;
}
......@@ -270,37 +311,25 @@ media_status_t AMediaCodec_stop(AMediaCodec *codec){
}*/
//API 19
uint8_t* AMediaCodec_getInputBuffer(AMediaCodec *codec, size_t idx, size_t *out_size){
uint8_t* AMediaCodec_getInputBuffer(AMediaCodec *codec, size_t idx, size_t *out_size) {
JNIEnv *env = ms_get_jni_env();
jobject object;
jobject object = NULL;
uint8_t *buf = NULL;
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return NULL;
}
jmethodID methodID = env->GetMethodID(mediaCodecClass,"getInputBuffers","()[Ljava/nio/ByteBuffer;");
if (methodID != NULL){
object = env->CallObjectMethod(codec->jcodec, methodID);
handle_java_exception();
if(object != NULL){
jobjectArray jbuffers = reinterpret_cast<jobjectArray>(object);
jobject jbuf = env->GetObjectArrayElement(jbuffers,idx);
jlong capacity = env->GetDirectBufferCapacity(jbuf);
*out_size = (size_t) capacity;
buf = (uint8_t *) env->GetDirectBufferAddress(jbuf);
env->DeleteLocalRef(jbuf);
env->DeleteLocalRef(object);
}
object = env->CallObjectMethod(codec->jcodec, codec->getInputBuffers);
if(object != NULL){
jobjectArray jbuffers = reinterpret_cast<jobjectArray>(object);
jobject jbuf = env->GetObjectArrayElement(jbuffers,idx);
jlong capacity = env->GetDirectBufferCapacity(jbuf);
*out_size = (size_t) capacity;
buf = (uint8_t *) env->GetDirectBufferAddress(jbuf);
env->DeleteLocalRef(jbuf);
env->DeleteLocalRef(object);
} else {
ms_error("getInputBuffers() not found in class mediacodec !");
env->ExceptionClear();
env->DeleteLocalRef(mediaCodecClass);
return NULL;
ms_error("getInputBuffers() not found in class mediacodec !");
env->ExceptionClear();
}
env->DeleteLocalRef(mediaCodecClass);
handle_java_exception();
return buf;
}
......@@ -331,389 +360,222 @@ uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *codec, size_t idx, size_t *out
return buf;
}*/
uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *codec, size_t idx, size_t *out_size){
uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec *codec, size_t idx, size_t *out_size) {
JNIEnv *env = ms_get_jni_env();
jobject object;
jobject object = NULL;
uint8_t *buf = NULL;
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return NULL;
}
jmethodID methodID = env->GetMethodID(mediaCodecClass,"getOutputBuffers","()[Ljava/nio/ByteBuffer;");
if (methodID != NULL){
object = env->CallObjectMethod(codec->jcodec, methodID);
handle_java_exception();
if(object != NULL){
jobjectArray jbuffers = reinterpret_cast<jobjectArray>(object);
jobject jbuf = env->GetObjectArrayElement(jbuffers,idx);
buf = (uint8_t *) env->GetDirectBufferAddress(jbuf);
env->DeleteLocalRef(jbuf);
env->DeleteLocalRef(object);
}
object = env->CallObjectMethod(codec->jcodec, codec->getOutputBuffers);
if(object != NULL){
jobjectArray jbuffers = reinterpret_cast<jobjectArray>(object);
jobject jbuf = env->GetObjectArrayElement(jbuffers, idx);
buf = (uint8_t *) env->GetDirectBufferAddress(jbuf);
env->DeleteLocalRef(jbuf);
env->DeleteLocalRef(object);
} else {
ms_error("getOutputBuffers() not found in class mediacodec !");
env->ExceptionClear();
env->DeleteLocalRef(mediaCodecClass);
return NULL;
ms_error("getOutputBuffer() not found in class mediacodec !");
env->ExceptionClear();
}
env->DeleteLocalRef(mediaCodecClass);
handle_java_exception();
return buf;
}
ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec *codec, int64_t timeoutUs){
ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec *codec, int64_t timeoutUs) {
JNIEnv *env = ms_get_jni_env();
jint jindex=-1;
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return -1;
}
jint jindex = -1;
jmethodID methodID = env->GetMethodID(mediaCodecClass,"dequeueInputBuffer","(J)I");
if (methodID != NULL){
jindex = env->CallIntMethod(codec->jcodec, methodID, timeoutUs);
if (handle_java_exception() == -1) jindex = AMEDIA_ERROR_UNKNOWN; /*return value to notify the exception*/
/*otherwise, if -1 is returned as index, it just means that no buffer are available at this time (not an error)*/
} else {
ms_error("dequeueInputBuffer() not found in class mediacodec !");
env->ExceptionClear();
jindex = -1;
}
env->DeleteLocalRef(mediaCodecClass);
return (ssize_t) jindex;
jindex = env->CallIntMethod(codec->jcodec, codec->dequeueInputBuffer, timeoutUs);
/*return value to notify the exception*/
/*otherwise, if -1 is returned as index, it just means that no buffer are available at this time (not an error)*/
return (handle_java_exception() == -1) ? AMEDIA_ERROR_UNKNOWN : (ssize_t) jindex;
}
media_status_t AMediaCodec_queueInputBuffer(AMediaCodec *codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags){
JNIEnv *env = ms_get_jni_env();
media_status_t ret = AMEDIA_OK;
jclass mediaCodecClass = env->FindClass("android/media/MediaCodec");
if (mediaCodecClass == NULL){
ms_error("Couldn't find android/media/MediaCodec class !");
env->ExceptionClear();
return AMEDIA_ERROR_BASE;
}
media_status_t AMediaCodec_queueInputBuffer(AMediaCodec *codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags) {
JNIEnv *env = ms_get_jni_env();
jmethodID methodID = env->GetMethodID(mediaCodecClass,"queueInputBuffer","(IIIJI)V");
if (methodID != NULL){
env->CallVoidMethod(codec->jcodec, methodID, idx, offset, size, time, flags);
if (handle_java_exception() == -1){
ret = AMEDIA_ERROR_BASE;
}
} else {
ms_error("queueInputBuffer() not found in class mediacodec !");
env->ExceptionClear();
ret = AMEDIA_ERROR_BASE;
}
env->DeleteLocalRef(mediaCodecClass);
return ret;
env->CallVoidMethod(codec->jcodec, codec->queueInputBuffer, idx, offset, size, time, flags);
return (handle_java_exception() == -1) ? AMEDIA_ERROR_BASE : AMEDIA_OK;
}
ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec *codec, AMediaCodecBufferInfo *info, int64_t timeoutUs) {
JNIEnv *env = ms_get_jni_env();
jint jindex=-1;
jint jindex = -1;
jobject jinfo = NULL;
jclass mediaBufferInfoClass;
jfieldID size;
jfieldID offset;
jfieldID flags;
jclass mediaBufferInfoClass = env->FindClass("android/media/MediaCodec$BufferInfo");
jmethodID methodID = env->GetMethodID(mediaBufferInfoClass,"<init>","()V");
if (methodID != NULL){
jinfo = env->NewObject(mediaBufferInfoClass,methodID);
size = env->GetFieldID(mediaBufferInfoClass, "size" , "I");
flags = env->GetFieldID(mediaBufferInfoClass, "flags" , "I");
offset = env->GetFieldID(mediaBufferInfoClass, "offset" , "I");
handle_java_exception();
} else {
ms_error("init not found in class MediaCodec$BufferInfo !");