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