android_media_MediaMuxer.cpp revision effc9b4839f3cc109fe3d8244022f3c898cd080b
168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui/* 268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * Copyright 2013, The Android Open Source Project 368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * 468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * Licensed under the Apache License, Version 2.0 (the "License"); 568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * you may not use this file except in compliance with the License. 668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * You may obtain a copy of the License at 768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * 868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * http://www.apache.org/licenses/LICENSE-2.0 968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * 1068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * Unless required by applicable law or agreed to in writing, software 1168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * distributed under the License is distributed on an "AS IS" BASIS, 1268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * See the License for the specific language governing permissions and 1468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui * limitations under the License. 1568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui */ 1668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 1768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui//#define LOG_NDEBUG 0 1868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#define LOG_TAG "MediaMuxer-JNI" 1968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include <utils/Log.h> 2068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 2168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include "android_media_Utils.h" 2268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include "android_runtime/AndroidRuntime.h" 2368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include "jni.h" 2468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include "JNIHelp.h" 2568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 2668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include <media/stagefright/foundation/ABuffer.h> 2768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include <media/stagefright/foundation/ADebug.h> 2868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include <media/stagefright/foundation/AMessage.h> 2968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui#include <media/stagefright/MediaMuxer.h> 3068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 3168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuinamespace android { 3268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 3368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistruct fields_t { 3468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jfieldID context; 3568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jmethodID arrayID; 3668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui}; 3768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 3868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic fields_t gFields; 3968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 4068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui} 4168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 4268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuiusing namespace android; 4368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 4468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic jint android_media_MediaMuxer_addTrack( 4568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui JNIEnv *env, jclass clazz, jint nativeObject, jobjectArray keys, 4668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jobjectArray values) { 4768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); 4868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (muxer == NULL) { 4968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalStateException", 5068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "Muxer was not set up correctly"); 5168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return -1; 5268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 5368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 5468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui sp<AMessage> trackformat; 5568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui status_t err = ConvertKeyValueArraysToMessage(env, keys, values, 5668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui &trackformat); 5768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (err != OK) { 5868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalArgumentException", 5968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "ConvertKeyValueArraysToMessage got an error"); 6068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return err; 6168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 6268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 6368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui // Return negative value when errors happen in addTrack. 6468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jint trackIndex = muxer->addTrack(trackformat); 6568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 6668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (trackIndex < 0) { 6768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalStateException", 6868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "Failed to add the track to the muxer"); 6968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return -1; 7068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 7168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return trackIndex; 7268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui} 7368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 7468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic void android_media_MediaMuxer_writeSampleData( 7568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui JNIEnv *env, jclass clazz, jint nativeObject, jint trackIndex, 7668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jobject byteBuf, jint offset, jint size, jlong timeUs, jint flags) { 7768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); 7868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (muxer == NULL) { 7968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalStateException", 8068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "Muxer was not set up correctly"); 8168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return; 8268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 8368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 8468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui // Try to convert the incoming byteBuffer into ABuffer 8568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui void *dst = env->GetDirectBufferAddress(byteBuf); 8668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 8768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jlong dstSize; 8868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jbyteArray byteArray = NULL; 8968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 9068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (dst == NULL) { 9168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 9268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui byteArray = 9368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui (jbyteArray)env->CallObjectMethod(byteBuf, gFields.arrayID); 9468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 9568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (byteArray == NULL) { 9668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalArgumentException", 9768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "byteArray is null"); 9868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return; 9968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 10068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 10168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jboolean isCopy; 10268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui dst = env->GetByteArrayElements(byteArray, &isCopy); 10368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 10468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui dstSize = env->GetArrayLength(byteArray); 10568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } else { 10668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui dstSize = env->GetDirectBufferCapacity(byteBuf); 10768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 10868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 10968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (dstSize < (offset + size)) { 11068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui ALOGE("writeSampleData saw wrong dstSize %lld, size %d, offset %d", 11168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui dstSize, size, offset); 11268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (byteArray != NULL) { 11368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0); 11468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 11568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalArgumentException", 11668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "sample has a wrong size"); 11768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return; 11868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 11968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 12068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui sp<ABuffer> buffer = new ABuffer((char *)dst + offset, size); 12168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 12268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui status_t err = muxer->writeSampleData(buffer, trackIndex, timeUs, flags); 12368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 12468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (byteArray != NULL) { 12568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0); 12668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 12768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 12868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (err != OK) { 12968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalStateException", 13068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "writeSampleData returned an error"); 13168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 13268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return; 13368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui} 13468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 13568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui// Constructor counterpart. 13668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic jint android_media_MediaMuxer_native_setup( 13768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui JNIEnv *env, jclass clazz, jobject fileDescriptor, 13868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jint format) { 13968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 14068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui ALOGV("native_setup: fd %d", fd); 14168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 14268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui MediaMuxer::OutputFormat fileFormat = 14368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui static_cast<MediaMuxer::OutputFormat>(format); 14468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui sp<MediaMuxer> muxer = new MediaMuxer(fd, fileFormat); 14568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui muxer->incStrong(clazz); 14668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return int(muxer.get()); 14768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui} 14868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 149effc9b4839f3cc109fe3d8244022f3c898cd080bztenghuistatic void android_media_MediaMuxer_setOrientationHint( 150effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui JNIEnv *env, jclass clazz, jint nativeObject, jint degrees) { 151effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); 152effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui if (muxer == NULL) { 153effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui jniThrowException(env, "java/lang/IllegalStateException", 154effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui "Muxer was not set up correctly"); 155effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui return; 156effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui } 157effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui status_t err = muxer->setOrientationHint(degrees); 158effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui 159effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui if (err != OK) { 160effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui jniThrowException(env, "java/lang/IllegalStateException", 161effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui "Failed to set orientation hint"); 162effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui return; 163effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui } 164effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui 165effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui} 166effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui 16768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic void android_media_MediaMuxer_start(JNIEnv *env, jclass clazz, 16868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jint nativeObject) { 16968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); 17068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (muxer == NULL) { 17168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalStateException", 17268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "Muxer was not set up correctly"); 17368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return; 17468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 17568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui status_t err = muxer->start(); 17668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 17768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (err != OK) { 17868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalStateException", 17968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "Failed to start the muxer"); 18068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return; 18168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 18268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 18368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui} 18468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 18568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic void android_media_MediaMuxer_stop(JNIEnv *env, jclass clazz, 18668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jint nativeObject) { 18768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); 18868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (muxer == NULL) { 18968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalStateException", 19068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "Muxer was not set up correctly"); 19168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return; 19268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 19368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 19468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui status_t err = muxer->stop(); 19568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 19668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (err != OK) { 19768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jniThrowException(env, "java/lang/IllegalStateException", 19868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "Failed to stop the muxer"); 19968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return; 20068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 20168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui} 20268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 20368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic void android_media_MediaMuxer_native_release( 20468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui JNIEnv *env, jclass clazz, jint nativeObject) { 20568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); 20668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui if (muxer != NULL) { 20768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui muxer->decStrong(clazz); 20868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui } 20968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui} 21068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 21168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic JNINativeMethod gMethods[] = { 21268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 21368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui { "nativeAddTrack", "(I[Ljava/lang/String;[Ljava/lang/Object;)I", 21468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui (void *)android_media_MediaMuxer_addTrack }, 21568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 216effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui { "nativeSetOrientationHint", "(II)V", 217effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui (void *)android_media_MediaMuxer_setOrientationHint}, 218effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui 21968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui { "nativeStart", "(I)V", (void *)android_media_MediaMuxer_start}, 22068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 22168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui { "nativeWriteSampleData", "(IILjava/nio/ByteBuffer;IIJI)V", 22268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui (void *)android_media_MediaMuxer_writeSampleData }, 22368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 22468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui { "nativeStop", "(I)V", (void *)android_media_MediaMuxer_stop}, 22568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 22668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui { "nativeSetup", "(Ljava/io/FileDescriptor;I)I", 22768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui (void *)android_media_MediaMuxer_native_setup }, 22868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 22968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui { "nativeRelease", "(I)V", 23068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui (void *)android_media_MediaMuxer_native_release }, 23168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 23268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui}; 23368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 23468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui// This function only registers the native methods, and is called from 23568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui// JNI_OnLoad in android_media_MediaPlayer.cpp 23668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuiint register_android_media_MediaMuxer(JNIEnv *env) { 23768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui int err = AndroidRuntime::registerNativeMethods(env, 23868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui "android/media/MediaMuxer", gMethods, NELEM(gMethods)); 23968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 24068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jclass clazz = env->FindClass("android/media/MediaMuxer"); 24168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui CHECK(clazz != NULL); 24268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 24368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui gFields.context = env->GetFieldID(clazz, "mNativeContext", "I"); 24468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui CHECK(gFields.context != NULL); 24568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 24668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui jclass byteBufClass = env->FindClass("java/nio/ByteBuffer"); 24768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui CHECK(byteBufClass != NULL); 24868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 24968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui gFields.arrayID = 25068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui env->GetMethodID(byteBufClass, "array", "()[B"); 25168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui CHECK(gFields.arrayID != NULL); 25268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui 25368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui return err; 25468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui} 255