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