StagefrightRecorder.cpp revision 2dec2b5be2056c6d9428897dc672185872d30d17
1/* 2 * Copyright (C) 2009 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//#define LOG_NDEBUG 0 18#define LOG_TAG "StagefrightRecorder" 19#include <utils/Log.h> 20 21#include "StagefrightRecorder.h" 22 23#include <binder/IPCThreadState.h> 24#include <media/stagefright/AudioSource.h> 25#include <media/stagefright/AMRWriter.h> 26#include <media/stagefright/CameraSource.h> 27#include <media/stagefright/MPEG4Writer.h> 28#include <media/stagefright/MediaDebug.h> 29#include <media/stagefright/MediaDefs.h> 30#include <media/stagefright/MetaData.h> 31#include <media/stagefright/OMXClient.h> 32#include <media/stagefright/OMXCodec.h> 33#include <media/MediaProfiles.h> 34#include <camera/ICamera.h> 35#include <camera/Camera.h> 36#include <camera/CameraParameters.h> 37#include <surfaceflinger/ISurface.h> 38#include <utils/Errors.h> 39#include <sys/types.h> 40#include <unistd.h> 41#include <ctype.h> 42 43namespace android { 44 45StagefrightRecorder::StagefrightRecorder() { 46 reset(); 47} 48 49StagefrightRecorder::~StagefrightRecorder() { 50 stop(); 51 52 if (mOutputFd >= 0) { 53 ::close(mOutputFd); 54 mOutputFd = -1; 55 } 56} 57 58status_t StagefrightRecorder::init() { 59 return OK; 60} 61 62status_t StagefrightRecorder::setAudioSource(audio_source as) { 63 mAudioSource = as; 64 65 return OK; 66} 67 68status_t StagefrightRecorder::setVideoSource(video_source vs) { 69 mVideoSource = vs; 70 71 return OK; 72} 73 74status_t StagefrightRecorder::setOutputFormat(output_format of) { 75 mOutputFormat = of; 76 77 return OK; 78} 79 80status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 81 mAudioEncoder = ae; 82 83 return OK; 84} 85 86status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 87 mVideoEncoder = ve; 88 89 return OK; 90} 91 92status_t StagefrightRecorder::setVideoSize(int width, int height) { 93 if (width <= 0 || height <= 0) { 94 LOGE("Invalid video size: %dx%d", width, height); 95 return BAD_VALUE; 96 } 97 98 // Additional check on the dimension will be performed later 99 mVideoWidth = width; 100 mVideoHeight = height; 101 102 return OK; 103} 104 105status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 106 if (frames_per_second <= 0 || frames_per_second > 30) { 107 LOGE("Invalid video frame rate: %d", frames_per_second); 108 return BAD_VALUE; 109 } 110 111 // Additional check on the frame rate will be performed later 112 mFrameRate = frames_per_second; 113 114 return OK; 115} 116 117status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) { 118 LOGV("setCamera"); 119 if (camera == 0) { 120 LOGE("camera is NULL"); 121 return UNKNOWN_ERROR; 122 } 123 124 int64_t token = IPCThreadState::self()->clearCallingIdentity(); 125 mFlags &= ~FLAGS_HOT_CAMERA; 126 mCamera = Camera::create(camera); 127 if (mCamera == 0) { 128 LOGE("Unable to connect to camera"); 129 IPCThreadState::self()->restoreCallingIdentity(token); 130 return UNKNOWN_ERROR; 131 } 132 133 LOGV("Connected to camera"); 134 if (mCamera->previewEnabled()) { 135 LOGV("camera is hot"); 136 mFlags |= FLAGS_HOT_CAMERA; 137 } 138 IPCThreadState::self()->restoreCallingIdentity(token); 139 140 return OK; 141} 142 143status_t StagefrightRecorder::setPreviewSurface(const sp<ISurface> &surface) { 144 mPreviewSurface = surface; 145 146 return OK; 147} 148 149status_t StagefrightRecorder::setOutputFile(const char *path) { 150 // We don't actually support this at all, as the media_server process 151 // no longer has permissions to create files. 152 153 return UNKNOWN_ERROR; 154} 155 156status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) { 157 // These don't make any sense, do they? 158 CHECK_EQ(offset, 0); 159 CHECK_EQ(length, 0); 160 161 if (mOutputFd >= 0) { 162 ::close(mOutputFd); 163 } 164 mOutputFd = dup(fd); 165 166 return OK; 167} 168 169// Attempt to parse an int64 literal optionally surrounded by whitespace, 170// returns true on success, false otherwise. 171static bool safe_strtoi64(const char *s, int64_t *val) { 172 char *end; 173 *val = strtoll(s, &end, 10); 174 175 if (end == s || errno == ERANGE) { 176 return false; 177 } 178 179 // Skip trailing whitespace 180 while (isspace(*end)) { 181 ++end; 182 } 183 184 // For a successful return, the string must contain nothing but a valid 185 // int64 literal optionally surrounded by whitespace. 186 187 return *end == '\0'; 188} 189 190// Return true if the value is in [0, 0x007FFFFFFF] 191static bool safe_strtoi32(const char *s, int32_t *val) { 192 int64_t temp; 193 if (safe_strtoi64(s, &temp)) { 194 if (temp >= 0 && temp <= 0x007FFFFFFF) { 195 *val = static_cast<int32_t>(temp); 196 return true; 197 } 198 } 199 return false; 200} 201 202// Trim both leading and trailing whitespace from the given string. 203static void TrimString(String8 *s) { 204 size_t num_bytes = s->bytes(); 205 const char *data = s->string(); 206 207 size_t leading_space = 0; 208 while (leading_space < num_bytes && isspace(data[leading_space])) { 209 ++leading_space; 210 } 211 212 size_t i = num_bytes; 213 while (i > leading_space && isspace(data[i - 1])) { 214 --i; 215 } 216 217 s->setTo(String8(&data[leading_space], i - leading_space)); 218} 219 220status_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) { 221 LOGV("setParamAudioSamplingRate: %d", sampleRate); 222 if (sampleRate <= 0) { 223 LOGE("Invalid audio sampling rate: %d", sampleRate); 224 return BAD_VALUE; 225 } 226 227 // Additional check on the sample rate will be performed later. 228 mSampleRate = sampleRate; 229 return OK; 230} 231 232status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) { 233 LOGV("setParamAudioNumberOfChannels: %d", channels); 234 if (channels <= 0 || channels >= 3) { 235 LOGE("Invalid number of audio channels: %d", channels); 236 } 237 238 // Additional check on the number of channels will be performed later. 239 mAudioChannels = channels; 240 return OK; 241} 242 243status_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) { 244 LOGV("setParamAudioEncodingBitRate: %d", bitRate); 245 if (bitRate <= 0) { 246 LOGE("Invalid audio encoding bit rate: %d", bitRate); 247 return BAD_VALUE; 248 } 249 250 // The target bit rate may not be exactly the same as the requested. 251 // It depends on many factors, such as rate control, and the bit rate 252 // range that a specific encoder supports. The mismatch between the 253 // the target and requested bit rate will NOT be treated as an error. 254 mAudioBitRate = bitRate; 255 return OK; 256} 257 258status_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) { 259 LOGV("setParamVideoEncodingBitRate: %d", bitRate); 260 if (bitRate <= 0) { 261 LOGE("Invalid video encoding bit rate: %d", bitRate); 262 return BAD_VALUE; 263 } 264 265 // The target bit rate may not be exactly the same as the requested. 266 // It depends on many factors, such as rate control, and the bit rate 267 // range that a specific encoder supports. The mismatch between the 268 // the target and requested bit rate will NOT be treated as an error. 269 mVideoBitRate = bitRate; 270 return OK; 271} 272 273status_t StagefrightRecorder::setParamMaxDurationOrFileSize(int64_t limit, 274 bool limit_is_duration) { 275 LOGV("setParamMaxDurationOrFileSize: limit (%lld) for %s", 276 limit, limit_is_duration?"duration":"size"); 277 if (limit_is_duration) { // limit is in ms 278 if (limit <= 1000) { // XXX: 1 second 279 LOGE("Max file duration is too short: %lld us", limit); 280 } 281 mMaxFileDurationUs = limit * 1000LL; 282 } else { 283 if (limit <= 1024) { // XXX: 1 kB 284 LOGE("Max file size is too small: %lld bytes", limit); 285 } 286 mMaxFileSizeBytes = limit; 287 } 288 return OK; 289} 290 291status_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) { 292 LOGV("setParamInterleaveDuration: %d", durationUs); 293 if (durationUs <= 500000) { // 500 ms 294 // If interleave duration is too small, it is very inefficient to do 295 // interleaving since the metadata overhead will count for a significant 296 // portion of the saved contents 297 LOGE("Audio/video interleave duration is too small: %d us", durationUs); 298 return BAD_VALUE; 299 } else if (durationUs >= 10000000) { // 10 seconds 300 // If interleaving duration is too large, it can cause the recording 301 // session to use too much memory since we have to save the output 302 // data before we write them out 303 LOGE("Audio/video interleave duration is too large: %d us", durationUs); 304 return BAD_VALUE; 305 } 306 mInterleaveDurationUs = durationUs; 307 return OK; 308} 309 310// If interval < 0, only the first frame is I frame, and rest are all P frames 311// If interval == 0, all frames are encoded as I frames. No P frames 312// If interval > 0, it is the time spacing between 2 neighboring I frames 313status_t StagefrightRecorder::setParamIFramesInterval(int32_t interval) { 314 LOGV("setParamIFramesInterval: %d seconds", interval); 315 mIFramesInterval = interval; 316 return OK; 317} 318 319status_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit) { 320 LOGV("setParam64BitFileOffset: %s", 321 use64Bit? "use 64 bit file offset": "use 32 bit file offset"); 322 mUse64BitFileOffset = use64Bit; 323 return OK; 324} 325 326status_t StagefrightRecorder::setParameter( 327 const String8 &key, const String8 &value) { 328 LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); 329 if (key == "max-duration") { 330 int64_t max_duration_ms; 331 if (safe_strtoi64(value.string(), &max_duration_ms)) { 332 return setParamMaxDurationOrFileSize( 333 max_duration_ms, true /* limit_is_duration */); 334 } 335 } else if (key == "max-filesize") { 336 int64_t max_filesize_bytes; 337 if (safe_strtoi64(value.string(), &max_filesize_bytes)) { 338 return setParamMaxDurationOrFileSize( 339 max_filesize_bytes, false /* limit is filesize */); 340 } 341 } else if (key == "audio-param-sampling-rate") { 342 int32_t sampling_rate; 343 if (safe_strtoi32(value.string(), &sampling_rate)) { 344 return setParamAudioSamplingRate(sampling_rate); 345 } 346 } else if (key == "audio-param-number-of-channels") { 347 int32_t number_of_channels; 348 if (safe_strtoi32(value.string(), &number_of_channels)) { 349 return setParamAudioNumberOfChannels(number_of_channels); 350 } 351 } else if (key == "audio-param-encoding-bitrate") { 352 int32_t audio_bitrate; 353 if (safe_strtoi32(value.string(), &audio_bitrate)) { 354 return setParamAudioEncodingBitRate(audio_bitrate); 355 } 356 } else if (key == "video-param-encoding-bitrate") { 357 int32_t video_bitrate; 358 if (safe_strtoi32(value.string(), &video_bitrate)) { 359 return setParamVideoEncodingBitRate(video_bitrate); 360 } 361 } else if (key == "param-interleave-duration-us") { 362 int32_t durationUs; 363 if (safe_strtoi32(value.string(), &durationUs)) { 364 return setParamInterleaveDuration(durationUs); 365 } 366 } else if (key == "param-i-frames-interval") { 367 int32_t interval; 368 if (safe_strtoi32(value.string(), &interval)) { 369 return setParamIFramesInterval(interval); 370 } 371 } else if (key == "param-use-64bit-offset") { 372 int32_t use64BitOffset; 373 if (safe_strtoi32(value.string(), &use64BitOffset)) { 374 return setParam64BitFileOffset(use64BitOffset != 0); 375 } 376 } else { 377 LOGE("setParameter: failed to find key %s", key.string()); 378 } 379 return BAD_VALUE; 380} 381 382status_t StagefrightRecorder::setParameters(const String8 ¶ms) { 383 LOGV("setParameters: %s", params.string()); 384 const char *cparams = params.string(); 385 const char *key_start = cparams; 386 for (;;) { 387 const char *equal_pos = strchr(key_start, '='); 388 if (equal_pos == NULL) { 389 LOGE("Parameters %s miss a value", cparams); 390 return BAD_VALUE; 391 } 392 String8 key(key_start, equal_pos - key_start); 393 TrimString(&key); 394 if (key.length() == 0) { 395 LOGE("Parameters %s contains an empty key", cparams); 396 return BAD_VALUE; 397 } 398 const char *value_start = equal_pos + 1; 399 const char *semicolon_pos = strchr(value_start, ';'); 400 String8 value; 401 if (semicolon_pos == NULL) { 402 value.setTo(value_start); 403 } else { 404 value.setTo(value_start, semicolon_pos - value_start); 405 } 406 if (setParameter(key, value) != OK) { 407 return BAD_VALUE; 408 } 409 if (semicolon_pos == NULL) { 410 break; // Reaches the end 411 } 412 key_start = semicolon_pos + 1; 413 } 414 return OK; 415} 416 417status_t StagefrightRecorder::setListener(const sp<IMediaPlayerClient> &listener) { 418 mListener = listener; 419 420 return OK; 421} 422 423status_t StagefrightRecorder::prepare() { 424 return OK; 425} 426 427status_t StagefrightRecorder::start() { 428 if (mWriter != NULL) { 429 return UNKNOWN_ERROR; 430 } 431 432 switch (mOutputFormat) { 433 case OUTPUT_FORMAT_DEFAULT: 434 case OUTPUT_FORMAT_THREE_GPP: 435 case OUTPUT_FORMAT_MPEG_4: 436 return startMPEG4Recording(); 437 438 case OUTPUT_FORMAT_AMR_NB: 439 case OUTPUT_FORMAT_AMR_WB: 440 return startAMRRecording(); 441 442 case OUTPUT_FORMAT_AAC_ADIF: 443 case OUTPUT_FORMAT_AAC_ADTS: 444 return startAACRecording(); 445 446 default: 447 return UNKNOWN_ERROR; 448 } 449} 450 451sp<MediaSource> StagefrightRecorder::createAudioSource() { 452 sp<AudioSource> audioSource = 453 new AudioSource( 454 mAudioSource, 455 mSampleRate, 456 mAudioChannels); 457 458 status_t err = audioSource->initCheck(); 459 460 if (err != OK) { 461 LOGE("audio source is not initialized"); 462 return NULL; 463 } 464 465 sp<MetaData> encMeta = new MetaData; 466 const char *mime; 467 switch (mAudioEncoder) { 468 case AUDIO_ENCODER_AMR_NB: 469 case AUDIO_ENCODER_DEFAULT: 470 mime = MEDIA_MIMETYPE_AUDIO_AMR_NB; 471 break; 472 case AUDIO_ENCODER_AMR_WB: 473 mime = MEDIA_MIMETYPE_AUDIO_AMR_WB; 474 break; 475 case AUDIO_ENCODER_AAC: 476 mime = MEDIA_MIMETYPE_AUDIO_AAC; 477 break; 478 default: 479 LOGE("Unknown audio encoder: %d", mAudioEncoder); 480 return NULL; 481 } 482 encMeta->setCString(kKeyMIMEType, mime); 483 484 int32_t maxInputSize; 485 CHECK(audioSource->getFormat()->findInt32( 486 kKeyMaxInputSize, &maxInputSize)); 487 488 encMeta->setInt32(kKeyMaxInputSize, maxInputSize); 489 encMeta->setInt32(kKeyChannelCount, mAudioChannels); 490 encMeta->setInt32(kKeySampleRate, mSampleRate); 491 encMeta->setInt32(kKeyBitRate, mAudioBitRate); 492 493 OMXClient client; 494 CHECK_EQ(client.connect(), OK); 495 496 sp<MediaSource> audioEncoder = 497 OMXCodec::Create(client.interface(), encMeta, 498 true /* createEncoder */, audioSource); 499 mAudioSourceNode = audioSource; 500 501 return audioEncoder; 502} 503 504status_t StagefrightRecorder::startAACRecording() { 505 CHECK(mOutputFormat == OUTPUT_FORMAT_AAC_ADIF || 506 mOutputFormat == OUTPUT_FORMAT_AAC_ADTS); 507 508 CHECK(mAudioEncoder == AUDIO_ENCODER_AAC); 509 CHECK(mAudioSource != AUDIO_SOURCE_LIST_END); 510 CHECK(mOutputFd >= 0); 511 512 CHECK(0 == "AACWriter is not implemented yet"); 513 514 return OK; 515} 516 517status_t StagefrightRecorder::startAMRRecording() { 518 CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB || 519 mOutputFormat == OUTPUT_FORMAT_AMR_WB); 520 521 if (mOutputFormat == OUTPUT_FORMAT_AMR_NB) { 522 if (mAudioEncoder != AUDIO_ENCODER_DEFAULT && 523 mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 524 LOGE("Invalid encoder %d used for AMRNB recording", 525 mAudioEncoder); 526 return UNKNOWN_ERROR; 527 } 528 if (mSampleRate != 8000) { 529 LOGE("Invalid sampling rate %d used for AMRNB recording", 530 mSampleRate); 531 return UNKNOWN_ERROR; 532 } 533 } else { // mOutputFormat must be OUTPUT_FORMAT_AMR_WB 534 if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 535 LOGE("Invlaid encoder %d used for AMRWB recording", 536 mAudioEncoder); 537 return UNKNOWN_ERROR; 538 } 539 if (mSampleRate != 16000) { 540 LOGE("Invalid sample rate %d used for AMRWB recording", 541 mSampleRate); 542 return UNKNOWN_ERROR; 543 } 544 } 545 if (mAudioChannels != 1) { 546 LOGE("Invalid number of audio channels %d used for amr recording", 547 mAudioChannels); 548 return UNKNOWN_ERROR; 549 } 550 551 if (mAudioSource >= AUDIO_SOURCE_LIST_END) { 552 LOGE("Invalid audio source: %d", mAudioSource); 553 return UNKNOWN_ERROR; 554 } 555 556 sp<MediaSource> audioEncoder = createAudioSource(); 557 558 if (audioEncoder == NULL) { 559 return UNKNOWN_ERROR; 560 } 561 562 CHECK(mOutputFd >= 0); 563 mWriter = new AMRWriter(dup(mOutputFd)); 564 mWriter->addSource(audioEncoder); 565 566 if (mMaxFileDurationUs != 0) { 567 mWriter->setMaxFileDuration(mMaxFileDurationUs); 568 } 569 if (mMaxFileSizeBytes != 0) { 570 mWriter->setMaxFileSize(mMaxFileSizeBytes); 571 } 572 mWriter->setListener(mListener); 573 mWriter->start(); 574 575 return OK; 576} 577 578void StagefrightRecorder::clipVideoFrameRate() { 579 LOGV("clipVideoFrameRate: encoder %d", mVideoEncoder); 580 int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 581 "enc.vid.fps.min", mVideoEncoder); 582 int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 583 "enc.vid.fps.max", mVideoEncoder); 584 if (mFrameRate < minFrameRate) { 585 LOGW("Intended video encoding frame rate (%d fps) is too small" 586 " and will be set to (%d fps)", mFrameRate, minFrameRate); 587 mFrameRate = minFrameRate; 588 } else if (mFrameRate > maxFrameRate) { 589 LOGW("Intended video encoding frame rate (%d fps) is too large" 590 " and will be set to (%d fps)", mFrameRate, maxFrameRate); 591 mFrameRate = maxFrameRate; 592 } 593} 594 595void StagefrightRecorder::clipVideoBitRate() { 596 LOGV("clipVideoBitRate: encoder %d", mVideoEncoder); 597 int minBitRate = mEncoderProfiles->getVideoEncoderParamByName( 598 "enc.vid.bps.min", mVideoEncoder); 599 int maxBitRate = mEncoderProfiles->getVideoEncoderParamByName( 600 "enc.vid.bps.max", mVideoEncoder); 601 if (mVideoBitRate < minBitRate) { 602 LOGW("Intended video encoding bit rate (%d bps) is too small" 603 " and will be set to (%d bps)", mVideoBitRate, minBitRate); 604 mVideoBitRate = minBitRate; 605 } else if (mVideoBitRate > maxBitRate) { 606 LOGW("Intended video encoding bit rate (%d bps) is too large" 607 " and will be set to (%d bps)", mVideoBitRate, maxBitRate); 608 mVideoBitRate = maxBitRate; 609 } 610} 611 612void StagefrightRecorder::clipVideoFrameWidth() { 613 LOGV("clipVideoFrameWidth: encoder %d", mVideoEncoder); 614 int minFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 615 "enc.vid.width.min", mVideoEncoder); 616 int maxFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 617 "enc.vid.width.max", mVideoEncoder); 618 if (mVideoWidth < minFrameWidth) { 619 LOGW("Intended video encoding frame width (%d) is too small" 620 " and will be set to (%d)", mVideoWidth, minFrameWidth); 621 mVideoWidth = minFrameWidth; 622 } else if (mVideoWidth > maxFrameWidth) { 623 LOGW("Intended video encoding frame width (%d) is too large" 624 " and will be set to (%d)", mVideoWidth, maxFrameWidth); 625 mVideoWidth = maxFrameWidth; 626 } 627} 628 629void StagefrightRecorder::clipVideoFrameHeight() { 630 LOGV("clipVideoFrameHeight: encoder %d", mVideoEncoder); 631 int minFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 632 "enc.vid.height.min", mVideoEncoder); 633 int maxFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 634 "enc.vid.height.max", mVideoEncoder); 635 if (mVideoHeight < minFrameHeight) { 636 LOGW("Intended video encoding frame height (%d) is too small" 637 " and will be set to (%d)", mVideoHeight, minFrameHeight); 638 mVideoHeight = minFrameHeight; 639 } else if (mVideoHeight > maxFrameHeight) { 640 LOGW("Intended video encoding frame height (%d) is too large" 641 " and will be set to (%d)", mVideoHeight, maxFrameHeight); 642 mVideoHeight = maxFrameHeight; 643 } 644} 645 646status_t StagefrightRecorder::startMPEG4Recording() { 647 mWriter = new MPEG4Writer(dup(mOutputFd)); 648 int32_t totalBitRate = 0; 649 650 // Add audio source first if it exists 651 if (mAudioSource != AUDIO_SOURCE_LIST_END) { 652 sp<MediaSource> audioEncoder; 653 switch(mAudioEncoder) { 654 case AUDIO_ENCODER_AMR_NB: 655 case AUDIO_ENCODER_AMR_WB: 656 case AUDIO_ENCODER_AAC: 657 audioEncoder = createAudioSource(); 658 break; 659 default: 660 LOGE("Unsupported audio encoder: %d", mAudioEncoder); 661 return UNKNOWN_ERROR; 662 } 663 664 if (audioEncoder == NULL) { 665 return UNKNOWN_ERROR; 666 } 667 totalBitRate += mAudioBitRate; 668 mWriter->addSource(audioEncoder); 669 } 670 if (mVideoSource == VIDEO_SOURCE_DEFAULT 671 || mVideoSource == VIDEO_SOURCE_CAMERA) { 672 673 clipVideoBitRate(); 674 clipVideoFrameRate(); 675 clipVideoFrameWidth(); 676 clipVideoFrameHeight(); 677 678 int64_t token = IPCThreadState::self()->clearCallingIdentity(); 679 if (mCamera == 0) { 680 mCamera = Camera::connect(0); 681 mCamera->lock(); 682 } 683 684 // Set the actual video recording frame size 685 CameraParameters params(mCamera->getParameters()); 686 params.setPreviewSize(mVideoWidth, mVideoHeight); 687 params.setPreviewFrameRate(mFrameRate); 688 String8 s = params.flatten(); 689 CHECK_EQ(OK, mCamera->setParameters(s)); 690 CameraParameters newCameraParams(mCamera->getParameters()); 691 692 // Check on video frame size 693 int frameWidth = 0, frameHeight = 0; 694 newCameraParams.getPreviewSize(&frameWidth, &frameHeight); 695 if (frameWidth < 0 || frameWidth != mVideoWidth || 696 frameHeight < 0 || frameHeight != mVideoHeight) { 697 LOGE("Failed to set the video frame size to %dx%d", 698 mVideoWidth, mVideoHeight); 699 IPCThreadState::self()->restoreCallingIdentity(token); 700 return UNKNOWN_ERROR; 701 } 702 703 // Check on video frame rate 704 int frameRate = newCameraParams.getPreviewFrameRate(); 705 if (frameRate < 0 || (frameRate - mFrameRate) != 0) { 706 LOGE("Failed to set frame rate to %d fps. The actual " 707 "frame rate is %d", mFrameRate, frameRate); 708 } 709 710 CHECK_EQ(OK, mCamera->setPreviewDisplay(mPreviewSurface)); 711 IPCThreadState::self()->restoreCallingIdentity(token); 712 713 sp<CameraSource> cameraSource = 714 CameraSource::CreateFromCamera(mCamera); 715 716 CHECK(cameraSource != NULL); 717 718 sp<MetaData> enc_meta = new MetaData; 719 enc_meta->setInt32(kKeyBitRate, mVideoBitRate); 720 enc_meta->setInt32(kKeySampleRate, mFrameRate); 721 722 switch (mVideoEncoder) { 723 case VIDEO_ENCODER_H263: 724 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); 725 break; 726 727 case VIDEO_ENCODER_MPEG_4_SP: 728 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 729 break; 730 731 case VIDEO_ENCODER_H264: 732 enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 733 break; 734 735 default: 736 CHECK(!"Should not be here, unsupported video encoding."); 737 break; 738 } 739 740 sp<MetaData> meta = cameraSource->getFormat(); 741 742 int32_t width, height, stride, sliceHeight; 743 CHECK(meta->findInt32(kKeyWidth, &width)); 744 CHECK(meta->findInt32(kKeyHeight, &height)); 745 CHECK(meta->findInt32(kKeyStride, &stride)); 746 CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight)); 747 748 enc_meta->setInt32(kKeyWidth, width); 749 enc_meta->setInt32(kKeyHeight, height); 750 enc_meta->setInt32(kKeyIFramesInterval, mIFramesInterval); 751 enc_meta->setInt32(kKeyStride, stride); 752 enc_meta->setInt32(kKeySliceHeight, sliceHeight); 753 754 OMXClient client; 755 CHECK_EQ(client.connect(), OK); 756 757 sp<MediaSource> encoder = 758 OMXCodec::Create( 759 client.interface(), enc_meta, 760 true /* createEncoder */, cameraSource); 761 762 CHECK(mOutputFd >= 0); 763 totalBitRate += mVideoBitRate; 764 mWriter->addSource(encoder); 765 } 766 767 { 768 // MPEGWriter specific handling 769 MPEG4Writer *writer = ((MPEG4Writer *) mWriter.get()); 770 writer->setInterleaveDuration(mInterleaveDurationUs); 771 } 772 773 if (mMaxFileDurationUs != 0) { 774 mWriter->setMaxFileDuration(mMaxFileDurationUs); 775 } 776 if (mMaxFileSizeBytes != 0) { 777 mWriter->setMaxFileSize(mMaxFileSizeBytes); 778 } 779 mWriter->setListener(mListener); 780 sp<MetaData> meta = new MetaData; 781 meta->setInt32(kKeyBitRate, totalBitRate); 782 meta->setInt32(kKey64BitFileOffset, mUse64BitFileOffset); 783 mWriter->start(meta.get()); 784 return OK; 785} 786 787status_t StagefrightRecorder::pause() { 788 if (mWriter == NULL) { 789 return UNKNOWN_ERROR; 790 } 791 mWriter->pause(); 792 return OK; 793} 794 795status_t StagefrightRecorder::stop() { 796 if (mWriter == NULL) { 797 return UNKNOWN_ERROR; 798 } 799 800 mWriter->stop(); 801 mWriter = NULL; 802 803 return OK; 804} 805 806status_t StagefrightRecorder::close() { 807 stop(); 808 809 if (mCamera != 0) { 810 int64_t token = IPCThreadState::self()->clearCallingIdentity(); 811 if ((mFlags & FLAGS_HOT_CAMERA) == 0) { 812 LOGV("Camera was cold when we started, stopping preview"); 813 mCamera->stopPreview(); 814 } 815 mCamera->unlock(); 816 mCamera = NULL; 817 IPCThreadState::self()->restoreCallingIdentity(token); 818 mFlags = 0; 819 } 820 return OK; 821} 822 823status_t StagefrightRecorder::reset() { 824 stop(); 825 826 // No audio or video source by default 827 mAudioSource = AUDIO_SOURCE_LIST_END; 828 mVideoSource = VIDEO_SOURCE_LIST_END; 829 830 // Default parameters 831 mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 832 mAudioEncoder = AUDIO_ENCODER_AMR_NB; 833 mVideoEncoder = VIDEO_ENCODER_H263; 834 mVideoWidth = 176; 835 mVideoHeight = 144; 836 mFrameRate = 20; 837 mVideoBitRate = 192000; 838 mSampleRate = 8000; 839 mAudioChannels = 1; 840 mAudioBitRate = 12200; 841 mInterleaveDurationUs = 0; 842 mIFramesInterval = 1; 843 mAudioSourceNode = 0; 844 mUse64BitFileOffset = false; 845 mEncoderProfiles = MediaProfiles::getInstance(); 846 847 mOutputFd = -1; 848 mFlags = 0; 849 850 return OK; 851} 852 853status_t StagefrightRecorder::getMaxAmplitude(int *max) { 854 if (mAudioSourceNode != 0) { 855 *max = mAudioSourceNode->getMaxAmplitude(); 856 } else { 857 *max = 0; 858 } 859 860 return OK; 861} 862 863} // namespace android 864