android_media_MediaMuxer.cpp revision 656fd0402613cec0196d5e2ae0a460d044d2805b
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(
45656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat        JNIEnv *env, jclass clazz, jlong 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(
75656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat        JNIEnv *env, jclass clazz, jlong 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(
150656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat        JNIEnv *env, jclass clazz, jlong 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
167cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun Hestatic void android_media_MediaMuxer_setLocation(
168cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He        JNIEnv *env, jclass clazz, jint nativeObject, jint latitude, jint longitude) {
169cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He    MediaMuxer* muxer = reinterpret_cast<MediaMuxer *>(nativeObject);
170cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He
171cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He    status_t res = muxer->setLocation(latitude, longitude);
172cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He    if (res != OK) {
173cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He        jniThrowException(env, "java/lang/IllegalStateException",
174cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He                          "Failed to set location");
175cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He        return;
176cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He    }
177cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He}
178cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He
17968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic void android_media_MediaMuxer_start(JNIEnv *env, jclass clazz,
180656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat                                           jlong nativeObject) {
18168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
18268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    if (muxer == NULL) {
18368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        jniThrowException(env, "java/lang/IllegalStateException",
18468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui                          "Muxer was not set up correctly");
18568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        return;
18668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    }
18768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    status_t err = muxer->start();
18868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
18968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    if (err != OK) {
19068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        jniThrowException(env, "java/lang/IllegalStateException",
19168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui                          "Failed to start the muxer");
19268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        return;
19368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    }
19468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
19568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui}
19668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
19768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic void android_media_MediaMuxer_stop(JNIEnv *env, jclass clazz,
198656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat                                          jlong nativeObject) {
19968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
20068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    if (muxer == NULL) {
20168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        jniThrowException(env, "java/lang/IllegalStateException",
20268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui                          "Muxer was not set up correctly");
20368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        return;
20468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    }
20568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
20668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    status_t err = muxer->stop();
20768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
20868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    if (err != OK) {
20968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        jniThrowException(env, "java/lang/IllegalStateException",
21068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui                          "Failed to stop the muxer");
21168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        return;
21268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    }
21368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui}
21468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
21568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic void android_media_MediaMuxer_native_release(
216656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat        JNIEnv *env, jclass clazz, jlong nativeObject) {
21768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
21868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    if (muxer != NULL) {
21968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        muxer->decStrong(clazz);
22068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    }
22168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui}
22268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
22368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuistatic JNINativeMethod gMethods[] = {
22468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
225656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    { "nativeAddTrack", "(J[Ljava/lang/String;[Ljava/lang/Object;)I",
22668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        (void *)android_media_MediaMuxer_addTrack },
22768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
228656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    { "nativeSetOrientationHint", "(JI)V",
229effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui        (void *)android_media_MediaMuxer_setOrientationHint},
230effc9b4839f3cc109fe3d8244022f3c898cd080bztenghui
231656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    { "nativeSetLocation", "(JII)V",
232cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He        (void *)android_media_MediaMuxer_setLocation},
233cfd47481d1b375663d4e8e8d0c292d9001aa384bZhijun He
234656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    { "nativeStart", "(J)V", (void *)android_media_MediaMuxer_start},
23568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
236656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    { "nativeWriteSampleData", "(JILjava/nio/ByteBuffer;IIJI)V",
23768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        (void *)android_media_MediaMuxer_writeSampleData },
23868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
239656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    { "nativeStop", "(J)V", (void *)android_media_MediaMuxer_stop},
24068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
241656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    { "nativeSetup", "(Ljava/io/FileDescriptor;I)J",
24268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        (void *)android_media_MediaMuxer_native_setup },
24368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
244656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    { "nativeRelease", "(J)V",
24568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        (void *)android_media_MediaMuxer_native_release },
24668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
24768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui};
24868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
24968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui// This function only registers the native methods, and is called from
25068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui// JNI_OnLoad in android_media_MediaPlayer.cpp
25168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghuiint register_android_media_MediaMuxer(JNIEnv *env) {
25268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    int err = AndroidRuntime::registerNativeMethods(env,
25368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui                "android/media/MediaMuxer", gMethods, NELEM(gMethods));
25468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
25568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    jclass clazz = env->FindClass("android/media/MediaMuxer");
25668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    CHECK(clazz != NULL);
25768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
258656fd0402613cec0196d5e2ae0a460d044d2805bAshok Bhat    gFields.context = env->GetFieldID(clazz, "mNativeContext", "J");
25968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    CHECK(gFields.context != NULL);
26068ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
26168ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    jclass byteBufClass = env->FindClass("java/nio/ByteBuffer");
26268ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    CHECK(byteBufClass != NULL);
26368ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
26468ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    gFields.arrayID =
26568ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui        env->GetMethodID(byteBufClass, "array", "()[B");
26668ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    CHECK(gFields.arrayID != NULL);
26768ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui
26868ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui    return err;
26968ccf103a10c674f1db649bb15bb3e790bc6dad3ztenghui}
270