1 /* 2 ** 3 ** Copyright (c) 2008 The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 //#define LOG_NDEBUG 0 19 #define LOG_TAG "MediaRecorder" 20 #include <utils/Log.h> 21 #include <media/mediarecorder.h> 22 #include <binder/IServiceManager.h> 23 #include <utils/String8.h> 24 #include <media/IMediaPlayerService.h> 25 #include <media/IMediaRecorder.h> 26 #include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED 27 #include <gui/IGraphicBufferProducer.h> 28 29 namespace android { 30 31 status_t MediaRecorder::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy) 32 { 33 ALOGV("setCamera(%p,%p)", camera.get(), proxy.get()); 34 if (mMediaRecorder == NULL) { 35 ALOGE("media recorder is not initialized yet"); 36 return INVALID_OPERATION; 37 } 38 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) { 39 ALOGE("setCamera called in an invalid state(%d)", mCurrentState); 40 return INVALID_OPERATION; 41 } 42 43 status_t ret = mMediaRecorder->setCamera(camera, proxy); 44 if (OK != ret) { 45 ALOGV("setCamera failed: %d", ret); 46 mCurrentState = MEDIA_RECORDER_ERROR; 47 return ret; 48 } 49 return ret; 50 } 51 52 status_t MediaRecorder::setPreviewSurface(const sp<IGraphicBufferProducer>& surface) 53 { 54 ALOGV("setPreviewSurface(%p)", surface.get()); 55 if (mMediaRecorder == NULL) { 56 ALOGE("media recorder is not initialized yet"); 57 return INVALID_OPERATION; 58 } 59 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 60 ALOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState); 61 return INVALID_OPERATION; 62 } 63 if (!mIsVideoSourceSet) { 64 ALOGE("try to set preview surface without setting the video source first"); 65 return INVALID_OPERATION; 66 } 67 68 status_t ret = mMediaRecorder->setPreviewSurface(surface); 69 if (OK != ret) { 70 ALOGV("setPreviewSurface failed: %d", ret); 71 mCurrentState = MEDIA_RECORDER_ERROR; 72 return ret; 73 } 74 return ret; 75 } 76 77 status_t MediaRecorder::init() 78 { 79 ALOGV("init"); 80 if (mMediaRecorder == NULL) { 81 ALOGE("media recorder is not initialized yet"); 82 return INVALID_OPERATION; 83 } 84 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) { 85 ALOGE("init called in an invalid state(%d)", mCurrentState); 86 return INVALID_OPERATION; 87 } 88 89 status_t ret = mMediaRecorder->init(); 90 if (OK != ret) { 91 ALOGV("init failed: %d", ret); 92 mCurrentState = MEDIA_RECORDER_ERROR; 93 return ret; 94 } 95 96 ret = mMediaRecorder->setListener(this); 97 if (OK != ret) { 98 ALOGV("setListener failed: %d", ret); 99 mCurrentState = MEDIA_RECORDER_ERROR; 100 return ret; 101 } 102 103 mCurrentState = MEDIA_RECORDER_INITIALIZED; 104 return ret; 105 } 106 107 status_t MediaRecorder::setVideoSource(int vs) 108 { 109 ALOGV("setVideoSource(%d)", vs); 110 if (mMediaRecorder == NULL) { 111 ALOGE("media recorder is not initialized yet"); 112 return INVALID_OPERATION; 113 } 114 if (mIsVideoSourceSet) { 115 ALOGE("video source has already been set"); 116 return INVALID_OPERATION; 117 } 118 if (mCurrentState & MEDIA_RECORDER_IDLE) { 119 ALOGV("Call init() since the media recorder is not initialized yet"); 120 status_t ret = init(); 121 if (OK != ret) { 122 return ret; 123 } 124 } 125 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { 126 ALOGE("setVideoSource called in an invalid state(%d)", mCurrentState); 127 return INVALID_OPERATION; 128 } 129 130 // following call is made over the Binder Interface 131 status_t ret = mMediaRecorder->setVideoSource(vs); 132 133 if (OK != ret) { 134 ALOGV("setVideoSource failed: %d", ret); 135 mCurrentState = MEDIA_RECORDER_ERROR; 136 return ret; 137 } 138 mIsVideoSourceSet = true; 139 return ret; 140 } 141 142 status_t MediaRecorder::setAudioSource(int as) 143 { 144 ALOGV("setAudioSource(%d)", as); 145 if (mMediaRecorder == NULL) { 146 ALOGE("media recorder is not initialized yet"); 147 return INVALID_OPERATION; 148 } 149 if (mCurrentState & MEDIA_RECORDER_IDLE) { 150 ALOGV("Call init() since the media recorder is not initialized yet"); 151 status_t ret = init(); 152 if (OK != ret) { 153 return ret; 154 } 155 } 156 if (mIsAudioSourceSet) { 157 ALOGE("audio source has already been set"); 158 return INVALID_OPERATION; 159 } 160 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { 161 ALOGE("setAudioSource called in an invalid state(%d)", mCurrentState); 162 return INVALID_OPERATION; 163 } 164 165 status_t ret = mMediaRecorder->setAudioSource(as); 166 if (OK != ret) { 167 ALOGV("setAudioSource failed: %d", ret); 168 mCurrentState = MEDIA_RECORDER_ERROR; 169 return ret; 170 } 171 mIsAudioSourceSet = true; 172 return ret; 173 } 174 175 status_t MediaRecorder::setOutputFormat(int of) 176 { 177 ALOGV("setOutputFormat(%d)", of); 178 if (mMediaRecorder == NULL) { 179 ALOGE("media recorder is not initialized yet"); 180 return INVALID_OPERATION; 181 } 182 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { 183 ALOGE("setOutputFormat called in an invalid state: %d", mCurrentState); 184 return INVALID_OPERATION; 185 } 186 if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START && of != OUTPUT_FORMAT_RTP_AVP && of != OUTPUT_FORMAT_MPEG2TS) { //first non-video output format 187 ALOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of); 188 return INVALID_OPERATION; 189 } 190 191 status_t ret = mMediaRecorder->setOutputFormat(of); 192 if (OK != ret) { 193 ALOGE("setOutputFormat failed: %d", ret); 194 mCurrentState = MEDIA_RECORDER_ERROR; 195 return ret; 196 } 197 mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED; 198 return ret; 199 } 200 201 status_t MediaRecorder::setVideoEncoder(int ve) 202 { 203 ALOGV("setVideoEncoder(%d)", ve); 204 if (mMediaRecorder == NULL) { 205 ALOGE("media recorder is not initialized yet"); 206 return INVALID_OPERATION; 207 } 208 if (!mIsVideoSourceSet) { 209 ALOGE("try to set the video encoder without setting the video source first"); 210 return INVALID_OPERATION; 211 } 212 if (mIsVideoEncoderSet) { 213 ALOGE("video encoder has already been set"); 214 return INVALID_OPERATION; 215 } 216 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 217 ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState); 218 return INVALID_OPERATION; 219 } 220 221 status_t ret = mMediaRecorder->setVideoEncoder(ve); 222 if (OK != ret) { 223 ALOGV("setVideoEncoder failed: %d", ret); 224 mCurrentState = MEDIA_RECORDER_ERROR; 225 return ret; 226 } 227 mIsVideoEncoderSet = true; 228 return ret; 229 } 230 231 status_t MediaRecorder::setAudioEncoder(int ae) 232 { 233 ALOGV("setAudioEncoder(%d)", ae); 234 if (mMediaRecorder == NULL) { 235 ALOGE("media recorder is not initialized yet"); 236 return INVALID_OPERATION; 237 } 238 if (!mIsAudioSourceSet) { 239 ALOGE("try to set the audio encoder without setting the audio source first"); 240 return INVALID_OPERATION; 241 } 242 if (mIsAudioEncoderSet) { 243 ALOGE("audio encoder has already been set"); 244 return INVALID_OPERATION; 245 } 246 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 247 ALOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState); 248 return INVALID_OPERATION; 249 } 250 251 status_t ret = mMediaRecorder->setAudioEncoder(ae); 252 if (OK != ret) { 253 ALOGV("setAudioEncoder failed: %d", ret); 254 mCurrentState = MEDIA_RECORDER_ERROR; 255 return ret; 256 } 257 mIsAudioEncoderSet = true; 258 return ret; 259 } 260 261 status_t MediaRecorder::setOutputFile(const char* path) 262 { 263 ALOGV("setOutputFile(%s)", path); 264 if (mMediaRecorder == NULL) { 265 ALOGE("media recorder is not initialized yet"); 266 return INVALID_OPERATION; 267 } 268 if (mIsOutputFileSet) { 269 ALOGE("output file has already been set"); 270 return INVALID_OPERATION; 271 } 272 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 273 ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState); 274 return INVALID_OPERATION; 275 } 276 277 status_t ret = mMediaRecorder->setOutputFile(path); 278 if (OK != ret) { 279 ALOGV("setOutputFile failed: %d", ret); 280 mCurrentState = MEDIA_RECORDER_ERROR; 281 return ret; 282 } 283 mIsOutputFileSet = true; 284 return ret; 285 } 286 287 status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length) 288 { 289 ALOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length); 290 if (mMediaRecorder == NULL) { 291 ALOGE("media recorder is not initialized yet"); 292 return INVALID_OPERATION; 293 } 294 if (mIsOutputFileSet) { 295 ALOGE("output file has already been set"); 296 return INVALID_OPERATION; 297 } 298 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 299 ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState); 300 return INVALID_OPERATION; 301 } 302 303 // It appears that if an invalid file descriptor is passed through 304 // binder calls, the server-side of the inter-process function call 305 // is skipped. As a result, the check at the server-side to catch 306 // the invalid file descritpor never gets invoked. This is to workaround 307 // this issue by checking the file descriptor first before passing 308 // it through binder call. 309 if (fd < 0) { 310 ALOGE("Invalid file descriptor: %d", fd); 311 return BAD_VALUE; 312 } 313 314 status_t ret = mMediaRecorder->setOutputFile(fd, offset, length); 315 if (OK != ret) { 316 ALOGV("setOutputFile failed: %d", ret); 317 mCurrentState = MEDIA_RECORDER_ERROR; 318 return ret; 319 } 320 mIsOutputFileSet = true; 321 return ret; 322 } 323 324 status_t MediaRecorder::setVideoSize(int width, int height) 325 { 326 ALOGV("setVideoSize(%d, %d)", width, height); 327 if (mMediaRecorder == NULL) { 328 ALOGE("media recorder is not initialized yet"); 329 return INVALID_OPERATION; 330 } 331 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 332 ALOGE("setVideoSize called in an invalid state: %d", mCurrentState); 333 return INVALID_OPERATION; 334 } 335 if (!mIsVideoSourceSet) { 336 ALOGE("Cannot set video size without setting video source first"); 337 return INVALID_OPERATION; 338 } 339 340 status_t ret = mMediaRecorder->setVideoSize(width, height); 341 if (OK != ret) { 342 ALOGE("setVideoSize failed: %d", ret); 343 mCurrentState = MEDIA_RECORDER_ERROR; 344 return ret; 345 } 346 347 return ret; 348 } 349 350 // Query a SurfaceMediaSurface through the Mediaserver, over the 351 // binder interface. This is used by the Filter Framework (MediaEncoder) 352 // to get an <IGraphicBufferProducer> object to hook up to ANativeWindow. 353 sp<IGraphicBufferProducer> MediaRecorder:: 354 querySurfaceMediaSourceFromMediaServer() 355 { 356 Mutex::Autolock _l(mLock); 357 mSurfaceMediaSource = 358 mMediaRecorder->querySurfaceMediaSource(); 359 if (mSurfaceMediaSource == NULL) { 360 ALOGE("SurfaceMediaSource could not be initialized!"); 361 } 362 return mSurfaceMediaSource; 363 } 364 365 366 367 status_t MediaRecorder::setVideoFrameRate(int frames_per_second) 368 { 369 ALOGV("setVideoFrameRate(%d)", frames_per_second); 370 if (mMediaRecorder == NULL) { 371 ALOGE("media recorder is not initialized yet"); 372 return INVALID_OPERATION; 373 } 374 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 375 ALOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState); 376 return INVALID_OPERATION; 377 } 378 if (!mIsVideoSourceSet) { 379 ALOGE("Cannot set video frame rate without setting video source first"); 380 return INVALID_OPERATION; 381 } 382 383 status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second); 384 if (OK != ret) { 385 ALOGE("setVideoFrameRate failed: %d", ret); 386 mCurrentState = MEDIA_RECORDER_ERROR; 387 return ret; 388 } 389 return ret; 390 } 391 392 status_t MediaRecorder::setParameters(const String8& params) { 393 ALOGV("setParameters(%s)", params.string()); 394 if (mMediaRecorder == NULL) { 395 ALOGE("media recorder is not initialized yet"); 396 return INVALID_OPERATION; 397 } 398 399 bool isInvalidState = (mCurrentState & 400 (MEDIA_RECORDER_PREPARED | 401 MEDIA_RECORDER_RECORDING | 402 MEDIA_RECORDER_ERROR)); 403 if (isInvalidState) { 404 ALOGE("setParameters is called in an invalid state: %d", mCurrentState); 405 return INVALID_OPERATION; 406 } 407 408 status_t ret = mMediaRecorder->setParameters(params); 409 if (OK != ret) { 410 ALOGE("setParameters(%s) failed: %d", params.string(), ret); 411 // Do not change our current state to MEDIA_RECORDER_ERROR, failures 412 // of the only currently supported parameters, "max-duration" and 413 // "max-filesize" are _not_ fatal. 414 } 415 416 return ret; 417 } 418 419 status_t MediaRecorder::prepare() 420 { 421 ALOGV("prepare"); 422 if (mMediaRecorder == NULL) { 423 ALOGE("media recorder is not initialized yet"); 424 return INVALID_OPERATION; 425 } 426 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) { 427 ALOGE("prepare called in an invalid state: %d", mCurrentState); 428 return INVALID_OPERATION; 429 } 430 if (mIsAudioSourceSet != mIsAudioEncoderSet) { 431 if (mIsAudioSourceSet) { 432 ALOGE("audio source is set, but audio encoder is not set"); 433 } else { // must not happen, since setAudioEncoder checks this already 434 ALOGE("audio encoder is set, but audio source is not set"); 435 } 436 return INVALID_OPERATION; 437 } 438 439 if (mIsVideoSourceSet != mIsVideoEncoderSet) { 440 if (mIsVideoSourceSet) { 441 ALOGE("video source is set, but video encoder is not set"); 442 } else { // must not happen, since setVideoEncoder checks this already 443 ALOGE("video encoder is set, but video source is not set"); 444 } 445 return INVALID_OPERATION; 446 } 447 448 status_t ret = mMediaRecorder->prepare(); 449 if (OK != ret) { 450 ALOGE("prepare failed: %d", ret); 451 mCurrentState = MEDIA_RECORDER_ERROR; 452 return ret; 453 } 454 mCurrentState = MEDIA_RECORDER_PREPARED; 455 return ret; 456 } 457 458 status_t MediaRecorder::getMaxAmplitude(int* max) 459 { 460 ALOGV("getMaxAmplitude"); 461 if (mMediaRecorder == NULL) { 462 ALOGE("media recorder is not initialized yet"); 463 return INVALID_OPERATION; 464 } 465 if (mCurrentState & MEDIA_RECORDER_ERROR) { 466 ALOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState); 467 return INVALID_OPERATION; 468 } 469 470 status_t ret = mMediaRecorder->getMaxAmplitude(max); 471 if (OK != ret) { 472 ALOGE("getMaxAmplitude failed: %d", ret); 473 mCurrentState = MEDIA_RECORDER_ERROR; 474 return ret; 475 } 476 return ret; 477 } 478 479 status_t MediaRecorder::start() 480 { 481 ALOGV("start"); 482 if (mMediaRecorder == NULL) { 483 ALOGE("media recorder is not initialized yet"); 484 return INVALID_OPERATION; 485 } 486 if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) { 487 ALOGE("start called in an invalid state: %d", mCurrentState); 488 return INVALID_OPERATION; 489 } 490 491 status_t ret = mMediaRecorder->start(); 492 if (OK != ret) { 493 ALOGE("start failed: %d", ret); 494 mCurrentState = MEDIA_RECORDER_ERROR; 495 return ret; 496 } 497 mCurrentState = MEDIA_RECORDER_RECORDING; 498 return ret; 499 } 500 501 status_t MediaRecorder::stop() 502 { 503 ALOGV("stop"); 504 if (mMediaRecorder == NULL) { 505 ALOGE("media recorder is not initialized yet"); 506 return INVALID_OPERATION; 507 } 508 if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) { 509 ALOGE("stop called in an invalid state: %d", mCurrentState); 510 return INVALID_OPERATION; 511 } 512 513 status_t ret = mMediaRecorder->stop(); 514 if (OK != ret) { 515 ALOGE("stop failed: %d", ret); 516 mCurrentState = MEDIA_RECORDER_ERROR; 517 return ret; 518 } 519 520 // FIXME: 521 // stop and reset are semantically different. 522 // We treat them the same for now, and will change this in the future. 523 doCleanUp(); 524 mCurrentState = MEDIA_RECORDER_IDLE; 525 return ret; 526 } 527 528 // Reset should be OK in any state 529 status_t MediaRecorder::reset() 530 { 531 ALOGV("reset"); 532 if (mMediaRecorder == NULL) { 533 ALOGE("media recorder is not initialized yet"); 534 return INVALID_OPERATION; 535 } 536 537 doCleanUp(); 538 status_t ret = UNKNOWN_ERROR; 539 switch (mCurrentState) { 540 case MEDIA_RECORDER_IDLE: 541 ret = OK; 542 break; 543 544 case MEDIA_RECORDER_RECORDING: 545 case MEDIA_RECORDER_DATASOURCE_CONFIGURED: 546 case MEDIA_RECORDER_PREPARED: 547 case MEDIA_RECORDER_ERROR: { 548 ret = doReset(); 549 if (OK != ret) { 550 return ret; // No need to continue 551 } 552 } // Intentional fall through 553 case MEDIA_RECORDER_INITIALIZED: 554 ret = close(); 555 break; 556 557 default: { 558 ALOGE("Unexpected non-existing state: %d", mCurrentState); 559 break; 560 } 561 } 562 return ret; 563 } 564 565 status_t MediaRecorder::close() 566 { 567 ALOGV("close"); 568 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) { 569 ALOGE("close called in an invalid state: %d", mCurrentState); 570 return INVALID_OPERATION; 571 } 572 status_t ret = mMediaRecorder->close(); 573 if (OK != ret) { 574 ALOGE("close failed: %d", ret); 575 mCurrentState = MEDIA_RECORDER_ERROR; 576 return UNKNOWN_ERROR; 577 } else { 578 mCurrentState = MEDIA_RECORDER_IDLE; 579 } 580 return ret; 581 } 582 583 status_t MediaRecorder::doReset() 584 { 585 ALOGV("doReset"); 586 status_t ret = mMediaRecorder->reset(); 587 if (OK != ret) { 588 ALOGE("doReset failed: %d", ret); 589 mCurrentState = MEDIA_RECORDER_ERROR; 590 return ret; 591 } else { 592 mCurrentState = MEDIA_RECORDER_INITIALIZED; 593 } 594 return ret; 595 } 596 597 void MediaRecorder::doCleanUp() 598 { 599 ALOGV("doCleanUp"); 600 mIsAudioSourceSet = false; 601 mIsVideoSourceSet = false; 602 mIsAudioEncoderSet = false; 603 mIsVideoEncoderSet = false; 604 mIsOutputFileSet = false; 605 } 606 607 // Release should be OK in any state 608 status_t MediaRecorder::release() 609 { 610 ALOGV("release"); 611 if (mMediaRecorder != NULL) { 612 return mMediaRecorder->release(); 613 } 614 return INVALID_OPERATION; 615 } 616 617 MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL) 618 { 619 ALOGV("constructor"); 620 621 const sp<IMediaPlayerService>& service(getMediaPlayerService()); 622 if (service != NULL) { 623 mMediaRecorder = service->createMediaRecorder(); 624 } 625 if (mMediaRecorder != NULL) { 626 mCurrentState = MEDIA_RECORDER_IDLE; 627 } 628 629 630 doCleanUp(); 631 } 632 633 status_t MediaRecorder::initCheck() 634 { 635 return mMediaRecorder != 0 ? NO_ERROR : NO_INIT; 636 } 637 638 MediaRecorder::~MediaRecorder() 639 { 640 ALOGV("destructor"); 641 if (mMediaRecorder != NULL) { 642 mMediaRecorder.clear(); 643 } 644 645 if (mSurfaceMediaSource != NULL) { 646 mSurfaceMediaSource.clear(); 647 } 648 } 649 650 status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener) 651 { 652 ALOGV("setListener"); 653 Mutex::Autolock _l(mLock); 654 mListener = listener; 655 656 return NO_ERROR; 657 } 658 659 status_t MediaRecorder::setClientName(const String16& clientName) 660 { 661 ALOGV("setClientName"); 662 if (mMediaRecorder == NULL) { 663 ALOGE("media recorder is not initialized yet"); 664 return INVALID_OPERATION; 665 } 666 bool isInvalidState = (mCurrentState & 667 (MEDIA_RECORDER_PREPARED | 668 MEDIA_RECORDER_RECORDING | 669 MEDIA_RECORDER_ERROR)); 670 if (isInvalidState) { 671 ALOGE("setClientName is called in an invalid state: %d", mCurrentState); 672 return INVALID_OPERATION; 673 } 674 675 mMediaRecorder->setClientName(clientName); 676 677 return NO_ERROR; 678 } 679 680 void MediaRecorder::notify(int msg, int ext1, int ext2) 681 { 682 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); 683 684 sp<MediaRecorderListener> listener; 685 mLock.lock(); 686 listener = mListener; 687 mLock.unlock(); 688 689 if (listener != NULL) { 690 Mutex::Autolock _l(mNotifyLock); 691 ALOGV("callback application"); 692 listener->notify(msg, ext1, ext2); 693 ALOGV("back from callback"); 694 } 695 } 696 697 void MediaRecorder::died() 698 { 699 ALOGV("died"); 700 notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0); 701 } 702 703 }; // namespace android 704