StagefrightRecorder.cpp revision ac4e4189db77dc0af7671b162d11be5ccec69339
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 <inttypes.h> 20#include <utils/Log.h> 21 22#include "WebmWriter.h" 23#include "StagefrightRecorder.h" 24 25#include <algorithm> 26 27#include <android/hardware/ICamera.h> 28 29#include <binder/IPCThreadState.h> 30#include <binder/IServiceManager.h> 31 32#include <media/IMediaPlayerService.h> 33#include <media/MediaAnalyticsItem.h> 34#include <media/stagefright/foundation/ABuffer.h> 35#include <media/stagefright/foundation/ADebug.h> 36#include <media/stagefright/foundation/AMessage.h> 37#include <media/stagefright/foundation/ALooper.h> 38#include <media/stagefright/ACodec.h> 39#include <media/stagefright/AudioSource.h> 40#include <media/stagefright/AMRWriter.h> 41#include <media/stagefright/AACWriter.h> 42#include <media/stagefright/CameraSource.h> 43#include <media/stagefright/CameraSourceTimeLapse.h> 44#include <media/stagefright/MPEG2TSWriter.h> 45#include <media/stagefright/MPEG4Writer.h> 46#include <media/stagefright/MediaDefs.h> 47#include <media/stagefright/MetaData.h> 48#include <media/stagefright/MediaCodecSource.h> 49#include <media/stagefright/PersistentSurface.h> 50#include <media/MediaProfiles.h> 51#include <camera/CameraParameters.h> 52 53#include <utils/Errors.h> 54#include <sys/types.h> 55#include <ctype.h> 56#include <unistd.h> 57 58#include <system/audio.h> 59 60#include "ARTPWriter.h" 61 62namespace android { 63 64static const float kTypicalDisplayRefreshingRate = 60.f; 65// display refresh rate drops on battery saver 66static const float kMinTypicalDisplayRefreshingRate = kTypicalDisplayRefreshingRate / 2; 67static const int kMaxNumVideoTemporalLayers = 8; 68 69// key for media statistics 70static const char *kKeyRecorder = "recorder"; 71// attrs for media statistics 72// 73// To collect the encoder usage for the battery app 74static void addBatteryData(uint32_t params) { 75 sp<IBinder> binder = 76 defaultServiceManager()->getService(String16("media.player")); 77 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 78 CHECK(service.get() != NULL); 79 80 service->addBatteryData(params); 81} 82 83 84StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName) 85 : MediaRecorderBase(opPackageName), 86 mWriter(NULL), 87 mOutputFd(-1), 88 mAudioSource(AUDIO_SOURCE_CNT), 89 mVideoSource(VIDEO_SOURCE_LIST_END), 90 mStarted(false) { 91 92 ALOGV("Constructor"); 93 94 mAnalyticsDirty = false; 95 reset(); 96} 97 98StagefrightRecorder::~StagefrightRecorder() { 99 ALOGV("Destructor"); 100 stop(); 101 102 if (mLooper != NULL) { 103 mLooper->stop(); 104 } 105 106 // log the current record, provided it has some information worth recording 107 if (mAnalyticsDirty && mAnalyticsItem != NULL) { 108 updateMetrics(); 109 if (mAnalyticsItem->count() > 0) { 110 mAnalyticsItem->setFinalized(true); 111 mAnalyticsItem->selfrecord(); 112 } 113 delete mAnalyticsItem; 114 mAnalyticsItem = NULL; 115 } 116} 117 118void StagefrightRecorder::updateMetrics() { 119 ALOGV("updateMetrics"); 120 121 // we'll populate the values from the raw fields. 122 // (NOT going to populate as we go through the various set* ops) 123 124 // TBD mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 125 // TBD mAudioEncoder = AUDIO_ENCODER_AMR_NB; 126 // TBD mVideoEncoder = VIDEO_ENCODER_DEFAULT; 127 mAnalyticsItem->setInt32("ht", mVideoHeight); 128 mAnalyticsItem->setInt32("wid", mVideoWidth); 129 mAnalyticsItem->setInt32("frame-rate", mFrameRate); 130 mAnalyticsItem->setInt32("video-bitrate", mVideoBitRate); 131 mAnalyticsItem->setInt32("audio-samplerate", mSampleRate); 132 mAnalyticsItem->setInt32("audio-channels", mAudioChannels); 133 mAnalyticsItem->setInt32("audio-bitrate", mAudioBitRate); 134 // TBD mInterleaveDurationUs = 0; 135 mAnalyticsItem->setInt32("video-iframe-interval", mIFramesIntervalSec); 136 // TBD mAudioSourceNode = 0; 137 // TBD mUse64BitFileOffset = false; 138 mAnalyticsItem->setInt32("movie-timescale", mMovieTimeScale); 139 mAnalyticsItem->setInt32("audio-timescale", mAudioTimeScale); 140 mAnalyticsItem->setInt32("video-timescale", mVideoTimeScale); 141 // TBD mCameraId = 0; 142 // TBD mStartTimeOffsetMs = -1; 143 mAnalyticsItem->setInt32("video-encoder-profile", mVideoEncoderProfile); 144 mAnalyticsItem->setInt32("video-encoder-level", mVideoEncoderLevel); 145 // TBD mMaxFileDurationUs = 0; 146 // TBD mMaxFileSizeBytes = 0; 147 // TBD mTrackEveryTimeDurationUs = 0; 148 mAnalyticsItem->setInt32("capture-fpsenable", mCaptureFpsEnable); 149 mAnalyticsItem->setInt32("capture-fps", mCaptureFps); 150 // TBD mTimeBetweenCaptureUs = -1; 151 // TBD mCameraSourceTimeLapse = NULL; 152 // TBD mMetaDataStoredInVideoBuffers = kMetadataBufferTypeInvalid; 153 // TBD mEncoderProfiles = MediaProfiles::getInstance(); 154 mAnalyticsItem->setInt32("rotation", mRotationDegrees); 155 // PII mLatitudex10000 = -3600000; 156 // PII mLongitudex10000 = -3600000; 157 // TBD mTotalBitRate = 0; 158 159 // TBD: some duration information (capture, paused) 160 // 161 162} 163 164void StagefrightRecorder::resetMetrics() { 165 ALOGV("resetMetrics"); 166 // flush anything we have, restart the record 167 if (mAnalyticsDirty && mAnalyticsItem != NULL) { 168 updateMetrics(); 169 if (mAnalyticsItem->count() > 0) { 170 mAnalyticsItem->setFinalized(true); 171 mAnalyticsItem->selfrecord(); 172 } 173 delete mAnalyticsItem; 174 mAnalyticsItem = NULL; 175 } 176 mAnalyticsItem = new MediaAnalyticsItem(kKeyRecorder); 177 (void) mAnalyticsItem->generateSessionID(); 178 mAnalyticsDirty = false; 179} 180 181status_t StagefrightRecorder::init() { 182 ALOGV("init"); 183 184 mLooper = new ALooper; 185 mLooper->setName("recorder_looper"); 186 mLooper->start(); 187 188 return OK; 189} 190 191// The client side of mediaserver asks it to creat a SurfaceMediaSource 192// and return a interface reference. The client side will use that 193// while encoding GL Frames 194sp<IGraphicBufferProducer> StagefrightRecorder::querySurfaceMediaSource() const { 195 ALOGV("Get SurfaceMediaSource"); 196 return mGraphicBufferProducer; 197} 198 199status_t StagefrightRecorder::setAudioSource(audio_source_t as) { 200 ALOGV("setAudioSource: %d", as); 201 if (as < AUDIO_SOURCE_DEFAULT || 202 (as >= AUDIO_SOURCE_CNT && as != AUDIO_SOURCE_FM_TUNER)) { 203 ALOGE("Invalid audio source: %d", as); 204 return BAD_VALUE; 205 } 206 207 if (as == AUDIO_SOURCE_DEFAULT) { 208 mAudioSource = AUDIO_SOURCE_MIC; 209 } else { 210 mAudioSource = as; 211 } 212 213 return OK; 214} 215 216status_t StagefrightRecorder::setVideoSource(video_source vs) { 217 ALOGV("setVideoSource: %d", vs); 218 if (vs < VIDEO_SOURCE_DEFAULT || 219 vs >= VIDEO_SOURCE_LIST_END) { 220 ALOGE("Invalid video source: %d", vs); 221 return BAD_VALUE; 222 } 223 224 if (vs == VIDEO_SOURCE_DEFAULT) { 225 mVideoSource = VIDEO_SOURCE_CAMERA; 226 } else { 227 mVideoSource = vs; 228 } 229 230 return OK; 231} 232 233status_t StagefrightRecorder::setOutputFormat(output_format of) { 234 ALOGV("setOutputFormat: %d", of); 235 if (of < OUTPUT_FORMAT_DEFAULT || 236 of >= OUTPUT_FORMAT_LIST_END) { 237 ALOGE("Invalid output format: %d", of); 238 return BAD_VALUE; 239 } 240 241 if (of == OUTPUT_FORMAT_DEFAULT) { 242 mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 243 } else { 244 mOutputFormat = of; 245 } 246 247 return OK; 248} 249 250status_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) { 251 ALOGV("setAudioEncoder: %d", ae); 252 if (ae < AUDIO_ENCODER_DEFAULT || 253 ae >= AUDIO_ENCODER_LIST_END) { 254 ALOGE("Invalid audio encoder: %d", ae); 255 return BAD_VALUE; 256 } 257 258 if (ae == AUDIO_ENCODER_DEFAULT) { 259 mAudioEncoder = AUDIO_ENCODER_AMR_NB; 260 } else { 261 mAudioEncoder = ae; 262 } 263 264 return OK; 265} 266 267status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) { 268 ALOGV("setVideoEncoder: %d", ve); 269 if (ve < VIDEO_ENCODER_DEFAULT || 270 ve >= VIDEO_ENCODER_LIST_END) { 271 ALOGE("Invalid video encoder: %d", ve); 272 return BAD_VALUE; 273 } 274 275 mVideoEncoder = ve; 276 277 return OK; 278} 279 280status_t StagefrightRecorder::setVideoSize(int width, int height) { 281 ALOGV("setVideoSize: %dx%d", width, height); 282 if (width <= 0 || height <= 0) { 283 ALOGE("Invalid video size: %dx%d", width, height); 284 return BAD_VALUE; 285 } 286 287 // Additional check on the dimension will be performed later 288 mVideoWidth = width; 289 mVideoHeight = height; 290 291 return OK; 292} 293 294status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { 295 ALOGV("setVideoFrameRate: %d", frames_per_second); 296 if ((frames_per_second <= 0 && frames_per_second != -1) || 297 frames_per_second > kMaxHighSpeedFps) { 298 ALOGE("Invalid video frame rate: %d", frames_per_second); 299 return BAD_VALUE; 300 } 301 302 // Additional check on the frame rate will be performed later 303 mFrameRate = frames_per_second; 304 305 return OK; 306} 307 308status_t StagefrightRecorder::setCamera(const sp<hardware::ICamera> &camera, 309 const sp<ICameraRecordingProxy> &proxy) { 310 ALOGV("setCamera"); 311 if (camera == 0) { 312 ALOGE("camera is NULL"); 313 return BAD_VALUE; 314 } 315 if (proxy == 0) { 316 ALOGE("camera proxy is NULL"); 317 return BAD_VALUE; 318 } 319 320 mCamera = camera; 321 mCameraProxy = proxy; 322 return OK; 323} 324 325status_t StagefrightRecorder::setPreviewSurface(const sp<IGraphicBufferProducer> &surface) { 326 ALOGV("setPreviewSurface: %p", surface.get()); 327 mPreviewSurface = surface; 328 329 return OK; 330} 331 332status_t StagefrightRecorder::setInputSurface( 333 const sp<PersistentSurface>& surface) { 334 mPersistentSurface = surface; 335 336 return OK; 337} 338 339status_t StagefrightRecorder::setOutputFile(int fd) { 340 ALOGV("setOutputFile: %d", fd); 341 342 if (fd < 0) { 343 ALOGE("Invalid file descriptor: %d", fd); 344 return -EBADF; 345 } 346 347 // start with a clean, empty file 348 ftruncate(fd, 0); 349 350 if (mOutputFd >= 0) { 351 ::close(mOutputFd); 352 } 353 mOutputFd = dup(fd); 354 355 return OK; 356} 357 358status_t StagefrightRecorder::setNextOutputFile(int fd) { 359 Mutex::Autolock autolock(mLock); 360 // Only support MPEG4 361 if (mOutputFormat != OUTPUT_FORMAT_MPEG_4) { 362 ALOGE("Only MP4 file format supports setting next output file"); 363 return INVALID_OPERATION; 364 } 365 ALOGV("setNextOutputFile: %d", fd); 366 367 if (fd < 0) { 368 ALOGE("Invalid file descriptor: %d", fd); 369 return -EBADF; 370 } 371 372 // start with a clean, empty file 373 ftruncate(fd, 0); 374 int nextFd = dup(fd); 375 if (mWriter == NULL) { 376 ALOGE("setNextOutputFile failed. Writer has been freed"); 377 return INVALID_OPERATION; 378 } 379 return mWriter->setNextFd(nextFd); 380} 381 382// Attempt to parse an float literal optionally surrounded by whitespace, 383// returns true on success, false otherwise. 384static bool safe_strtof(const char *s, float *val) { 385 char *end; 386 387 // It is lame, but according to man page, we have to set errno to 0 388 // before calling strtof(). 389 errno = 0; 390 *val = strtof(s, &end); 391 392 if (end == s || errno == ERANGE) { 393 return false; 394 } 395 396 // Skip trailing whitespace 397 while (isspace(*end)) { 398 ++end; 399 } 400 401 // For a successful return, the string must contain nothing but a valid 402 // float literal optionally surrounded by whitespace. 403 404 return *end == '\0'; 405} 406 407// Attempt to parse an int64 literal optionally surrounded by whitespace, 408// returns true on success, false otherwise. 409static bool safe_strtoi64(const char *s, int64_t *val) { 410 char *end; 411 412 // It is lame, but according to man page, we have to set errno to 0 413 // before calling strtoll(). 414 errno = 0; 415 *val = strtoll(s, &end, 10); 416 417 if (end == s || errno == ERANGE) { 418 return false; 419 } 420 421 // Skip trailing whitespace 422 while (isspace(*end)) { 423 ++end; 424 } 425 426 // For a successful return, the string must contain nothing but a valid 427 // int64 literal optionally surrounded by whitespace. 428 429 return *end == '\0'; 430} 431 432// Return true if the value is in [0, 0x007FFFFFFF] 433static bool safe_strtoi32(const char *s, int32_t *val) { 434 int64_t temp; 435 if (safe_strtoi64(s, &temp)) { 436 if (temp >= 0 && temp <= 0x007FFFFFFF) { 437 *val = static_cast<int32_t>(temp); 438 return true; 439 } 440 } 441 return false; 442} 443 444// Trim both leading and trailing whitespace from the given string. 445static void TrimString(String8 *s) { 446 size_t num_bytes = s->bytes(); 447 const char *data = s->string(); 448 449 size_t leading_space = 0; 450 while (leading_space < num_bytes && isspace(data[leading_space])) { 451 ++leading_space; 452 } 453 454 size_t i = num_bytes; 455 while (i > leading_space && isspace(data[i - 1])) { 456 --i; 457 } 458 459 s->setTo(String8(&data[leading_space], i - leading_space)); 460} 461 462status_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) { 463 ALOGV("setParamAudioSamplingRate: %d", sampleRate); 464 if (sampleRate <= 0) { 465 ALOGE("Invalid audio sampling rate: %d", sampleRate); 466 return BAD_VALUE; 467 } 468 469 // Additional check on the sample rate will be performed later. 470 mSampleRate = sampleRate; 471 472 return OK; 473} 474 475status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) { 476 ALOGV("setParamAudioNumberOfChannels: %d", channels); 477 if (channels <= 0 || channels >= 3) { 478 ALOGE("Invalid number of audio channels: %d", channels); 479 return BAD_VALUE; 480 } 481 482 // Additional check on the number of channels will be performed later. 483 mAudioChannels = channels; 484 485 return OK; 486} 487 488status_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) { 489 ALOGV("setParamAudioEncodingBitRate: %d", bitRate); 490 if (bitRate <= 0) { 491 ALOGE("Invalid audio encoding bit rate: %d", bitRate); 492 return BAD_VALUE; 493 } 494 495 // The target bit rate may not be exactly the same as the requested. 496 // It depends on many factors, such as rate control, and the bit rate 497 // range that a specific encoder supports. The mismatch between the 498 // the target and requested bit rate will NOT be treated as an error. 499 mAudioBitRate = bitRate; 500 return OK; 501} 502 503status_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) { 504 ALOGV("setParamVideoEncodingBitRate: %d", bitRate); 505 if (bitRate <= 0) { 506 ALOGE("Invalid video encoding bit rate: %d", bitRate); 507 return BAD_VALUE; 508 } 509 510 // The target bit rate may not be exactly the same as the requested. 511 // It depends on many factors, such as rate control, and the bit rate 512 // range that a specific encoder supports. The mismatch between the 513 // the target and requested bit rate will NOT be treated as an error. 514 mVideoBitRate = bitRate; 515 return OK; 516} 517 518// Always rotate clockwise, and only support 0, 90, 180 and 270 for now. 519status_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) { 520 ALOGV("setParamVideoRotation: %d", degrees); 521 if (degrees < 0 || degrees % 90 != 0) { 522 ALOGE("Unsupported video rotation angle: %d", degrees); 523 return BAD_VALUE; 524 } 525 mRotationDegrees = degrees % 360; 526 return OK; 527} 528 529status_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) { 530 ALOGV("setParamMaxFileDurationUs: %lld us", (long long)timeUs); 531 532 // This is meant for backward compatibility for MediaRecorder.java 533 if (timeUs <= 0) { 534 ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", 535 (long long)timeUs); 536 timeUs = 0; // Disable the duration limit for zero or negative values. 537 } else if (timeUs <= 100000LL) { // XXX: 100 milli-seconds 538 ALOGE("Max file duration is too short: %lld us", (long long)timeUs); 539 return BAD_VALUE; 540 } 541 542 if (timeUs <= 15 * 1000000LL) { 543 ALOGW("Target duration (%lld us) too short to be respected", (long long)timeUs); 544 } 545 mMaxFileDurationUs = timeUs; 546 return OK; 547} 548 549status_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) { 550 ALOGV("setParamMaxFileSizeBytes: %lld bytes", (long long)bytes); 551 552 // This is meant for backward compatibility for MediaRecorder.java 553 if (bytes <= 0) { 554 ALOGW("Max file size is not positive: %lld bytes. " 555 "Disabling file size limit.", (long long)bytes); 556 bytes = 0; // Disable the file size limit for zero or negative values. 557 } else if (bytes <= 1024) { // XXX: 1 kB 558 ALOGE("Max file size is too small: %lld bytes", (long long)bytes); 559 return BAD_VALUE; 560 } 561 562 if (bytes <= 100 * 1024) { 563 ALOGW("Target file size (%lld bytes) is too small to be respected", (long long)bytes); 564 } 565 566 mMaxFileSizeBytes = bytes; 567 return OK; 568} 569 570status_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) { 571 ALOGV("setParamInterleaveDuration: %d", durationUs); 572 if (durationUs <= 500000) { // 500 ms 573 // If interleave duration is too small, it is very inefficient to do 574 // interleaving since the metadata overhead will count for a significant 575 // portion of the saved contents 576 ALOGE("Audio/video interleave duration is too small: %d us", durationUs); 577 return BAD_VALUE; 578 } else if (durationUs >= 10000000) { // 10 seconds 579 // If interleaving duration is too large, it can cause the recording 580 // session to use too much memory since we have to save the output 581 // data before we write them out 582 ALOGE("Audio/video interleave duration is too large: %d us", durationUs); 583 return BAD_VALUE; 584 } 585 mInterleaveDurationUs = durationUs; 586 return OK; 587} 588 589// If seconds < 0, only the first frame is I frame, and rest are all P frames 590// If seconds == 0, all frames are encoded as I frames. No P frames 591// If seconds > 0, it is the time spacing (seconds) between 2 neighboring I frames 592status_t StagefrightRecorder::setParamVideoIFramesInterval(int32_t seconds) { 593 ALOGV("setParamVideoIFramesInterval: %d seconds", seconds); 594 mIFramesIntervalSec = seconds; 595 return OK; 596} 597 598status_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit) { 599 ALOGV("setParam64BitFileOffset: %s", 600 use64Bit? "use 64 bit file offset": "use 32 bit file offset"); 601 mUse64BitFileOffset = use64Bit; 602 return OK; 603} 604 605status_t StagefrightRecorder::setParamVideoCameraId(int32_t cameraId) { 606 ALOGV("setParamVideoCameraId: %d", cameraId); 607 if (cameraId < 0) { 608 return BAD_VALUE; 609 } 610 mCameraId = cameraId; 611 return OK; 612} 613 614status_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) { 615 ALOGV("setParamTrackTimeStatus: %lld", (long long)timeDurationUs); 616 if (timeDurationUs < 20000) { // Infeasible if shorter than 20 ms? 617 ALOGE("Tracking time duration too short: %lld us", (long long)timeDurationUs); 618 return BAD_VALUE; 619 } 620 mTrackEveryTimeDurationUs = timeDurationUs; 621 return OK; 622} 623 624status_t StagefrightRecorder::setParamVideoEncoderProfile(int32_t profile) { 625 ALOGV("setParamVideoEncoderProfile: %d", profile); 626 627 // Additional check will be done later when we load the encoder. 628 // For now, we are accepting values defined in OpenMAX IL. 629 mVideoEncoderProfile = profile; 630 return OK; 631} 632 633status_t StagefrightRecorder::setParamVideoEncoderLevel(int32_t level) { 634 ALOGV("setParamVideoEncoderLevel: %d", level); 635 636 // Additional check will be done later when we load the encoder. 637 // For now, we are accepting values defined in OpenMAX IL. 638 mVideoEncoderLevel = level; 639 return OK; 640} 641 642status_t StagefrightRecorder::setParamMovieTimeScale(int32_t timeScale) { 643 ALOGV("setParamMovieTimeScale: %d", timeScale); 644 645 // The range is set to be the same as the audio's time scale range 646 // since audio's time scale has a wider range. 647 if (timeScale < 600 || timeScale > 96000) { 648 ALOGE("Time scale (%d) for movie is out of range [600, 96000]", timeScale); 649 return BAD_VALUE; 650 } 651 mMovieTimeScale = timeScale; 652 return OK; 653} 654 655status_t StagefrightRecorder::setParamVideoTimeScale(int32_t timeScale) { 656 ALOGV("setParamVideoTimeScale: %d", timeScale); 657 658 // 60000 is chosen to make sure that each video frame from a 60-fps 659 // video has 1000 ticks. 660 if (timeScale < 600 || timeScale > 60000) { 661 ALOGE("Time scale (%d) for video is out of range [600, 60000]", timeScale); 662 return BAD_VALUE; 663 } 664 mVideoTimeScale = timeScale; 665 return OK; 666} 667 668status_t StagefrightRecorder::setParamAudioTimeScale(int32_t timeScale) { 669 ALOGV("setParamAudioTimeScale: %d", timeScale); 670 671 // 96000 Hz is the highest sampling rate support in AAC. 672 if (timeScale < 600 || timeScale > 96000) { 673 ALOGE("Time scale (%d) for audio is out of range [600, 96000]", timeScale); 674 return BAD_VALUE; 675 } 676 mAudioTimeScale = timeScale; 677 return OK; 678} 679 680status_t StagefrightRecorder::setParamCaptureFpsEnable(int32_t captureFpsEnable) { 681 ALOGV("setParamCaptureFpsEnable: %d", captureFpsEnable); 682 683 if(captureFpsEnable == 0) { 684 mCaptureFpsEnable = false; 685 } else if (captureFpsEnable == 1) { 686 mCaptureFpsEnable = true; 687 } else { 688 return BAD_VALUE; 689 } 690 return OK; 691} 692 693status_t StagefrightRecorder::setParamCaptureFps(float fps) { 694 ALOGV("setParamCaptureFps: %.2f", fps); 695 696 int64_t timeUs = (int64_t) (1000000.0 / fps + 0.5f); 697 698 // Not allowing time more than a day 699 if (timeUs <= 0 || timeUs > 86400*1E6) { 700 ALOGE("Time between frame capture (%lld) is out of range [0, 1 Day]", (long long)timeUs); 701 return BAD_VALUE; 702 } 703 704 mCaptureFps = fps; 705 mTimeBetweenCaptureUs = timeUs; 706 return OK; 707} 708 709status_t StagefrightRecorder::setParamGeoDataLongitude( 710 int64_t longitudex10000) { 711 712 if (longitudex10000 > 1800000 || longitudex10000 < -1800000) { 713 return BAD_VALUE; 714 } 715 mLongitudex10000 = longitudex10000; 716 return OK; 717} 718 719status_t StagefrightRecorder::setParamGeoDataLatitude( 720 int64_t latitudex10000) { 721 722 if (latitudex10000 > 900000 || latitudex10000 < -900000) { 723 return BAD_VALUE; 724 } 725 mLatitudex10000 = latitudex10000; 726 return OK; 727} 728 729status_t StagefrightRecorder::setParameter( 730 const String8 &key, const String8 &value) { 731 ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string()); 732 if (key == "max-duration") { 733 int64_t max_duration_ms; 734 if (safe_strtoi64(value.string(), &max_duration_ms)) { 735 return setParamMaxFileDurationUs(1000LL * max_duration_ms); 736 } 737 } else if (key == "max-filesize") { 738 int64_t max_filesize_bytes; 739 if (safe_strtoi64(value.string(), &max_filesize_bytes)) { 740 return setParamMaxFileSizeBytes(max_filesize_bytes); 741 } 742 } else if (key == "interleave-duration-us") { 743 int32_t durationUs; 744 if (safe_strtoi32(value.string(), &durationUs)) { 745 return setParamInterleaveDuration(durationUs); 746 } 747 } else if (key == "param-movie-time-scale") { 748 int32_t timeScale; 749 if (safe_strtoi32(value.string(), &timeScale)) { 750 return setParamMovieTimeScale(timeScale); 751 } 752 } else if (key == "param-use-64bit-offset") { 753 int32_t use64BitOffset; 754 if (safe_strtoi32(value.string(), &use64BitOffset)) { 755 return setParam64BitFileOffset(use64BitOffset != 0); 756 } 757 } else if (key == "param-geotag-longitude") { 758 int64_t longitudex10000; 759 if (safe_strtoi64(value.string(), &longitudex10000)) { 760 return setParamGeoDataLongitude(longitudex10000); 761 } 762 } else if (key == "param-geotag-latitude") { 763 int64_t latitudex10000; 764 if (safe_strtoi64(value.string(), &latitudex10000)) { 765 return setParamGeoDataLatitude(latitudex10000); 766 } 767 } else if (key == "param-track-time-status") { 768 int64_t timeDurationUs; 769 if (safe_strtoi64(value.string(), &timeDurationUs)) { 770 return setParamTrackTimeStatus(timeDurationUs); 771 } 772 } else if (key == "audio-param-sampling-rate") { 773 int32_t sampling_rate; 774 if (safe_strtoi32(value.string(), &sampling_rate)) { 775 return setParamAudioSamplingRate(sampling_rate); 776 } 777 } else if (key == "audio-param-number-of-channels") { 778 int32_t number_of_channels; 779 if (safe_strtoi32(value.string(), &number_of_channels)) { 780 return setParamAudioNumberOfChannels(number_of_channels); 781 } 782 } else if (key == "audio-param-encoding-bitrate") { 783 int32_t audio_bitrate; 784 if (safe_strtoi32(value.string(), &audio_bitrate)) { 785 return setParamAudioEncodingBitRate(audio_bitrate); 786 } 787 } else if (key == "audio-param-time-scale") { 788 int32_t timeScale; 789 if (safe_strtoi32(value.string(), &timeScale)) { 790 return setParamAudioTimeScale(timeScale); 791 } 792 } else if (key == "video-param-encoding-bitrate") { 793 int32_t video_bitrate; 794 if (safe_strtoi32(value.string(), &video_bitrate)) { 795 return setParamVideoEncodingBitRate(video_bitrate); 796 } 797 } else if (key == "video-param-rotation-angle-degrees") { 798 int32_t degrees; 799 if (safe_strtoi32(value.string(), °rees)) { 800 return setParamVideoRotation(degrees); 801 } 802 } else if (key == "video-param-i-frames-interval") { 803 int32_t seconds; 804 if (safe_strtoi32(value.string(), &seconds)) { 805 return setParamVideoIFramesInterval(seconds); 806 } 807 } else if (key == "video-param-encoder-profile") { 808 int32_t profile; 809 if (safe_strtoi32(value.string(), &profile)) { 810 return setParamVideoEncoderProfile(profile); 811 } 812 } else if (key == "video-param-encoder-level") { 813 int32_t level; 814 if (safe_strtoi32(value.string(), &level)) { 815 return setParamVideoEncoderLevel(level); 816 } 817 } else if (key == "video-param-camera-id") { 818 int32_t cameraId; 819 if (safe_strtoi32(value.string(), &cameraId)) { 820 return setParamVideoCameraId(cameraId); 821 } 822 } else if (key == "video-param-time-scale") { 823 int32_t timeScale; 824 if (safe_strtoi32(value.string(), &timeScale)) { 825 return setParamVideoTimeScale(timeScale); 826 } 827 } else if (key == "time-lapse-enable") { 828 int32_t captureFpsEnable; 829 if (safe_strtoi32(value.string(), &captureFpsEnable)) { 830 return setParamCaptureFpsEnable(captureFpsEnable); 831 } 832 } else if (key == "time-lapse-fps") { 833 float fps; 834 if (safe_strtof(value.string(), &fps)) { 835 return setParamCaptureFps(fps); 836 } 837 } else { 838 ALOGE("setParameter: failed to find key %s", key.string()); 839 } 840 return BAD_VALUE; 841} 842 843status_t StagefrightRecorder::setParameters(const String8 ¶ms) { 844 ALOGV("setParameters: %s", params.string()); 845 const char *cparams = params.string(); 846 const char *key_start = cparams; 847 for (;;) { 848 const char *equal_pos = strchr(key_start, '='); 849 if (equal_pos == NULL) { 850 ALOGE("Parameters %s miss a value", cparams); 851 return BAD_VALUE; 852 } 853 String8 key(key_start, equal_pos - key_start); 854 TrimString(&key); 855 if (key.length() == 0) { 856 ALOGE("Parameters %s contains an empty key", cparams); 857 return BAD_VALUE; 858 } 859 const char *value_start = equal_pos + 1; 860 const char *semicolon_pos = strchr(value_start, ';'); 861 String8 value; 862 if (semicolon_pos == NULL) { 863 value.setTo(value_start); 864 } else { 865 value.setTo(value_start, semicolon_pos - value_start); 866 } 867 if (setParameter(key, value) != OK) { 868 return BAD_VALUE; 869 } 870 if (semicolon_pos == NULL) { 871 break; // Reaches the end 872 } 873 key_start = semicolon_pos + 1; 874 } 875 return OK; 876} 877 878status_t StagefrightRecorder::setListener(const sp<IMediaRecorderClient> &listener) { 879 mListener = listener; 880 881 return OK; 882} 883 884status_t StagefrightRecorder::setClientName(const String16& clientName) { 885 mClientName = clientName; 886 887 return OK; 888} 889 890status_t StagefrightRecorder::prepareInternal() { 891 ALOGV("prepare"); 892 if (mOutputFd < 0) { 893 ALOGE("Output file descriptor is invalid"); 894 return INVALID_OPERATION; 895 } 896 897 // Get UID and PID here for permission checking 898 mClientUid = IPCThreadState::self()->getCallingUid(); 899 mClientPid = IPCThreadState::self()->getCallingPid(); 900 901 status_t status = OK; 902 903 switch (mOutputFormat) { 904 case OUTPUT_FORMAT_DEFAULT: 905 case OUTPUT_FORMAT_THREE_GPP: 906 case OUTPUT_FORMAT_MPEG_4: 907 case OUTPUT_FORMAT_WEBM: 908 status = setupMPEG4orWEBMRecording(); 909 break; 910 911 case OUTPUT_FORMAT_AMR_NB: 912 case OUTPUT_FORMAT_AMR_WB: 913 status = setupAMRRecording(); 914 break; 915 916 case OUTPUT_FORMAT_AAC_ADIF: 917 case OUTPUT_FORMAT_AAC_ADTS: 918 status = setupAACRecording(); 919 break; 920 921 case OUTPUT_FORMAT_RTP_AVP: 922 status = setupRTPRecording(); 923 break; 924 925 case OUTPUT_FORMAT_MPEG2TS: 926 status = setupMPEG2TSRecording(); 927 break; 928 929 default: 930 ALOGE("Unsupported output file format: %d", mOutputFormat); 931 status = UNKNOWN_ERROR; 932 break; 933 } 934 935 ALOGV("Recording frameRate: %d captureFps: %f", 936 mFrameRate, mCaptureFps); 937 938 return status; 939} 940 941status_t StagefrightRecorder::prepare() { 942 ALOGV("prepare"); 943 Mutex::Autolock autolock(mLock); 944 if (mVideoSource == VIDEO_SOURCE_SURFACE) { 945 return prepareInternal(); 946 } 947 return OK; 948} 949 950status_t StagefrightRecorder::start() { 951 ALOGV("start"); 952 Mutex::Autolock autolock(mLock); 953 if (mOutputFd < 0) { 954 ALOGE("Output file descriptor is invalid"); 955 return INVALID_OPERATION; 956 } 957 958 status_t status = OK; 959 960 if (mVideoSource != VIDEO_SOURCE_SURFACE) { 961 status = prepareInternal(); 962 if (status != OK) { 963 return status; 964 } 965 } 966 967 if (mWriter == NULL) { 968 ALOGE("File writer is not avaialble"); 969 return UNKNOWN_ERROR; 970 } 971 972 switch (mOutputFormat) { 973 case OUTPUT_FORMAT_DEFAULT: 974 case OUTPUT_FORMAT_THREE_GPP: 975 case OUTPUT_FORMAT_MPEG_4: 976 case OUTPUT_FORMAT_WEBM: 977 { 978 bool isMPEG4 = true; 979 if (mOutputFormat == OUTPUT_FORMAT_WEBM) { 980 isMPEG4 = false; 981 } 982 sp<MetaData> meta = new MetaData; 983 setupMPEG4orWEBMMetaData(&meta); 984 status = mWriter->start(meta.get()); 985 break; 986 } 987 988 case OUTPUT_FORMAT_AMR_NB: 989 case OUTPUT_FORMAT_AMR_WB: 990 case OUTPUT_FORMAT_AAC_ADIF: 991 case OUTPUT_FORMAT_AAC_ADTS: 992 case OUTPUT_FORMAT_RTP_AVP: 993 case OUTPUT_FORMAT_MPEG2TS: 994 { 995 sp<MetaData> meta = new MetaData; 996 int64_t startTimeUs = systemTime() / 1000; 997 meta->setInt64(kKeyTime, startTimeUs); 998 status = mWriter->start(meta.get()); 999 break; 1000 } 1001 1002 default: 1003 { 1004 ALOGE("Unsupported output file format: %d", mOutputFormat); 1005 status = UNKNOWN_ERROR; 1006 break; 1007 } 1008 } 1009 1010 if (status != OK) { 1011 mWriter.clear(); 1012 mWriter = NULL; 1013 } 1014 1015 if ((status == OK) && (!mStarted)) { 1016 mAnalyticsDirty = true; 1017 mStarted = true; 1018 1019 uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted; 1020 if (mAudioSource != AUDIO_SOURCE_CNT) { 1021 params |= IMediaPlayerService::kBatteryDataTrackAudio; 1022 } 1023 if (mVideoSource != VIDEO_SOURCE_LIST_END) { 1024 params |= IMediaPlayerService::kBatteryDataTrackVideo; 1025 } 1026 1027 addBatteryData(params); 1028 } 1029 1030 return status; 1031} 1032 1033sp<MediaCodecSource> StagefrightRecorder::createAudioSource() { 1034 int32_t sourceSampleRate = mSampleRate; 1035 1036 if (mCaptureFpsEnable && mCaptureFps >= mFrameRate) { 1037 // Upscale the sample rate for slow motion recording. 1038 // Fail audio source creation if source sample rate is too high, as it could 1039 // cause out-of-memory due to large input buffer size. And audio recording 1040 // probably doesn't make sense in the scenario, since the slow-down factor 1041 // is probably huge (eg. mSampleRate=48K, mCaptureFps=240, mFrameRate=1). 1042 const static int32_t SAMPLE_RATE_HZ_MAX = 192000; 1043 sourceSampleRate = 1044 (mSampleRate * mCaptureFps + mFrameRate / 2) / mFrameRate; 1045 if (sourceSampleRate < mSampleRate || sourceSampleRate > SAMPLE_RATE_HZ_MAX) { 1046 ALOGE("source sample rate out of range! " 1047 "(mSampleRate %d, mCaptureFps %.2f, mFrameRate %d", 1048 mSampleRate, mCaptureFps, mFrameRate); 1049 return NULL; 1050 } 1051 } 1052 1053 sp<AudioSource> audioSource = 1054 new AudioSource( 1055 mAudioSource, 1056 mOpPackageName, 1057 sourceSampleRate, 1058 mAudioChannels, 1059 mSampleRate, 1060 mClientUid, 1061 mClientPid); 1062 1063 status_t err = audioSource->initCheck(); 1064 1065 if (err != OK) { 1066 ALOGE("audio source is not initialized"); 1067 return NULL; 1068 } 1069 1070 sp<AMessage> format = new AMessage; 1071 switch (mAudioEncoder) { 1072 case AUDIO_ENCODER_AMR_NB: 1073 case AUDIO_ENCODER_DEFAULT: 1074 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB); 1075 break; 1076 case AUDIO_ENCODER_AMR_WB: 1077 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB); 1078 break; 1079 case AUDIO_ENCODER_AAC: 1080 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 1081 format->setInt32("aac-profile", OMX_AUDIO_AACObjectLC); 1082 break; 1083 case AUDIO_ENCODER_HE_AAC: 1084 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 1085 format->setInt32("aac-profile", OMX_AUDIO_AACObjectHE); 1086 break; 1087 case AUDIO_ENCODER_AAC_ELD: 1088 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC); 1089 format->setInt32("aac-profile", OMX_AUDIO_AACObjectELD); 1090 break; 1091 1092 default: 1093 ALOGE("Unknown audio encoder: %d", mAudioEncoder); 1094 return NULL; 1095 } 1096 1097 int32_t maxInputSize; 1098 CHECK(audioSource->getFormat()->findInt32( 1099 kKeyMaxInputSize, &maxInputSize)); 1100 1101 format->setInt32("max-input-size", maxInputSize); 1102 format->setInt32("channel-count", mAudioChannels); 1103 format->setInt32("sample-rate", mSampleRate); 1104 format->setInt32("bitrate", mAudioBitRate); 1105 if (mAudioTimeScale > 0) { 1106 format->setInt32("time-scale", mAudioTimeScale); 1107 } 1108 format->setInt32("priority", 0 /* realtime */); 1109 1110 sp<MediaCodecSource> audioEncoder = 1111 MediaCodecSource::Create(mLooper, format, audioSource); 1112 mAudioSourceNode = audioSource; 1113 1114 if (audioEncoder == NULL) { 1115 ALOGE("Failed to create audio encoder"); 1116 } 1117 1118 return audioEncoder; 1119} 1120 1121status_t StagefrightRecorder::setupAACRecording() { 1122 // FIXME: 1123 // Add support for OUTPUT_FORMAT_AAC_ADIF 1124 CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_AAC_ADTS); 1125 1126 CHECK(mAudioEncoder == AUDIO_ENCODER_AAC || 1127 mAudioEncoder == AUDIO_ENCODER_HE_AAC || 1128 mAudioEncoder == AUDIO_ENCODER_AAC_ELD); 1129 CHECK(mAudioSource != AUDIO_SOURCE_CNT); 1130 1131 mWriter = new AACWriter(mOutputFd); 1132 return setupRawAudioRecording(); 1133} 1134 1135status_t StagefrightRecorder::setupAMRRecording() { 1136 CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB || 1137 mOutputFormat == OUTPUT_FORMAT_AMR_WB); 1138 1139 if (mOutputFormat == OUTPUT_FORMAT_AMR_NB) { 1140 if (mAudioEncoder != AUDIO_ENCODER_DEFAULT && 1141 mAudioEncoder != AUDIO_ENCODER_AMR_NB) { 1142 ALOGE("Invalid encoder %d used for AMRNB recording", 1143 mAudioEncoder); 1144 return BAD_VALUE; 1145 } 1146 } else { // mOutputFormat must be OUTPUT_FORMAT_AMR_WB 1147 if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) { 1148 ALOGE("Invlaid encoder %d used for AMRWB recording", 1149 mAudioEncoder); 1150 return BAD_VALUE; 1151 } 1152 } 1153 1154 mWriter = new AMRWriter(mOutputFd); 1155 return setupRawAudioRecording(); 1156} 1157 1158status_t StagefrightRecorder::setupRawAudioRecording() { 1159 if (mAudioSource >= AUDIO_SOURCE_CNT && mAudioSource != AUDIO_SOURCE_FM_TUNER) { 1160 ALOGE("Invalid audio source: %d", mAudioSource); 1161 return BAD_VALUE; 1162 } 1163 1164 status_t status = BAD_VALUE; 1165 if (OK != (status = checkAudioEncoderCapabilities())) { 1166 return status; 1167 } 1168 1169 sp<MediaCodecSource> audioEncoder = createAudioSource(); 1170 if (audioEncoder == NULL) { 1171 return UNKNOWN_ERROR; 1172 } 1173 1174 CHECK(mWriter != 0); 1175 mWriter->addSource(audioEncoder); 1176 mAudioEncoderSource = audioEncoder; 1177 1178 if (mMaxFileDurationUs != 0) { 1179 mWriter->setMaxFileDuration(mMaxFileDurationUs); 1180 } 1181 if (mMaxFileSizeBytes != 0) { 1182 mWriter->setMaxFileSize(mMaxFileSizeBytes); 1183 } 1184 mWriter->setListener(mListener); 1185 1186 return OK; 1187} 1188 1189status_t StagefrightRecorder::setupRTPRecording() { 1190 CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_RTP_AVP); 1191 1192 if ((mAudioSource != AUDIO_SOURCE_CNT 1193 && mVideoSource != VIDEO_SOURCE_LIST_END) 1194 || (mAudioSource == AUDIO_SOURCE_CNT 1195 && mVideoSource == VIDEO_SOURCE_LIST_END)) { 1196 // Must have exactly one source. 1197 return BAD_VALUE; 1198 } 1199 1200 if (mOutputFd < 0) { 1201 return BAD_VALUE; 1202 } 1203 1204 sp<MediaCodecSource> source; 1205 1206 if (mAudioSource != AUDIO_SOURCE_CNT) { 1207 source = createAudioSource(); 1208 mAudioEncoderSource = source; 1209 } else { 1210 setDefaultVideoEncoderIfNecessary(); 1211 1212 sp<MediaSource> mediaSource; 1213 status_t err = setupMediaSource(&mediaSource); 1214 if (err != OK) { 1215 return err; 1216 } 1217 1218 err = setupVideoEncoder(mediaSource, &source); 1219 if (err != OK) { 1220 return err; 1221 } 1222 mVideoEncoderSource = source; 1223 } 1224 1225 mWriter = new ARTPWriter(mOutputFd); 1226 mWriter->addSource(source); 1227 mWriter->setListener(mListener); 1228 1229 return OK; 1230} 1231 1232status_t StagefrightRecorder::setupMPEG2TSRecording() { 1233 CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_MPEG2TS); 1234 1235 sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd); 1236 1237 if (mAudioSource != AUDIO_SOURCE_CNT) { 1238 if (mAudioEncoder != AUDIO_ENCODER_AAC && 1239 mAudioEncoder != AUDIO_ENCODER_HE_AAC && 1240 mAudioEncoder != AUDIO_ENCODER_AAC_ELD) { 1241 return ERROR_UNSUPPORTED; 1242 } 1243 1244 status_t err = setupAudioEncoder(writer); 1245 1246 if (err != OK) { 1247 return err; 1248 } 1249 } 1250 1251 if (mVideoSource < VIDEO_SOURCE_LIST_END) { 1252 if (mVideoEncoder != VIDEO_ENCODER_H264) { 1253 ALOGE("MPEG2TS recording only supports H.264 encoding!"); 1254 return ERROR_UNSUPPORTED; 1255 } 1256 1257 sp<MediaSource> mediaSource; 1258 status_t err = setupMediaSource(&mediaSource); 1259 if (err != OK) { 1260 return err; 1261 } 1262 1263 sp<MediaCodecSource> encoder; 1264 err = setupVideoEncoder(mediaSource, &encoder); 1265 1266 if (err != OK) { 1267 return err; 1268 } 1269 1270 writer->addSource(encoder); 1271 mVideoEncoderSource = encoder; 1272 } 1273 1274 if (mMaxFileDurationUs != 0) { 1275 writer->setMaxFileDuration(mMaxFileDurationUs); 1276 } 1277 1278 if (mMaxFileSizeBytes != 0) { 1279 writer->setMaxFileSize(mMaxFileSizeBytes); 1280 } 1281 1282 mWriter = writer; 1283 1284 return OK; 1285} 1286 1287void StagefrightRecorder::clipVideoFrameRate() { 1288 ALOGV("clipVideoFrameRate: encoder %d", mVideoEncoder); 1289 if (mFrameRate == -1) { 1290 mFrameRate = mEncoderProfiles->getCamcorderProfileParamByName( 1291 "vid.fps", mCameraId, CAMCORDER_QUALITY_LOW); 1292 ALOGW("Using default video fps %d", mFrameRate); 1293 } 1294 1295 int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 1296 "enc.vid.fps.min", mVideoEncoder); 1297 int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName( 1298 "enc.vid.fps.max", mVideoEncoder); 1299 if (mFrameRate < minFrameRate && minFrameRate != -1) { 1300 ALOGW("Intended video encoding frame rate (%d fps) is too small" 1301 " and will be set to (%d fps)", mFrameRate, minFrameRate); 1302 mFrameRate = minFrameRate; 1303 } else if (mFrameRate > maxFrameRate && maxFrameRate != -1) { 1304 ALOGW("Intended video encoding frame rate (%d fps) is too large" 1305 " and will be set to (%d fps)", mFrameRate, maxFrameRate); 1306 mFrameRate = maxFrameRate; 1307 } 1308} 1309 1310void StagefrightRecorder::clipVideoBitRate() { 1311 ALOGV("clipVideoBitRate: encoder %d", mVideoEncoder); 1312 int minBitRate = mEncoderProfiles->getVideoEncoderParamByName( 1313 "enc.vid.bps.min", mVideoEncoder); 1314 int maxBitRate = mEncoderProfiles->getVideoEncoderParamByName( 1315 "enc.vid.bps.max", mVideoEncoder); 1316 if (mVideoBitRate < minBitRate && minBitRate != -1) { 1317 ALOGW("Intended video encoding bit rate (%d bps) is too small" 1318 " and will be set to (%d bps)", mVideoBitRate, minBitRate); 1319 mVideoBitRate = minBitRate; 1320 } else if (mVideoBitRate > maxBitRate && maxBitRate != -1) { 1321 ALOGW("Intended video encoding bit rate (%d bps) is too large" 1322 " and will be set to (%d bps)", mVideoBitRate, maxBitRate); 1323 mVideoBitRate = maxBitRate; 1324 } 1325} 1326 1327void StagefrightRecorder::clipVideoFrameWidth() { 1328 ALOGV("clipVideoFrameWidth: encoder %d", mVideoEncoder); 1329 int minFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 1330 "enc.vid.width.min", mVideoEncoder); 1331 int maxFrameWidth = mEncoderProfiles->getVideoEncoderParamByName( 1332 "enc.vid.width.max", mVideoEncoder); 1333 if (mVideoWidth < minFrameWidth && minFrameWidth != -1) { 1334 ALOGW("Intended video encoding frame width (%d) is too small" 1335 " and will be set to (%d)", mVideoWidth, minFrameWidth); 1336 mVideoWidth = minFrameWidth; 1337 } else if (mVideoWidth > maxFrameWidth && maxFrameWidth != -1) { 1338 ALOGW("Intended video encoding frame width (%d) is too large" 1339 " and will be set to (%d)", mVideoWidth, maxFrameWidth); 1340 mVideoWidth = maxFrameWidth; 1341 } 1342} 1343 1344status_t StagefrightRecorder::checkVideoEncoderCapabilities() { 1345 if (!mCaptureFpsEnable) { 1346 // Dont clip for time lapse capture as encoder will have enough 1347 // time to encode because of slow capture rate of time lapse. 1348 clipVideoBitRate(); 1349 clipVideoFrameRate(); 1350 clipVideoFrameWidth(); 1351 clipVideoFrameHeight(); 1352 setDefaultProfileIfNecessary(); 1353 } 1354 return OK; 1355} 1356 1357// Set to use AVC baseline profile if the encoding parameters matches 1358// CAMCORDER_QUALITY_LOW profile; this is for the sake of MMS service. 1359void StagefrightRecorder::setDefaultProfileIfNecessary() { 1360 ALOGV("setDefaultProfileIfNecessary"); 1361 1362 camcorder_quality quality = CAMCORDER_QUALITY_LOW; 1363 1364 int64_t durationUs = mEncoderProfiles->getCamcorderProfileParamByName( 1365 "duration", mCameraId, quality) * 1000000LL; 1366 1367 int fileFormat = mEncoderProfiles->getCamcorderProfileParamByName( 1368 "file.format", mCameraId, quality); 1369 1370 int videoCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1371 "vid.codec", mCameraId, quality); 1372 1373 int videoBitRate = mEncoderProfiles->getCamcorderProfileParamByName( 1374 "vid.bps", mCameraId, quality); 1375 1376 int videoFrameRate = mEncoderProfiles->getCamcorderProfileParamByName( 1377 "vid.fps", mCameraId, quality); 1378 1379 int videoFrameWidth = mEncoderProfiles->getCamcorderProfileParamByName( 1380 "vid.width", mCameraId, quality); 1381 1382 int videoFrameHeight = mEncoderProfiles->getCamcorderProfileParamByName( 1383 "vid.height", mCameraId, quality); 1384 1385 int audioCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1386 "aud.codec", mCameraId, quality); 1387 1388 int audioBitRate = mEncoderProfiles->getCamcorderProfileParamByName( 1389 "aud.bps", mCameraId, quality); 1390 1391 int audioSampleRate = mEncoderProfiles->getCamcorderProfileParamByName( 1392 "aud.hz", mCameraId, quality); 1393 1394 int audioChannels = mEncoderProfiles->getCamcorderProfileParamByName( 1395 "aud.ch", mCameraId, quality); 1396 1397 if (durationUs == mMaxFileDurationUs && 1398 fileFormat == mOutputFormat && 1399 videoCodec == mVideoEncoder && 1400 videoBitRate == mVideoBitRate && 1401 videoFrameRate == mFrameRate && 1402 videoFrameWidth == mVideoWidth && 1403 videoFrameHeight == mVideoHeight && 1404 audioCodec == mAudioEncoder && 1405 audioBitRate == mAudioBitRate && 1406 audioSampleRate == mSampleRate && 1407 audioChannels == mAudioChannels) { 1408 if (videoCodec == VIDEO_ENCODER_H264) { 1409 ALOGI("Force to use AVC baseline profile"); 1410 setParamVideoEncoderProfile(OMX_VIDEO_AVCProfileBaseline); 1411 // set 0 for invalid levels - this will be rejected by the 1412 // codec if it cannot handle it during configure 1413 setParamVideoEncoderLevel(ACodec::getAVCLevelFor( 1414 videoFrameWidth, videoFrameHeight, videoFrameRate, videoBitRate)); 1415 } 1416 } 1417} 1418 1419void StagefrightRecorder::setDefaultVideoEncoderIfNecessary() { 1420 if (mVideoEncoder == VIDEO_ENCODER_DEFAULT) { 1421 if (mOutputFormat == OUTPUT_FORMAT_WEBM) { 1422 // default to VP8 for WEBM recording 1423 mVideoEncoder = VIDEO_ENCODER_VP8; 1424 } else { 1425 // pick the default encoder for CAMCORDER_QUALITY_LOW 1426 int videoCodec = mEncoderProfiles->getCamcorderProfileParamByName( 1427 "vid.codec", mCameraId, CAMCORDER_QUALITY_LOW); 1428 1429 if (videoCodec > VIDEO_ENCODER_DEFAULT && 1430 videoCodec < VIDEO_ENCODER_LIST_END) { 1431 mVideoEncoder = (video_encoder)videoCodec; 1432 } else { 1433 // default to H.264 if camcorder profile not available 1434 mVideoEncoder = VIDEO_ENCODER_H264; 1435 } 1436 } 1437 } 1438} 1439 1440status_t StagefrightRecorder::checkAudioEncoderCapabilities() { 1441 clipAudioBitRate(); 1442 clipAudioSampleRate(); 1443 clipNumberOfAudioChannels(); 1444 return OK; 1445} 1446 1447void StagefrightRecorder::clipAudioBitRate() { 1448 ALOGV("clipAudioBitRate: encoder %d", mAudioEncoder); 1449 1450 int minAudioBitRate = 1451 mEncoderProfiles->getAudioEncoderParamByName( 1452 "enc.aud.bps.min", mAudioEncoder); 1453 if (minAudioBitRate != -1 && mAudioBitRate < minAudioBitRate) { 1454 ALOGW("Intended audio encoding bit rate (%d) is too small" 1455 " and will be set to (%d)", mAudioBitRate, minAudioBitRate); 1456 mAudioBitRate = minAudioBitRate; 1457 } 1458 1459 int maxAudioBitRate = 1460 mEncoderProfiles->getAudioEncoderParamByName( 1461 "enc.aud.bps.max", mAudioEncoder); 1462 if (maxAudioBitRate != -1 && mAudioBitRate > maxAudioBitRate) { 1463 ALOGW("Intended audio encoding bit rate (%d) is too large" 1464 " and will be set to (%d)", mAudioBitRate, maxAudioBitRate); 1465 mAudioBitRate = maxAudioBitRate; 1466 } 1467} 1468 1469void StagefrightRecorder::clipAudioSampleRate() { 1470 ALOGV("clipAudioSampleRate: encoder %d", mAudioEncoder); 1471 1472 int minSampleRate = 1473 mEncoderProfiles->getAudioEncoderParamByName( 1474 "enc.aud.hz.min", mAudioEncoder); 1475 if (minSampleRate != -1 && mSampleRate < minSampleRate) { 1476 ALOGW("Intended audio sample rate (%d) is too small" 1477 " and will be set to (%d)", mSampleRate, minSampleRate); 1478 mSampleRate = minSampleRate; 1479 } 1480 1481 int maxSampleRate = 1482 mEncoderProfiles->getAudioEncoderParamByName( 1483 "enc.aud.hz.max", mAudioEncoder); 1484 if (maxSampleRate != -1 && mSampleRate > maxSampleRate) { 1485 ALOGW("Intended audio sample rate (%d) is too large" 1486 " and will be set to (%d)", mSampleRate, maxSampleRate); 1487 mSampleRate = maxSampleRate; 1488 } 1489} 1490 1491void StagefrightRecorder::clipNumberOfAudioChannels() { 1492 ALOGV("clipNumberOfAudioChannels: encoder %d", mAudioEncoder); 1493 1494 int minChannels = 1495 mEncoderProfiles->getAudioEncoderParamByName( 1496 "enc.aud.ch.min", mAudioEncoder); 1497 if (minChannels != -1 && mAudioChannels < minChannels) { 1498 ALOGW("Intended number of audio channels (%d) is too small" 1499 " and will be set to (%d)", mAudioChannels, minChannels); 1500 mAudioChannels = minChannels; 1501 } 1502 1503 int maxChannels = 1504 mEncoderProfiles->getAudioEncoderParamByName( 1505 "enc.aud.ch.max", mAudioEncoder); 1506 if (maxChannels != -1 && mAudioChannels > maxChannels) { 1507 ALOGW("Intended number of audio channels (%d) is too large" 1508 " and will be set to (%d)", mAudioChannels, maxChannels); 1509 mAudioChannels = maxChannels; 1510 } 1511} 1512 1513void StagefrightRecorder::clipVideoFrameHeight() { 1514 ALOGV("clipVideoFrameHeight: encoder %d", mVideoEncoder); 1515 int minFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 1516 "enc.vid.height.min", mVideoEncoder); 1517 int maxFrameHeight = mEncoderProfiles->getVideoEncoderParamByName( 1518 "enc.vid.height.max", mVideoEncoder); 1519 if (minFrameHeight != -1 && mVideoHeight < minFrameHeight) { 1520 ALOGW("Intended video encoding frame height (%d) is too small" 1521 " and will be set to (%d)", mVideoHeight, minFrameHeight); 1522 mVideoHeight = minFrameHeight; 1523 } else if (maxFrameHeight != -1 && mVideoHeight > maxFrameHeight) { 1524 ALOGW("Intended video encoding frame height (%d) is too large" 1525 " and will be set to (%d)", mVideoHeight, maxFrameHeight); 1526 mVideoHeight = maxFrameHeight; 1527 } 1528} 1529 1530// Set up the appropriate MediaSource depending on the chosen option 1531status_t StagefrightRecorder::setupMediaSource( 1532 sp<MediaSource> *mediaSource) { 1533 if (mVideoSource == VIDEO_SOURCE_DEFAULT 1534 || mVideoSource == VIDEO_SOURCE_CAMERA) { 1535 sp<CameraSource> cameraSource; 1536 status_t err = setupCameraSource(&cameraSource); 1537 if (err != OK) { 1538 return err; 1539 } 1540 *mediaSource = cameraSource; 1541 } else if (mVideoSource == VIDEO_SOURCE_SURFACE) { 1542 *mediaSource = NULL; 1543 } else { 1544 return INVALID_OPERATION; 1545 } 1546 return OK; 1547} 1548 1549status_t StagefrightRecorder::setupCameraSource( 1550 sp<CameraSource> *cameraSource) { 1551 status_t err = OK; 1552 if ((err = checkVideoEncoderCapabilities()) != OK) { 1553 return err; 1554 } 1555 Size videoSize; 1556 videoSize.width = mVideoWidth; 1557 videoSize.height = mVideoHeight; 1558 if (mCaptureFpsEnable) { 1559 if (mTimeBetweenCaptureUs < 0) { 1560 ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %lld", 1561 (long long)mTimeBetweenCaptureUs); 1562 return BAD_VALUE; 1563 } 1564 1565 mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera( 1566 mCamera, mCameraProxy, mCameraId, mClientName, mClientUid, mClientPid, 1567 videoSize, mFrameRate, mPreviewSurface, 1568 mTimeBetweenCaptureUs); 1569 *cameraSource = mCameraSourceTimeLapse; 1570 } else { 1571 *cameraSource = CameraSource::CreateFromCamera( 1572 mCamera, mCameraProxy, mCameraId, mClientName, mClientUid, mClientPid, 1573 videoSize, mFrameRate, 1574 mPreviewSurface); 1575 } 1576 mCamera.clear(); 1577 mCameraProxy.clear(); 1578 if (*cameraSource == NULL) { 1579 return UNKNOWN_ERROR; 1580 } 1581 1582 if ((*cameraSource)->initCheck() != OK) { 1583 (*cameraSource).clear(); 1584 *cameraSource = NULL; 1585 return NO_INIT; 1586 } 1587 1588 // When frame rate is not set, the actual frame rate will be set to 1589 // the current frame rate being used. 1590 if (mFrameRate == -1) { 1591 int32_t frameRate = 0; 1592 CHECK ((*cameraSource)->getFormat()->findInt32( 1593 kKeyFrameRate, &frameRate)); 1594 ALOGI("Frame rate is not explicitly set. Use the current frame " 1595 "rate (%d fps)", frameRate); 1596 mFrameRate = frameRate; 1597 } 1598 1599 CHECK(mFrameRate != -1); 1600 1601 mMetaDataStoredInVideoBuffers = 1602 (*cameraSource)->metaDataStoredInVideoBuffers(); 1603 1604 return OK; 1605} 1606 1607status_t StagefrightRecorder::setupVideoEncoder( 1608 const sp<MediaSource> &cameraSource, 1609 sp<MediaCodecSource> *source) { 1610 source->clear(); 1611 1612 sp<AMessage> format = new AMessage(); 1613 1614 switch (mVideoEncoder) { 1615 case VIDEO_ENCODER_H263: 1616 format->setString("mime", MEDIA_MIMETYPE_VIDEO_H263); 1617 break; 1618 1619 case VIDEO_ENCODER_MPEG_4_SP: 1620 format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4); 1621 break; 1622 1623 case VIDEO_ENCODER_H264: 1624 format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC); 1625 break; 1626 1627 case VIDEO_ENCODER_VP8: 1628 format->setString("mime", MEDIA_MIMETYPE_VIDEO_VP8); 1629 break; 1630 1631 case VIDEO_ENCODER_HEVC: 1632 format->setString("mime", MEDIA_MIMETYPE_VIDEO_HEVC); 1633 break; 1634 1635 default: 1636 CHECK(!"Should not be here, unsupported video encoding."); 1637 break; 1638 } 1639 1640 if (cameraSource != NULL) { 1641 sp<MetaData> meta = cameraSource->getFormat(); 1642 1643 int32_t width, height, stride, sliceHeight, colorFormat; 1644 CHECK(meta->findInt32(kKeyWidth, &width)); 1645 CHECK(meta->findInt32(kKeyHeight, &height)); 1646 CHECK(meta->findInt32(kKeyStride, &stride)); 1647 CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight)); 1648 CHECK(meta->findInt32(kKeyColorFormat, &colorFormat)); 1649 1650 format->setInt32("width", width); 1651 format->setInt32("height", height); 1652 format->setInt32("stride", stride); 1653 format->setInt32("slice-height", sliceHeight); 1654 format->setInt32("color-format", colorFormat); 1655 } else { 1656 format->setInt32("width", mVideoWidth); 1657 format->setInt32("height", mVideoHeight); 1658 format->setInt32("stride", mVideoWidth); 1659 format->setInt32("slice-height", mVideoHeight); 1660 format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque); 1661 1662 // set up time lapse/slow motion for surface source 1663 if (mCaptureFpsEnable) { 1664 if (mTimeBetweenCaptureUs <= 0) { 1665 ALOGE("Invalid mTimeBetweenCaptureUs value: %lld", 1666 (long long)mTimeBetweenCaptureUs); 1667 return BAD_VALUE; 1668 } 1669 format->setInt64("time-lapse", mTimeBetweenCaptureUs); 1670 } 1671 } 1672 1673 format->setInt32("bitrate", mVideoBitRate); 1674 format->setInt32("frame-rate", mFrameRate); 1675 format->setInt32("i-frame-interval", mIFramesIntervalSec); 1676 1677 if (mVideoTimeScale > 0) { 1678 format->setInt32("time-scale", mVideoTimeScale); 1679 } 1680 if (mVideoEncoderProfile != -1) { 1681 format->setInt32("profile", mVideoEncoderProfile); 1682 } 1683 if (mVideoEncoderLevel != -1) { 1684 format->setInt32("level", mVideoEncoderLevel); 1685 } 1686 1687 uint32_t tsLayers = 1; 1688 bool preferBFrames = true; // we like B-frames as it produces better quality per bitrate 1689 format->setInt32("priority", 0 /* realtime */); 1690 float maxPlaybackFps = mFrameRate; // assume video is only played back at normal speed 1691 1692 if (mCaptureFpsEnable) { 1693 format->setFloat("operating-rate", mCaptureFps); 1694 1695 // enable layering for all time lapse and high frame rate recordings 1696 if (mFrameRate / mCaptureFps >= 1.9) { // time lapse 1697 preferBFrames = false; 1698 tsLayers = 2; // use at least two layers as resulting video will likely be sped up 1699 } else if (mCaptureFps > maxPlaybackFps) { // slow-mo 1700 maxPlaybackFps = mCaptureFps; // assume video will be played back at full capture speed 1701 preferBFrames = false; 1702 } 1703 } 1704 1705 for (uint32_t tryLayers = 1; tryLayers <= kMaxNumVideoTemporalLayers; ++tryLayers) { 1706 if (tryLayers > tsLayers) { 1707 tsLayers = tryLayers; 1708 } 1709 // keep going until the base layer fps falls below the typical display refresh rate 1710 float baseLayerFps = maxPlaybackFps / (1 << (tryLayers - 1)); 1711 if (baseLayerFps < kMinTypicalDisplayRefreshingRate / 0.9) { 1712 break; 1713 } 1714 } 1715 1716 if (tsLayers > 1) { 1717 uint32_t bLayers = std::min(2u, tsLayers - 1); // use up-to 2 B-layers 1718 uint32_t pLayers = tsLayers - bLayers; 1719 format->setString( 1720 "ts-schema", AStringPrintf("android.generic.%u+%u", pLayers, bLayers)); 1721 1722 // TODO: some encoders do not support B-frames with temporal layering, and we have a 1723 // different preference based on use-case. We could move this into camera profiles. 1724 format->setInt32("android._prefer-b-frames", preferBFrames); 1725 } 1726 1727 if (mMetaDataStoredInVideoBuffers != kMetadataBufferTypeInvalid) { 1728 format->setInt32("android._input-metadata-buffer-type", mMetaDataStoredInVideoBuffers); 1729 } 1730 1731 uint32_t flags = 0; 1732 if (cameraSource == NULL) { 1733 flags |= MediaCodecSource::FLAG_USE_SURFACE_INPUT; 1734 } else { 1735 // require dataspace setup even if not using surface input 1736 format->setInt32("android._using-recorder", 1); 1737 } 1738 1739 sp<MediaCodecSource> encoder = MediaCodecSource::Create( 1740 mLooper, format, cameraSource, mPersistentSurface, flags); 1741 if (encoder == NULL) { 1742 ALOGE("Failed to create video encoder"); 1743 // When the encoder fails to be created, we need 1744 // release the camera source due to the camera's lock 1745 // and unlock mechanism. 1746 if (cameraSource != NULL) { 1747 cameraSource->stop(); 1748 } 1749 return UNKNOWN_ERROR; 1750 } 1751 1752 if (cameraSource == NULL) { 1753 mGraphicBufferProducer = encoder->getGraphicBufferProducer(); 1754 } 1755 1756 *source = encoder; 1757 1758 return OK; 1759} 1760 1761status_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) { 1762 status_t status = BAD_VALUE; 1763 if (OK != (status = checkAudioEncoderCapabilities())) { 1764 return status; 1765 } 1766 1767 switch(mAudioEncoder) { 1768 case AUDIO_ENCODER_AMR_NB: 1769 case AUDIO_ENCODER_AMR_WB: 1770 case AUDIO_ENCODER_AAC: 1771 case AUDIO_ENCODER_HE_AAC: 1772 case AUDIO_ENCODER_AAC_ELD: 1773 break; 1774 1775 default: 1776 ALOGE("Unsupported audio encoder: %d", mAudioEncoder); 1777 return UNKNOWN_ERROR; 1778 } 1779 1780 sp<MediaCodecSource> audioEncoder = createAudioSource(); 1781 if (audioEncoder == NULL) { 1782 return UNKNOWN_ERROR; 1783 } 1784 1785 writer->addSource(audioEncoder); 1786 mAudioEncoderSource = audioEncoder; 1787 return OK; 1788} 1789 1790status_t StagefrightRecorder::setupMPEG4orWEBMRecording() { 1791 mWriter.clear(); 1792 mTotalBitRate = 0; 1793 1794 status_t err = OK; 1795 sp<MediaWriter> writer; 1796 sp<MPEG4Writer> mp4writer; 1797 if (mOutputFormat == OUTPUT_FORMAT_WEBM) { 1798 writer = new WebmWriter(mOutputFd); 1799 } else { 1800 writer = mp4writer = new MPEG4Writer(mOutputFd); 1801 } 1802 1803 if (mVideoSource < VIDEO_SOURCE_LIST_END) { 1804 setDefaultVideoEncoderIfNecessary(); 1805 1806 sp<MediaSource> mediaSource; 1807 err = setupMediaSource(&mediaSource); 1808 if (err != OK) { 1809 return err; 1810 } 1811 1812 sp<MediaCodecSource> encoder; 1813 err = setupVideoEncoder(mediaSource, &encoder); 1814 if (err != OK) { 1815 return err; 1816 } 1817 1818 writer->addSource(encoder); 1819 mVideoEncoderSource = encoder; 1820 mTotalBitRate += mVideoBitRate; 1821 } 1822 1823 if (mOutputFormat != OUTPUT_FORMAT_WEBM) { 1824 // Audio source is added at the end if it exists. 1825 // This help make sure that the "recoding" sound is suppressed for 1826 // camcorder applications in the recorded files. 1827 // TODO Audio source is currently unsupported for webm output; vorbis encoder needed. 1828 // disable audio for time lapse recording 1829 bool disableAudio = mCaptureFpsEnable && mCaptureFps < mFrameRate; 1830 if (!disableAudio && mAudioSource != AUDIO_SOURCE_CNT) { 1831 err = setupAudioEncoder(writer); 1832 if (err != OK) return err; 1833 mTotalBitRate += mAudioBitRate; 1834 } 1835 1836 if (mCaptureFpsEnable) { 1837 mp4writer->setCaptureRate(mCaptureFps); 1838 } 1839 1840 if (mInterleaveDurationUs > 0) { 1841 mp4writer->setInterleaveDuration(mInterleaveDurationUs); 1842 } 1843 if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) { 1844 mp4writer->setGeoData(mLatitudex10000, mLongitudex10000); 1845 } 1846 } 1847 if (mMaxFileDurationUs != 0) { 1848 writer->setMaxFileDuration(mMaxFileDurationUs); 1849 } 1850 if (mMaxFileSizeBytes != 0) { 1851 writer->setMaxFileSize(mMaxFileSizeBytes); 1852 } 1853 if (mVideoSource == VIDEO_SOURCE_DEFAULT 1854 || mVideoSource == VIDEO_SOURCE_CAMERA) { 1855 mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId); 1856 } else if (mVideoSource == VIDEO_SOURCE_SURFACE) { 1857 // surface source doesn't need large initial delay 1858 mStartTimeOffsetMs = 200; 1859 } 1860 if (mStartTimeOffsetMs > 0) { 1861 writer->setStartTimeOffsetMs(mStartTimeOffsetMs); 1862 } 1863 1864 writer->setListener(mListener); 1865 mWriter = writer; 1866 return OK; 1867} 1868 1869void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) { 1870 int64_t startTimeUs = systemTime() / 1000; 1871 (*meta)->setInt64(kKeyTime, startTimeUs); 1872 (*meta)->setInt32(kKeyFileType, mOutputFormat); 1873 (*meta)->setInt32(kKeyBitRate, mTotalBitRate); 1874 if (mMovieTimeScale > 0) { 1875 (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale); 1876 } 1877 if (mOutputFormat != OUTPUT_FORMAT_WEBM) { 1878 (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset); 1879 if (mTrackEveryTimeDurationUs > 0) { 1880 (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs); 1881 } 1882 if (mRotationDegrees != 0) { 1883 (*meta)->setInt32(kKeyRotation, mRotationDegrees); 1884 } 1885 } 1886} 1887 1888status_t StagefrightRecorder::pause() { 1889 ALOGV("pause"); 1890 if (!mStarted) { 1891 return INVALID_OPERATION; 1892 } 1893 1894 // Already paused --- no-op. 1895 if (mPauseStartTimeUs != 0) { 1896 return OK; 1897 } 1898 1899 if (mAudioEncoderSource != NULL) { 1900 mAudioEncoderSource->pause(); 1901 } 1902 if (mVideoEncoderSource != NULL) { 1903 mVideoEncoderSource->pause(); 1904 } 1905 1906 mPauseStartTimeUs = systemTime() / 1000; 1907 1908 return OK; 1909} 1910 1911status_t StagefrightRecorder::resume() { 1912 ALOGV("resume"); 1913 if (!mStarted) { 1914 return INVALID_OPERATION; 1915 } 1916 1917 // Not paused --- no-op. 1918 if (mPauseStartTimeUs == 0) { 1919 return OK; 1920 } 1921 1922 int64_t bufferStartTimeUs = 0; 1923 bool allSourcesStarted = true; 1924 for (const auto &source : { mAudioEncoderSource, mVideoEncoderSource }) { 1925 if (source == nullptr) { 1926 continue; 1927 } 1928 int64_t timeUs = source->getFirstSampleSystemTimeUs(); 1929 if (timeUs < 0) { 1930 allSourcesStarted = false; 1931 } 1932 if (bufferStartTimeUs < timeUs) { 1933 bufferStartTimeUs = timeUs; 1934 } 1935 } 1936 1937 if (allSourcesStarted) { 1938 if (mPauseStartTimeUs < bufferStartTimeUs) { 1939 mPauseStartTimeUs = bufferStartTimeUs; 1940 } 1941 // 30 ms buffer to avoid timestamp overlap 1942 mTotalPausedDurationUs += (systemTime() / 1000) - mPauseStartTimeUs - 30000; 1943 } 1944 double timeOffset = -mTotalPausedDurationUs; 1945 if (mCaptureFpsEnable) { 1946 timeOffset *= mCaptureFps / mFrameRate; 1947 } 1948 for (const auto &source : { mAudioEncoderSource, mVideoEncoderSource }) { 1949 if (source == nullptr) { 1950 continue; 1951 } 1952 source->setInputBufferTimeOffset((int64_t)timeOffset); 1953 source->start(); 1954 } 1955 mPauseStartTimeUs = 0; 1956 1957 return OK; 1958} 1959 1960status_t StagefrightRecorder::stop() { 1961 ALOGV("stop"); 1962 Mutex::Autolock autolock(mLock); 1963 status_t err = OK; 1964 1965 if (mCaptureFpsEnable && mCameraSourceTimeLapse != NULL) { 1966 mCameraSourceTimeLapse->startQuickReadReturns(); 1967 mCameraSourceTimeLapse = NULL; 1968 } 1969 1970 if (mWriter != NULL) { 1971 err = mWriter->stop(); 1972 mWriter.clear(); 1973 } 1974 1975 resetMetrics(); 1976 1977 mTotalPausedDurationUs = 0; 1978 mPauseStartTimeUs = 0; 1979 1980 mGraphicBufferProducer.clear(); 1981 mPersistentSurface.clear(); 1982 mAudioEncoderSource.clear(); 1983 mVideoEncoderSource.clear(); 1984 1985 if (mOutputFd >= 0) { 1986 ::close(mOutputFd); 1987 mOutputFd = -1; 1988 } 1989 1990 if (mStarted) { 1991 mStarted = false; 1992 1993 uint32_t params = 0; 1994 if (mAudioSource != AUDIO_SOURCE_CNT) { 1995 params |= IMediaPlayerService::kBatteryDataTrackAudio; 1996 } 1997 if (mVideoSource != VIDEO_SOURCE_LIST_END) { 1998 params |= IMediaPlayerService::kBatteryDataTrackVideo; 1999 } 2000 2001 addBatteryData(params); 2002 } 2003 2004 return err; 2005} 2006 2007status_t StagefrightRecorder::close() { 2008 ALOGV("close"); 2009 stop(); 2010 2011 return OK; 2012} 2013 2014status_t StagefrightRecorder::reset() { 2015 ALOGV("reset"); 2016 stop(); 2017 2018 // No audio or video source by default 2019 mAudioSource = AUDIO_SOURCE_CNT; 2020 mVideoSource = VIDEO_SOURCE_LIST_END; 2021 2022 // Default parameters 2023 mOutputFormat = OUTPUT_FORMAT_THREE_GPP; 2024 mAudioEncoder = AUDIO_ENCODER_AMR_NB; 2025 mVideoEncoder = VIDEO_ENCODER_DEFAULT; 2026 mVideoWidth = 176; 2027 mVideoHeight = 144; 2028 mFrameRate = -1; 2029 mVideoBitRate = 192000; 2030 mSampleRate = 8000; 2031 mAudioChannels = 1; 2032 mAudioBitRate = 12200; 2033 mInterleaveDurationUs = 0; 2034 mIFramesIntervalSec = 1; 2035 mAudioSourceNode = 0; 2036 mUse64BitFileOffset = false; 2037 mMovieTimeScale = -1; 2038 mAudioTimeScale = -1; 2039 mVideoTimeScale = -1; 2040 mCameraId = 0; 2041 mStartTimeOffsetMs = -1; 2042 mVideoEncoderProfile = -1; 2043 mVideoEncoderLevel = -1; 2044 mMaxFileDurationUs = 0; 2045 mMaxFileSizeBytes = 0; 2046 mTrackEveryTimeDurationUs = 0; 2047 mCaptureFpsEnable = false; 2048 mCaptureFps = 0.0f; 2049 mTimeBetweenCaptureUs = -1; 2050 mCameraSourceTimeLapse = NULL; 2051 mMetaDataStoredInVideoBuffers = kMetadataBufferTypeInvalid; 2052 mEncoderProfiles = MediaProfiles::getInstance(); 2053 mRotationDegrees = 0; 2054 mLatitudex10000 = -3600000; 2055 mLongitudex10000 = -3600000; 2056 mTotalBitRate = 0; 2057 2058 mOutputFd = -1; 2059 2060 return OK; 2061} 2062 2063status_t StagefrightRecorder::getMaxAmplitude(int *max) { 2064 ALOGV("getMaxAmplitude"); 2065 2066 if (max == NULL) { 2067 ALOGE("Null pointer argument"); 2068 return BAD_VALUE; 2069 } 2070 2071 if (mAudioSourceNode != 0) { 2072 *max = mAudioSourceNode->getMaxAmplitude(); 2073 } else { 2074 *max = 0; 2075 } 2076 2077 return OK; 2078} 2079 2080status_t StagefrightRecorder::getMetrics(Parcel *reply) { 2081 ALOGD("StagefrightRecorder::getMetrics"); 2082 2083 if (reply == NULL) { 2084 ALOGE("Null pointer argument"); 2085 return BAD_VALUE; 2086 } 2087 2088 if (mAnalyticsItem == NULL) { 2089 return UNKNOWN_ERROR; 2090 } 2091 2092 updateMetrics(); 2093 mAnalyticsItem->writeToParcel(reply); 2094 return OK; 2095} 2096 2097status_t StagefrightRecorder::dump( 2098 int fd, const Vector<String16>& args) const { 2099 ALOGV("dump"); 2100 Mutex::Autolock autolock(mLock); 2101 const size_t SIZE = 256; 2102 char buffer[SIZE]; 2103 String8 result; 2104 if (mWriter != 0) { 2105 mWriter->dump(fd, args); 2106 } else { 2107 snprintf(buffer, SIZE, " No file writer\n"); 2108 result.append(buffer); 2109 } 2110 snprintf(buffer, SIZE, " Recorder: %p\n", this); 2111 snprintf(buffer, SIZE, " Output file (fd %d):\n", mOutputFd); 2112 result.append(buffer); 2113 snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat); 2114 result.append(buffer); 2115 snprintf(buffer, SIZE, " Max file size (bytes): %" PRId64 "\n", mMaxFileSizeBytes); 2116 result.append(buffer); 2117 snprintf(buffer, SIZE, " Max file duration (us): %" PRId64 "\n", mMaxFileDurationUs); 2118 result.append(buffer); 2119 snprintf(buffer, SIZE, " File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32); 2120 result.append(buffer); 2121 snprintf(buffer, SIZE, " Interleave duration (us): %d\n", mInterleaveDurationUs); 2122 result.append(buffer); 2123 snprintf(buffer, SIZE, " Progress notification: %" PRId64 " us\n", mTrackEveryTimeDurationUs); 2124 result.append(buffer); 2125 snprintf(buffer, SIZE, " Audio\n"); 2126 result.append(buffer); 2127 snprintf(buffer, SIZE, " Source: %d\n", mAudioSource); 2128 result.append(buffer); 2129 snprintf(buffer, SIZE, " Encoder: %d\n", mAudioEncoder); 2130 result.append(buffer); 2131 snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mAudioBitRate); 2132 result.append(buffer); 2133 snprintf(buffer, SIZE, " Sampling rate (hz): %d\n", mSampleRate); 2134 result.append(buffer); 2135 snprintf(buffer, SIZE, " Number of channels: %d\n", mAudioChannels); 2136 result.append(buffer); 2137 snprintf(buffer, SIZE, " Max amplitude: %d\n", mAudioSourceNode == 0? 0: mAudioSourceNode->getMaxAmplitude()); 2138 result.append(buffer); 2139 snprintf(buffer, SIZE, " Video\n"); 2140 result.append(buffer); 2141 snprintf(buffer, SIZE, " Source: %d\n", mVideoSource); 2142 result.append(buffer); 2143 snprintf(buffer, SIZE, " Camera Id: %d\n", mCameraId); 2144 result.append(buffer); 2145 snprintf(buffer, SIZE, " Start time offset (ms): %d\n", mStartTimeOffsetMs); 2146 result.append(buffer); 2147 snprintf(buffer, SIZE, " Encoder: %d\n", mVideoEncoder); 2148 result.append(buffer); 2149 snprintf(buffer, SIZE, " Encoder profile: %d\n", mVideoEncoderProfile); 2150 result.append(buffer); 2151 snprintf(buffer, SIZE, " Encoder level: %d\n", mVideoEncoderLevel); 2152 result.append(buffer); 2153 snprintf(buffer, SIZE, " I frames interval (s): %d\n", mIFramesIntervalSec); 2154 result.append(buffer); 2155 snprintf(buffer, SIZE, " Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight); 2156 result.append(buffer); 2157 snprintf(buffer, SIZE, " Frame rate (fps): %d\n", mFrameRate); 2158 result.append(buffer); 2159 snprintf(buffer, SIZE, " Bit rate (bps): %d\n", mVideoBitRate); 2160 result.append(buffer); 2161 ::write(fd, result.string(), result.size()); 2162 return OK; 2163} 2164} // namespace android 2165