android_media_MediaRecorder.cpp revision e176ee1222931d67aaea0a3df96262728cc31031
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <assert.h> 18#include <fcntl.h> 19#include <inttypes.h> 20#include <limits.h> 21#include <stdio.h> 22#include <unistd.h> 23 24//#define LOG_NDEBUG 0 25#define LOG_TAG "MediaRecorderJNI" 26#include <utils/Log.h> 27 28#include <gui/Surface.h> 29#include <camera/Camera.h> 30#include <media/mediarecorder.h> 31#include <media/stagefright/PersistentSurface.h> 32#include <utils/threads.h> 33 34#include <ScopedUtfChars.h> 35 36#include "jni.h" 37#include "JNIHelp.h" 38#include "android_runtime/AndroidRuntime.h" 39 40#include <system/audio.h> 41#include <android_runtime/android_view_Surface.h> 42 43// ---------------------------------------------------------------------------- 44 45using namespace android; 46 47// ---------------------------------------------------------------------------- 48 49// helper function to extract a native Camera object from a Camera Java object 50extern sp<Camera> get_native_camera(JNIEnv *env, jobject thiz, struct JNICameraContext** context); 51extern sp<PersistentSurface> 52android_media_MediaCodec_getPersistentInputSurface(JNIEnv* env, jobject object); 53 54struct fields_t { 55 jfieldID context; 56 jfieldID surface; 57 58 jmethodID post_event; 59}; 60static fields_t fields; 61 62static Mutex sLock; 63 64// ---------------------------------------------------------------------------- 65// ref-counted object for callbacks 66class JNIMediaRecorderListener: public MediaRecorderListener 67{ 68public: 69 JNIMediaRecorderListener(JNIEnv* env, jobject thiz, jobject weak_thiz); 70 ~JNIMediaRecorderListener(); 71 void notify(int msg, int ext1, int ext2); 72private: 73 JNIMediaRecorderListener(); 74 jclass mClass; // Reference to MediaRecorder class 75 jobject mObject; // Weak ref to MediaRecorder Java object to call on 76}; 77 78JNIMediaRecorderListener::JNIMediaRecorderListener(JNIEnv* env, jobject thiz, jobject weak_thiz) 79{ 80 81 // Hold onto the MediaRecorder class for use in calling the static method 82 // that posts events to the application thread. 83 jclass clazz = env->GetObjectClass(thiz); 84 if (clazz == NULL) { 85 ALOGE("Can't find android/media/MediaRecorder"); 86 jniThrowException(env, "java/lang/Exception", NULL); 87 return; 88 } 89 mClass = (jclass)env->NewGlobalRef(clazz); 90 91 // We use a weak reference so the MediaRecorder object can be garbage collected. 92 // The reference is only used as a proxy for callbacks. 93 mObject = env->NewGlobalRef(weak_thiz); 94} 95 96JNIMediaRecorderListener::~JNIMediaRecorderListener() 97{ 98 // remove global references 99 JNIEnv *env = AndroidRuntime::getJNIEnv(); 100 env->DeleteGlobalRef(mObject); 101 env->DeleteGlobalRef(mClass); 102} 103 104void JNIMediaRecorderListener::notify(int msg, int ext1, int ext2) 105{ 106 ALOGV("JNIMediaRecorderListener::notify"); 107 108 JNIEnv *env = AndroidRuntime::getJNIEnv(); 109 env->CallStaticVoidMethod(mClass, fields.post_event, mObject, msg, ext1, ext2, NULL); 110} 111 112// ---------------------------------------------------------------------------- 113 114static sp<Surface> get_surface(JNIEnv* env, jobject clazz) 115{ 116 ALOGV("get_surface"); 117 return android_view_Surface_getSurface(env, clazz); 118} 119 120static sp<PersistentSurface> get_persistentSurface(JNIEnv* env, jobject object) 121{ 122 ALOGV("get_persistentSurface"); 123 return android_media_MediaCodec_getPersistentInputSurface(env, object); 124} 125 126// Returns true if it throws an exception. 127static bool process_media_recorder_call(JNIEnv *env, status_t opStatus, const char* exception, const char* message) 128{ 129 ALOGV("process_media_recorder_call"); 130 if (opStatus == (status_t)INVALID_OPERATION) { 131 jniThrowException(env, "java/lang/IllegalStateException", NULL); 132 return true; 133 } else if (opStatus != (status_t)OK) { 134 jniThrowException(env, exception, message); 135 return true; 136 } 137 return false; 138} 139 140static sp<MediaRecorder> getMediaRecorder(JNIEnv* env, jobject thiz) 141{ 142 Mutex::Autolock l(sLock); 143 MediaRecorder* const p = (MediaRecorder*)env->GetLongField(thiz, fields.context); 144 return sp<MediaRecorder>(p); 145} 146 147static sp<MediaRecorder> setMediaRecorder(JNIEnv* env, jobject thiz, const sp<MediaRecorder>& recorder) 148{ 149 Mutex::Autolock l(sLock); 150 sp<MediaRecorder> old = (MediaRecorder*)env->GetLongField(thiz, fields.context); 151 if (recorder.get()) { 152 recorder->incStrong(thiz); 153 } 154 if (old != 0) { 155 old->decStrong(thiz); 156 } 157 env->SetLongField(thiz, fields.context, (jlong)recorder.get()); 158 return old; 159} 160 161 162static void android_media_MediaRecorder_setCamera(JNIEnv* env, jobject thiz, jobject camera) 163{ 164 // we should not pass a null camera to get_native_camera() call. 165 if (camera == NULL) { 166 jniThrowNullPointerException(env, "camera object is a NULL pointer"); 167 return; 168 } 169 sp<Camera> c = get_native_camera(env, camera, NULL); 170 if (c == NULL) { 171 // get_native_camera will throw an exception in this case 172 return; 173 } 174 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 175 if (mr == NULL) { 176 jniThrowException(env, "java/lang/IllegalStateException", NULL); 177 return; 178 } 179 process_media_recorder_call(env, mr->setCamera(c->remote(), c->getRecordingProxy()), 180 "java/lang/RuntimeException", "setCamera failed."); 181} 182 183static void 184android_media_MediaRecorder_setVideoSource(JNIEnv *env, jobject thiz, jint vs) 185{ 186 ALOGV("setVideoSource(%d)", vs); 187 if (vs < VIDEO_SOURCE_DEFAULT || vs >= VIDEO_SOURCE_LIST_END) { 188 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video source"); 189 return; 190 } 191 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 192 if (mr == NULL) { 193 jniThrowException(env, "java/lang/IllegalStateException", NULL); 194 return; 195 } 196 process_media_recorder_call(env, mr->setVideoSource(vs), "java/lang/RuntimeException", "setVideoSource failed."); 197} 198 199static void 200android_media_MediaRecorder_setAudioSource(JNIEnv *env, jobject thiz, jint as) 201{ 202 ALOGV("setAudioSource(%d)", as); 203 if (as < AUDIO_SOURCE_DEFAULT || 204 (as >= AUDIO_SOURCE_CNT && as != AUDIO_SOURCE_FM_TUNER)) { 205 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid audio source"); 206 return; 207 } 208 209 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 210 if (mr == NULL) { 211 jniThrowException(env, "java/lang/IllegalStateException", NULL); 212 return; 213 } 214 process_media_recorder_call(env, mr->setAudioSource(as), "java/lang/RuntimeException", "setAudioSource failed."); 215} 216 217static void 218android_media_MediaRecorder_setOutputFormat(JNIEnv *env, jobject thiz, jint of) 219{ 220 ALOGV("setOutputFormat(%d)", of); 221 if (of < OUTPUT_FORMAT_DEFAULT || of >= OUTPUT_FORMAT_LIST_END) { 222 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid output format"); 223 return; 224 } 225 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 226 if (mr == NULL) { 227 jniThrowException(env, "java/lang/IllegalStateException", NULL); 228 return; 229 } 230 process_media_recorder_call(env, mr->setOutputFormat(of), "java/lang/RuntimeException", "setOutputFormat failed."); 231} 232 233static void 234android_media_MediaRecorder_setVideoEncoder(JNIEnv *env, jobject thiz, jint ve) 235{ 236 ALOGV("setVideoEncoder(%d)", ve); 237 if (ve < VIDEO_ENCODER_DEFAULT || ve >= VIDEO_ENCODER_LIST_END) { 238 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video encoder"); 239 return; 240 } 241 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 242 if (mr == NULL) { 243 jniThrowException(env, "java/lang/IllegalStateException", NULL); 244 return; 245 } 246 process_media_recorder_call(env, mr->setVideoEncoder(ve), "java/lang/RuntimeException", "setVideoEncoder failed."); 247} 248 249static void 250android_media_MediaRecorder_setAudioEncoder(JNIEnv *env, jobject thiz, jint ae) 251{ 252 ALOGV("setAudioEncoder(%d)", ae); 253 if (ae < AUDIO_ENCODER_DEFAULT || ae >= AUDIO_ENCODER_LIST_END) { 254 jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid audio encoder"); 255 return; 256 } 257 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 258 if (mr == NULL) { 259 jniThrowException(env, "java/lang/IllegalStateException", NULL); 260 return; 261 } 262 process_media_recorder_call(env, mr->setAudioEncoder(ae), "java/lang/RuntimeException", "setAudioEncoder failed."); 263} 264 265static void 266android_media_MediaRecorder_setParameter(JNIEnv *env, jobject thiz, jstring params) 267{ 268 ALOGV("setParameter()"); 269 if (params == NULL) 270 { 271 ALOGE("Invalid or empty params string. This parameter will be ignored."); 272 return; 273 } 274 275 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 276 if (mr == NULL) { 277 jniThrowException(env, "java/lang/IllegalStateException", NULL); 278 return; 279 } 280 281 const char* params8 = env->GetStringUTFChars(params, NULL); 282 if (params8 == NULL) 283 { 284 ALOGE("Failed to covert jstring to String8. This parameter will be ignored."); 285 return; 286 } 287 288 process_media_recorder_call(env, mr->setParameters(String8(params8)), "java/lang/RuntimeException", "setParameter failed."); 289 env->ReleaseStringUTFChars(params,params8); 290} 291 292static void 293android_media_MediaRecorder_setOutputFileFD(JNIEnv *env, jobject thiz, jobject fileDescriptor) 294{ 295 ALOGV("setOutputFile"); 296 if (fileDescriptor == NULL) { 297 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 298 return; 299 } 300 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 301 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 302 if (mr == NULL) { 303 jniThrowException(env, "java/lang/IllegalStateException", NULL); 304 return; 305 } 306 status_t opStatus = mr->setOutputFile(fd); 307 process_media_recorder_call(env, opStatus, "java/io/IOException", "setOutputFile failed."); 308} 309 310static void 311android_media_MediaRecorder_setNextOutputFileFD(JNIEnv *env, jobject thiz, jobject fileDescriptor) 312{ 313 ALOGV("setNextOutputFile"); 314 if (fileDescriptor == NULL) { 315 jniThrowException(env, "java/lang/IllegalArgumentException", NULL); 316 return; 317 } 318 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); 319 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 320 if (mr == NULL) { 321 jniThrowException(env, "java/lang/IllegalStateException", NULL); 322 return; 323 } 324 status_t opStatus = mr->setNextOutputFile(fd); 325 process_media_recorder_call(env, opStatus, "java/io/IOException", "setOutputFile failed."); 326} 327 328static void 329android_media_MediaRecorder_setVideoSize(JNIEnv *env, jobject thiz, jint width, jint height) 330{ 331 ALOGV("setVideoSize(%d, %d)", width, height); 332 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 333 if (mr == NULL) { 334 jniThrowException(env, "java/lang/IllegalStateException", NULL); 335 return; 336 } 337 338 if (width <= 0 || height <= 0) { 339 jniThrowException(env, "java/lang/IllegalArgumentException", "invalid video size"); 340 return; 341 } 342 process_media_recorder_call(env, mr->setVideoSize(width, height), "java/lang/RuntimeException", "setVideoSize failed."); 343} 344 345static void 346android_media_MediaRecorder_setVideoFrameRate(JNIEnv *env, jobject thiz, jint rate) 347{ 348 ALOGV("setVideoFrameRate(%d)", rate); 349 if (rate <= 0) { 350 jniThrowException(env, "java/lang/IllegalArgumentException", "invalid frame rate"); 351 return; 352 } 353 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 354 if (mr == NULL) { 355 jniThrowException(env, "java/lang/IllegalStateException", NULL); 356 return; 357 } 358 process_media_recorder_call(env, mr->setVideoFrameRate(rate), "java/lang/RuntimeException", "setVideoFrameRate failed."); 359} 360 361static void 362android_media_MediaRecorder_setMaxDuration(JNIEnv *env, jobject thiz, jint max_duration_ms) 363{ 364 ALOGV("setMaxDuration(%d)", max_duration_ms); 365 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 366 if (mr == NULL) { 367 jniThrowException(env, "java/lang/IllegalStateException", NULL); 368 return; 369 } 370 371 char params[64]; 372 sprintf(params, "max-duration=%d", max_duration_ms); 373 374 process_media_recorder_call(env, mr->setParameters(String8(params)), "java/lang/RuntimeException", "setMaxDuration failed."); 375} 376 377static void 378android_media_MediaRecorder_setMaxFileSize( 379 JNIEnv *env, jobject thiz, jlong max_filesize_bytes) 380{ 381 ALOGV("setMaxFileSize(%lld)", (long long)max_filesize_bytes); 382 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 383 if (mr == NULL) { 384 jniThrowException(env, "java/lang/IllegalStateException", NULL); 385 return; 386 } 387 388 char params[64]; 389 sprintf(params, "max-filesize=%" PRId64, max_filesize_bytes); 390 391 process_media_recorder_call(env, mr->setParameters(String8(params)), "java/lang/RuntimeException", "setMaxFileSize failed."); 392} 393 394static void 395android_media_MediaRecorder_prepare(JNIEnv *env, jobject thiz) 396{ 397 ALOGV("prepare"); 398 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 399 if (mr == NULL) { 400 jniThrowException(env, "java/lang/IllegalStateException", NULL); 401 return; 402 } 403 404 jobject surface = env->GetObjectField(thiz, fields.surface); 405 if (surface != NULL) { 406 const sp<Surface> native_surface = get_surface(env, surface); 407 408 // The application may misbehave and 409 // the preview surface becomes unavailable 410 if (native_surface.get() == 0) { 411 ALOGE("Application lost the surface"); 412 jniThrowException(env, "java/io/IOException", "invalid preview surface"); 413 return; 414 } 415 416 ALOGI("prepare: surface=%p", native_surface.get()); 417 if (process_media_recorder_call(env, mr->setPreviewSurface(native_surface->getIGraphicBufferProducer()), "java/lang/RuntimeException", "setPreviewSurface failed.")) { 418 return; 419 } 420 } 421 process_media_recorder_call(env, mr->prepare(), "java/io/IOException", "prepare failed."); 422} 423 424static jint 425android_media_MediaRecorder_native_getMaxAmplitude(JNIEnv *env, jobject thiz) 426{ 427 ALOGV("getMaxAmplitude"); 428 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 429 if (mr == NULL) { 430 jniThrowException(env, "java/lang/IllegalStateException", NULL); 431 return 0; 432 } 433 int result = 0; 434 process_media_recorder_call(env, mr->getMaxAmplitude(&result), "java/lang/RuntimeException", "getMaxAmplitude failed."); 435 return (jint) result; 436} 437 438static jobject 439android_media_MediaRecorder_getSurface(JNIEnv *env, jobject thiz) 440{ 441 ALOGV("getSurface"); 442 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 443 if (mr == NULL) { 444 jniThrowException(env, "java/lang/IllegalStateException", NULL); 445 return NULL; 446 } 447 448 sp<IGraphicBufferProducer> bufferProducer = mr->querySurfaceMediaSourceFromMediaServer(); 449 if (bufferProducer == NULL) { 450 jniThrowException( 451 env, 452 "java/lang/IllegalStateException", 453 "failed to get surface"); 454 return NULL; 455 } 456 457 // Wrap the IGBP in a Java-language Surface. 458 return android_view_Surface_createFromIGraphicBufferProducer(env, 459 bufferProducer); 460} 461 462static void 463android_media_MediaRecorder_start(JNIEnv *env, jobject thiz) 464{ 465 ALOGV("start"); 466 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 467 if (mr == NULL) { 468 jniThrowException(env, "java/lang/IllegalStateException", NULL); 469 return; 470 } 471 process_media_recorder_call(env, mr->start(), "java/lang/RuntimeException", "start failed."); 472} 473 474static void 475android_media_MediaRecorder_stop(JNIEnv *env, jobject thiz) 476{ 477 ALOGV("stop"); 478 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 479 if (mr == NULL) { 480 jniThrowException(env, "java/lang/IllegalStateException", NULL); 481 return; 482 } 483 process_media_recorder_call(env, mr->stop(), "java/lang/RuntimeException", "stop failed."); 484} 485 486static void 487android_media_MediaRecorder_pause(JNIEnv *env, jobject thiz) 488{ 489 ALOGV("pause"); 490 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 491 if (mr == NULL) { 492 jniThrowException(env, "java/lang/IllegalStateException", NULL); 493 return; 494 } 495 process_media_recorder_call(env, mr->pause(), "java/lang/RuntimeException", "pause failed."); 496} 497 498static void 499android_media_MediaRecorder_resume(JNIEnv *env, jobject thiz) 500{ 501 ALOGV("resume"); 502 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 503 if (mr == NULL) { 504 jniThrowException(env, "java/lang/IllegalStateException", NULL); 505 return; 506 } 507 process_media_recorder_call(env, mr->resume(), "java/lang/RuntimeException", "resume failed."); 508} 509 510static void 511android_media_MediaRecorder_native_reset(JNIEnv *env, jobject thiz) 512{ 513 ALOGV("native_reset"); 514 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 515 if (mr == NULL) { 516 jniThrowException(env, "java/lang/IllegalStateException", NULL); 517 return; 518 } 519 process_media_recorder_call(env, mr->reset(), "java/lang/RuntimeException", "native_reset failed."); 520} 521 522static void 523android_media_MediaRecorder_release(JNIEnv *env, jobject thiz) 524{ 525 ALOGV("release"); 526 sp<MediaRecorder> mr = setMediaRecorder(env, thiz, 0); 527 if (mr != NULL) { 528 mr->setListener(NULL); 529 mr->release(); 530 } 531} 532 533// This function gets some field IDs, which in turn causes class initialization. 534// It is called from a static block in MediaRecorder, which won't run until the 535// first time an instance of this class is used. 536static void 537android_media_MediaRecorder_native_init(JNIEnv *env) 538{ 539 jclass clazz; 540 541 clazz = env->FindClass("android/media/MediaRecorder"); 542 if (clazz == NULL) { 543 return; 544 } 545 546 fields.context = env->GetFieldID(clazz, "mNativeContext", "J"); 547 if (fields.context == NULL) { 548 return; 549 } 550 551 fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;"); 552 if (fields.surface == NULL) { 553 return; 554 } 555 556 jclass surface = env->FindClass("android/view/Surface"); 557 if (surface == NULL) { 558 return; 559 } 560 561 fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative", 562 "(Ljava/lang/Object;IIILjava/lang/Object;)V"); 563 if (fields.post_event == NULL) { 564 return; 565 } 566} 567 568 569static void 570android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, 571 jstring packageName, jstring opPackageName) 572{ 573 ALOGV("setup"); 574 575 ScopedUtfChars opPackageNameStr(env, opPackageName); 576 577 sp<MediaRecorder> mr = new MediaRecorder(String16(opPackageNameStr.c_str())); 578 if (mr == NULL) { 579 jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); 580 return; 581 } 582 if (mr->initCheck() != NO_ERROR) { 583 jniThrowException(env, "java/lang/RuntimeException", "Unable to initialize media recorder"); 584 return; 585 } 586 587 // create new listener and give it to MediaRecorder 588 sp<JNIMediaRecorderListener> listener = new JNIMediaRecorderListener(env, thiz, weak_this); 589 mr->setListener(listener); 590 591 // Convert client name jstring to String16 592 const char16_t *rawClientName = reinterpret_cast<const char16_t*>( 593 env->GetStringChars(packageName, NULL)); 594 jsize rawClientNameLen = env->GetStringLength(packageName); 595 String16 clientName(rawClientName, rawClientNameLen); 596 env->ReleaseStringChars(packageName, 597 reinterpret_cast<const jchar*>(rawClientName)); 598 599 // pass client package name for permissions tracking 600 mr->setClientName(clientName); 601 602 setMediaRecorder(env, thiz, mr); 603} 604 605static void 606android_media_MediaRecorder_native_finalize(JNIEnv *env, jobject thiz) 607{ 608 ALOGV("finalize"); 609 android_media_MediaRecorder_release(env, thiz); 610} 611 612void android_media_MediaRecorder_setInputSurface( 613 JNIEnv* env, jobject thiz, jobject object) { 614 ALOGV("android_media_MediaRecorder_setInputSurface"); 615 616 sp<MediaRecorder> mr = getMediaRecorder(env, thiz); 617 if (mr == NULL) { 618 jniThrowException(env, "java/lang/IllegalStateException", NULL); 619 return; 620 } 621 622 sp<PersistentSurface> persistentSurface = get_persistentSurface(env, object); 623 624 process_media_recorder_call(env, mr->setInputSurface(persistentSurface), 625 "java/lang/IllegalArgumentException", "native_setInputSurface failed."); 626} 627 628// ---------------------------------------------------------------------------- 629 630static const JNINativeMethod gMethods[] = { 631 {"setCamera", "(Landroid/hardware/Camera;)V", (void *)android_media_MediaRecorder_setCamera}, 632 {"setVideoSource", "(I)V", (void *)android_media_MediaRecorder_setVideoSource}, 633 {"setAudioSource", "(I)V", (void *)android_media_MediaRecorder_setAudioSource}, 634 {"setOutputFormat", "(I)V", (void *)android_media_MediaRecorder_setOutputFormat}, 635 {"setVideoEncoder", "(I)V", (void *)android_media_MediaRecorder_setVideoEncoder}, 636 {"setAudioEncoder", "(I)V", (void *)android_media_MediaRecorder_setAudioEncoder}, 637 {"setParameter", "(Ljava/lang/String;)V", (void *)android_media_MediaRecorder_setParameter}, 638 {"_setOutputFile", "(Ljava/io/FileDescriptor;)V", (void *)android_media_MediaRecorder_setOutputFileFD}, 639 {"_setNextOutputFile", "(Ljava/io/FileDescriptor;)V", (void *)android_media_MediaRecorder_setNextOutputFileFD}, 640 {"setVideoSize", "(II)V", (void *)android_media_MediaRecorder_setVideoSize}, 641 {"setVideoFrameRate", "(I)V", (void *)android_media_MediaRecorder_setVideoFrameRate}, 642 {"setMaxDuration", "(I)V", (void *)android_media_MediaRecorder_setMaxDuration}, 643 {"setMaxFileSize", "(J)V", (void *)android_media_MediaRecorder_setMaxFileSize}, 644 {"_prepare", "()V", (void *)android_media_MediaRecorder_prepare}, 645 {"getSurface", "()Landroid/view/Surface;", (void *)android_media_MediaRecorder_getSurface}, 646 {"getMaxAmplitude", "()I", (void *)android_media_MediaRecorder_native_getMaxAmplitude}, 647 {"start", "()V", (void *)android_media_MediaRecorder_start}, 648 {"stop", "()V", (void *)android_media_MediaRecorder_stop}, 649 {"pause", "()V", (void *)android_media_MediaRecorder_pause}, 650 {"resume", "()V", (void *)android_media_MediaRecorder_resume}, 651 {"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset}, 652 {"release", "()V", (void *)android_media_MediaRecorder_release}, 653 {"native_init", "()V", (void *)android_media_MediaRecorder_native_init}, 654 {"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V", 655 (void *)android_media_MediaRecorder_native_setup}, 656 {"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize}, 657 {"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface }, 658}; 659 660// This function only registers the native methods, and is called from 661// JNI_OnLoad in android_media_MediaPlayer.cpp 662int register_android_media_MediaRecorder(JNIEnv *env) 663{ 664 return AndroidRuntime::registerNativeMethods(env, 665 "android/media/MediaRecorder", gMethods, NELEM(gMethods)); 666} 667