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