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