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