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