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