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