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