130ab66297501757d745b9ae10da61adcd891f497Andreas Huber/*
230ab66297501757d745b9ae10da61adcd891f497Andreas Huber * Copyright (C) 2009 The Android Open Source Project
330ab66297501757d745b9ae10da61adcd891f497Andreas Huber *
430ab66297501757d745b9ae10da61adcd891f497Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
530ab66297501757d745b9ae10da61adcd891f497Andreas Huber * you may not use this file except in compliance with the License.
630ab66297501757d745b9ae10da61adcd891f497Andreas Huber * You may obtain a copy of the License at
730ab66297501757d745b9ae10da61adcd891f497Andreas Huber *
830ab66297501757d745b9ae10da61adcd891f497Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
930ab66297501757d745b9ae10da61adcd891f497Andreas Huber *
1030ab66297501757d745b9ae10da61adcd891f497Andreas Huber * Unless required by applicable law or agreed to in writing, software
1130ab66297501757d745b9ae10da61adcd891f497Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1230ab66297501757d745b9ae10da61adcd891f497Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1330ab66297501757d745b9ae10da61adcd891f497Andreas Huber * See the License for the specific language governing permissions and
1430ab66297501757d745b9ae10da61adcd891f497Andreas Huber * limitations under the License.
1530ab66297501757d745b9ae10da61adcd891f497Andreas Huber */
1630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1730ab66297501757d745b9ae10da61adcd891f497Andreas Huber//#define LOG_NDEBUG 0
1830ab66297501757d745b9ae10da61adcd891f497Andreas Huber#define LOG_TAG "StagefrightRecorder"
1930ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <utils/Log.h>
2030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
2130ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include "StagefrightRecorder.h"
2230ab66297501757d745b9ae10da61adcd891f497Andreas Huber
2375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <binder/IPCThreadState.h>
2475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <binder/IServiceManager.h>
2575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
2675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang#include <media/IMediaPlayerService.h>
27aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/openmax/OMX_Audio.h>
28f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
292dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber#include <media/stagefright/AudioSource.h>
302dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber#include <media/stagefright/AMRWriter.h>
31760943b5e7a09b602aba04ec451e97662f48b0a4James Dong#include <media/stagefright/AACWriter.h>
3230ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/CameraSource.h>
3365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSourceTimeLapse.h>
3459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber#include <media/stagefright/MPEG2TSWriter.h>
3530ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MPEG4Writer.h>
3630ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MediaDefs.h>
3730ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/MetaData.h>
3830ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/OMXClient.h>
3930ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <media/stagefright/OMXCodec.h>
40b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi#include <media/stagefright/SurfaceMediaSource.h>
4199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong#include <media/MediaProfiles.h>
423cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/ICamera.h>
43ef9d0cd72e476a4b7556833fb09505a51b626797James Dong#include <camera/CameraParameters.h>
44df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h>
45b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
4630ab66297501757d745b9ae10da61adcd891f497Andreas Huber#include <utils/Errors.h>
47c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#include <sys/types.h>
48050b28a593350047845a45a14cc5026221ac1620James Dong#include <ctype.h>
49ca2fa61ef03cac008ea86e6fe16b2e5f9f1a2be3Nipun Kwatra#include <unistd.h>
5030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
5164760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
52fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
5339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "ARTPWriter.h"
5439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
5530ab66297501757d745b9ae10da61adcd891f497Andreas Hubernamespace android {
5630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
5775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang// To collect the encoder usage for the battery app
5875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wangstatic void addBatteryData(uint32_t params) {
5975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    sp<IBinder> binder =
6075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        defaultServiceManager()->getService(String16("media.player"));
6175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
6275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    CHECK(service.get() != NULL);
6375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
6475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    service->addBatteryData(params);
6575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang}
6675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
6775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
68d329e21495eda9dbc531fdd0c26c77f1593ac3f4James DongStagefrightRecorder::StagefrightRecorder()
693cecf640c4daf2df616b278bd9986018c8182908James Dong    : mWriter(NULL),
703cecf640c4daf2df616b278bd9986018c8182908James Dong      mOutputFd(-1),
71fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin      mAudioSource(AUDIO_SOURCE_CNT),
7275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang      mVideoSource(VIDEO_SOURCE_LIST_END),
73b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi      mStarted(false), mSurfaceMediaSource(NULL) {
74d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Constructor");
7630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    reset();
7730ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
7830ab66297501757d745b9ae10da61adcd891f497Andreas Huber
7930ab66297501757d745b9ae10da61adcd891f497Andreas HuberStagefrightRecorder::~StagefrightRecorder() {
803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Destructor");
8130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    stop();
8230ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
8330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
8430ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::init() {
853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("init");
8630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
8730ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
8830ab66297501757d745b9ae10da61adcd891f497Andreas Huber
89b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// The client side of mediaserver asks it to creat a SurfaceMediaSource
90b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// and return a interface reference. The client side will use that
91b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// while encoding GL Frames
92b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketisp<ISurfaceTexture> StagefrightRecorder::querySurfaceMediaSource() const {
933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Get SurfaceMediaSource");
94bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    return mSurfaceMediaSource->getBufferQueue();
95b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi}
96b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
97fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatus_t StagefrightRecorder::setAudioSource(audio_source_t as) {
983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setAudioSource: %d", as);
99d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (as < AUDIO_SOURCE_DEFAULT ||
100fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        as >= AUDIO_SOURCE_CNT) {
10129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid audio source: %d", as);
102d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return BAD_VALUE;
103d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
104d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
105d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (as == AUDIO_SOURCE_DEFAULT) {
106d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mAudioSource = AUDIO_SOURCE_MIC;
107d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    } else {
108d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mAudioSource = as;
109d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
11030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
11130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
11230ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
11330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
11430ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoSource(video_source vs) {
1153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setVideoSource: %d", vs);
116d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (vs < VIDEO_SOURCE_DEFAULT ||
117d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        vs >= VIDEO_SOURCE_LIST_END) {
11829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid video source: %d", vs);
119d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return BAD_VALUE;
120d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
121d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
122d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (vs == VIDEO_SOURCE_DEFAULT) {
123d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mVideoSource = VIDEO_SOURCE_CAMERA;
124d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    } else {
125d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mVideoSource = vs;
126d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
12730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
12830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
12930ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
13030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
13130ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setOutputFormat(output_format of) {
1323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setOutputFormat: %d", of);
133d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (of < OUTPUT_FORMAT_DEFAULT ||
134d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        of >= OUTPUT_FORMAT_LIST_END) {
13529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid output format: %d", of);
136d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return BAD_VALUE;
137d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
138d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
139d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (of == OUTPUT_FORMAT_DEFAULT) {
140d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mOutputFormat = OUTPUT_FORMAT_THREE_GPP;
141d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    } else {
142d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mOutputFormat = of;
143d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
14430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
14530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
14630ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
14730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
14830ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) {
1493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setAudioEncoder: %d", ae);
150d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (ae < AUDIO_ENCODER_DEFAULT ||
151d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        ae >= AUDIO_ENCODER_LIST_END) {
15229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid audio encoder: %d", ae);
153d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return BAD_VALUE;
154d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
155d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
156d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (ae == AUDIO_ENCODER_DEFAULT) {
157d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mAudioEncoder = AUDIO_ENCODER_AMR_NB;
158d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    } else {
159d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mAudioEncoder = ae;
160d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
16130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
16230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
16330ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
16430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
16530ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoEncoder(video_encoder ve) {
1663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setVideoEncoder: %d", ve);
167d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (ve < VIDEO_ENCODER_DEFAULT ||
168d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        ve >= VIDEO_ENCODER_LIST_END) {
16929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid video encoder: %d", ve);
170d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return BAD_VALUE;
171d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
172d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
173d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (ve == VIDEO_ENCODER_DEFAULT) {
174d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mVideoEncoder = VIDEO_ENCODER_H263;
175d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    } else {
176d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        mVideoEncoder = ve;
177d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
17830ab66297501757d745b9ae10da61adcd891f497Andreas Huber
17930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
18030ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
18130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
18230ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoSize(int width, int height) {
1833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setVideoSize: %dx%d", width, height);
184ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    if (width <= 0 || height <= 0) {
18529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid video size: %dx%d", width, height);
186ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        return BAD_VALUE;
187ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
188ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
189ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // Additional check on the dimension will be performed later
19030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    mVideoWidth = width;
19130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    mVideoHeight = height;
19230ab66297501757d745b9ae10da61adcd891f497Andreas Huber
19330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
19430ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
19530ab66297501757d745b9ae10da61adcd891f497Andreas Huber
19630ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) {
1973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setVideoFrameRate: %d", frames_per_second);
198635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    if ((frames_per_second <= 0 && frames_per_second != -1) ||
199635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        frames_per_second > 120) {
20029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid video frame rate: %d", frames_per_second);
201ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        return BAD_VALUE;
202ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
203ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
204ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // Additional check on the frame rate will be performed later
20530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    mFrameRate = frames_per_second;
20630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
20730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
20830ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
20930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
2104ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Listatus_t StagefrightRecorder::setCamera(const sp<ICamera> &camera,
2114ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li                                        const sp<ICameraRecordingProxy> &proxy) {
2123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setCamera");
213c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    if (camera == 0) {
21429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("camera is NULL");
215934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        return BAD_VALUE;
216c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    }
2174ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    if (proxy == 0) {
21829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("camera proxy is NULL");
2194ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        return BAD_VALUE;
2204ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    }
221c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong
22254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mCamera = camera;
2234ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mCameraProxy = proxy;
22430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
22530ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
22630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
2274b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennisstatus_t StagefrightRecorder::setPreviewSurface(const sp<Surface> &surface) {
2283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setPreviewSurface: %p", surface.get());
22930ab66297501757d745b9ae10da61adcd891f497Andreas Huber    mPreviewSurface = surface;
23030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
23130ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
23230ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
23330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
23430ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setOutputFile(const char *path) {
23529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("setOutputFile(const char*) must not be called");
23630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // We don't actually support this at all, as the media_server process
23730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // no longer has permissions to create files.
23830ab66297501757d745b9ae10da61adcd891f497Andreas Huber
239934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    return -EPERM;
24030ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
24130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
24230ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) {
2433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setOutputFile: %d, %lld, %lld", fd, offset, length);
24430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    // These don't make any sense, do they?
245f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK_EQ(offset, 0ll);
246f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK_EQ(length, 0ll);
24730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
248934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    if (fd < 0) {
24929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid file descriptor: %d", fd);
250934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        return -EBADF;
251934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    }
252934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong
25330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (mOutputFd >= 0) {
25430ab66297501757d745b9ae10da61adcd891f497Andreas Huber        ::close(mOutputFd);
25530ab66297501757d745b9ae10da61adcd891f497Andreas Huber    }
25630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    mOutputFd = dup(fd);
25730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
25830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
25930ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
26030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
261050b28a593350047845a45a14cc5026221ac1620James Dong// Attempt to parse an int64 literal optionally surrounded by whitespace,
262050b28a593350047845a45a14cc5026221ac1620James Dong// returns true on success, false otherwise.
263ef9d0cd72e476a4b7556833fb09505a51b626797James Dongstatic bool safe_strtoi64(const char *s, int64_t *val) {
264050b28a593350047845a45a14cc5026221ac1620James Dong    char *end;
26527944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong
26627944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong    // It is lame, but according to man page, we have to set errno to 0
26727944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong    // before calling strtoll().
26827944ef5cd8d0fb476c8c8958986e827c5f8ab83James Dong    errno = 0;
269ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    *val = strtoll(s, &end, 10);
270050b28a593350047845a45a14cc5026221ac1620James Dong
271050b28a593350047845a45a14cc5026221ac1620James Dong    if (end == s || errno == ERANGE) {
272050b28a593350047845a45a14cc5026221ac1620James Dong        return false;
273050b28a593350047845a45a14cc5026221ac1620James Dong    }
274050b28a593350047845a45a14cc5026221ac1620James Dong
275050b28a593350047845a45a14cc5026221ac1620James Dong    // Skip trailing whitespace
276050b28a593350047845a45a14cc5026221ac1620James Dong    while (isspace(*end)) {
277050b28a593350047845a45a14cc5026221ac1620James Dong        ++end;
278050b28a593350047845a45a14cc5026221ac1620James Dong    }
279050b28a593350047845a45a14cc5026221ac1620James Dong
280050b28a593350047845a45a14cc5026221ac1620James Dong    // For a successful return, the string must contain nothing but a valid
281050b28a593350047845a45a14cc5026221ac1620James Dong    // int64 literal optionally surrounded by whitespace.
282050b28a593350047845a45a14cc5026221ac1620James Dong
283050b28a593350047845a45a14cc5026221ac1620James Dong    return *end == '\0';
284050b28a593350047845a45a14cc5026221ac1620James Dong}
285050b28a593350047845a45a14cc5026221ac1620James Dong
286ef9d0cd72e476a4b7556833fb09505a51b626797James Dong// Return true if the value is in [0, 0x007FFFFFFF]
287ef9d0cd72e476a4b7556833fb09505a51b626797James Dongstatic bool safe_strtoi32(const char *s, int32_t *val) {
288ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    int64_t temp;
289ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    if (safe_strtoi64(s, &temp)) {
290ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        if (temp >= 0 && temp <= 0x007FFFFFFF) {
291ef9d0cd72e476a4b7556833fb09505a51b626797James Dong            *val = static_cast<int32_t>(temp);
292ef9d0cd72e476a4b7556833fb09505a51b626797James Dong            return true;
293ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        }
294ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
295ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    return false;
296ef9d0cd72e476a4b7556833fb09505a51b626797James Dong}
297ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
298050b28a593350047845a45a14cc5026221ac1620James Dong// Trim both leading and trailing whitespace from the given string.
299050b28a593350047845a45a14cc5026221ac1620James Dongstatic void TrimString(String8 *s) {
300050b28a593350047845a45a14cc5026221ac1620James Dong    size_t num_bytes = s->bytes();
301050b28a593350047845a45a14cc5026221ac1620James Dong    const char *data = s->string();
302050b28a593350047845a45a14cc5026221ac1620James Dong
303050b28a593350047845a45a14cc5026221ac1620James Dong    size_t leading_space = 0;
304050b28a593350047845a45a14cc5026221ac1620James Dong    while (leading_space < num_bytes && isspace(data[leading_space])) {
305050b28a593350047845a45a14cc5026221ac1620James Dong        ++leading_space;
306050b28a593350047845a45a14cc5026221ac1620James Dong    }
307050b28a593350047845a45a14cc5026221ac1620James Dong
308050b28a593350047845a45a14cc5026221ac1620James Dong    size_t i = num_bytes;
309050b28a593350047845a45a14cc5026221ac1620James Dong    while (i > leading_space && isspace(data[i - 1])) {
310050b28a593350047845a45a14cc5026221ac1620James Dong        --i;
311050b28a593350047845a45a14cc5026221ac1620James Dong    }
312050b28a593350047845a45a14cc5026221ac1620James Dong
313050b28a593350047845a45a14cc5026221ac1620James Dong    s->setTo(String8(&data[leading_space], i - leading_space));
314050b28a593350047845a45a14cc5026221ac1620James Dong}
315050b28a593350047845a45a14cc5026221ac1620James Dong
316050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) {
3173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamAudioSamplingRate: %d", sampleRate);
318ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    if (sampleRate <= 0) {
31929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid audio sampling rate: %d", sampleRate);
320ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        return BAD_VALUE;
321ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
322ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
323ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // Additional check on the sample rate will be performed later.
324050b28a593350047845a45a14cc5026221ac1620James Dong    mSampleRate = sampleRate;
325050b28a593350047845a45a14cc5026221ac1620James Dong    return OK;
326050b28a593350047845a45a14cc5026221ac1620James Dong}
327050b28a593350047845a45a14cc5026221ac1620James Dong
328050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) {
3293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamAudioNumberOfChannels: %d", channels);
330ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    if (channels <= 0 || channels >= 3) {
33129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid number of audio channels: %d", channels);
332934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        return BAD_VALUE;
333ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
334ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
335ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // Additional check on the number of channels will be performed later.
336050b28a593350047845a45a14cc5026221ac1620James Dong    mAudioChannels = channels;
337050b28a593350047845a45a14cc5026221ac1620James Dong    return OK;
338050b28a593350047845a45a14cc5026221ac1620James Dong}
339050b28a593350047845a45a14cc5026221ac1620James Dong
340050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) {
3413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamAudioEncodingBitRate: %d", bitRate);
342ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    if (bitRate <= 0) {
34329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid audio encoding bit rate: %d", bitRate);
344ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        return BAD_VALUE;
345ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
346ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
347ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // The target bit rate may not be exactly the same as the requested.
348ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // It depends on many factors, such as rate control, and the bit rate
349ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // range that a specific encoder supports. The mismatch between the
350ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // the target and requested bit rate will NOT be treated as an error.
351050b28a593350047845a45a14cc5026221ac1620James Dong    mAudioBitRate = bitRate;
352050b28a593350047845a45a14cc5026221ac1620James Dong    return OK;
353050b28a593350047845a45a14cc5026221ac1620James Dong}
354050b28a593350047845a45a14cc5026221ac1620James Dong
355050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) {
3563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamVideoEncodingBitRate: %d", bitRate);
357ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    if (bitRate <= 0) {
35829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid video encoding bit rate: %d", bitRate);
359ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        return BAD_VALUE;
360ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
361ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
362ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // The target bit rate may not be exactly the same as the requested.
363ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // It depends on many factors, such as rate control, and the bit rate
364ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // range that a specific encoder supports. The mismatch between the
365ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    // the target and requested bit rate will NOT be treated as an error.
366050b28a593350047845a45a14cc5026221ac1620James Dong    mVideoBitRate = bitRate;
367050b28a593350047845a45a14cc5026221ac1620James Dong    return OK;
368050b28a593350047845a45a14cc5026221ac1620James Dong}
369050b28a593350047845a45a14cc5026221ac1620James Dong
37013f6284305e4b27395a23db7882d670bdb1bcae1James Dong// Always rotate clockwise, and only support 0, 90, 180 and 270 for now.
37113f6284305e4b27395a23db7882d670bdb1bcae1James Dongstatus_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) {
3723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamVideoRotation: %d", degrees);
37313f6284305e4b27395a23db7882d670bdb1bcae1James Dong    if (degrees < 0 || degrees % 90 != 0) {
37429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Unsupported video rotation angle: %d", degrees);
37513f6284305e4b27395a23db7882d670bdb1bcae1James Dong        return BAD_VALUE;
37613f6284305e4b27395a23db7882d670bdb1bcae1James Dong    }
37713f6284305e4b27395a23db7882d670bdb1bcae1James Dong    mRotationDegrees = degrees % 360;
37813f6284305e4b27395a23db7882d670bdb1bcae1James Dong    return OK;
37913f6284305e4b27395a23db7882d670bdb1bcae1James Dong}
38013f6284305e4b27395a23db7882d670bdb1bcae1James Dong
381934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) {
3823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamMaxFileDurationUs: %lld us", timeUs);
3832d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong
3842d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong    // This is meant for backward compatibility for MediaRecorder.java
385be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra    if (timeUs <= 0) {
3865ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", timeUs);
387be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra        timeUs = 0; // Disable the duration limit for zero or negative values.
388be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra    } else if (timeUs <= 100000LL) {  // XXX: 100 milli-seconds
38929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Max file duration is too short: %lld us", timeUs);
390934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        return BAD_VALUE;
391ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
392be6fd201b9a04fe0f8fd409f10595ddb41832591Nipun Kwatra
393acd234bba9f048971d66890009eeff9a8db94be3James Dong    if (timeUs <= 15 * 1000000LL) {
3945ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Target duration (%lld us) too short to be respected", timeUs);
395acd234bba9f048971d66890009eeff9a8db94be3James Dong    }
396934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    mMaxFileDurationUs = timeUs;
397934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    return OK;
398934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong}
399934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong
400934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
4013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamMaxFileSizeBytes: %lld bytes", bytes);
4022d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong
4032d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong    // This is meant for backward compatibility for MediaRecorder.java
4042d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong    if (bytes <= 0) {
4055ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Max file size is not positive: %lld bytes. "
4062d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong             "Disabling file size limit.", bytes);
4072d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong        bytes = 0; // Disable the file size limit for zero or negative values.
4082d1e5d35be5e6d4b55ac8b39fbfcbeb60fcdd084James Dong    } else if (bytes <= 1024) {  // XXX: 1 kB
40929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Max file size is too small: %lld bytes", bytes);
410934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        return BAD_VALUE;
411934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    }
412acd234bba9f048971d66890009eeff9a8db94be3James Dong
413acd234bba9f048971d66890009eeff9a8db94be3James Dong    if (bytes <= 100 * 1024) {
4145ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Target file size (%lld bytes) is too small to be respected", bytes);
415acd234bba9f048971d66890009eeff9a8db94be3James Dong    }
416acd234bba9f048971d66890009eeff9a8db94be3James Dong
417934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    mMaxFileSizeBytes = bytes;
418050b28a593350047845a45a14cc5026221ac1620James Dong    return OK;
419050b28a593350047845a45a14cc5026221ac1620James Dong}
420050b28a593350047845a45a14cc5026221ac1620James Dong
42113aec890216948b0c364f8f92792129d0335f506James Dongstatus_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) {
4223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamInterleaveDuration: %d", durationUs);
423ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong    if (durationUs <= 500000) {           //  500 ms
424ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong        // If interleave duration is too small, it is very inefficient to do
425ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong        // interleaving since the metadata overhead will count for a significant
426ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong        // portion of the saved contents
42729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Audio/video interleave duration is too small: %d us", durationUs);
428ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        return BAD_VALUE;
429ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong    } else if (durationUs >= 10000000) {  // 10 seconds
430ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong        // If interleaving duration is too large, it can cause the recording
431ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong        // session to use too much memory since we have to save the output
432ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong        // data before we write them out
43329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Audio/video interleave duration is too large: %d us", durationUs);
434ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong        return BAD_VALUE;
435ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    }
43613aec890216948b0c364f8f92792129d0335f506James Dong    mInterleaveDurationUs = durationUs;
43713aec890216948b0c364f8f92792129d0335f506James Dong    return OK;
43813aec890216948b0c364f8f92792129d0335f506James Dong}
439ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
4408f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds <  0, only the first frame is I frame, and rest are all P frames
4418f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds == 0, all frames are encoded as I frames. No P frames
4428f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong// If seconds >  0, it is the time spacing (seconds) between 2 neighboring I frames
4438f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamVideoIFramesInterval(int32_t seconds) {
4443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamVideoIFramesInterval: %d seconds", seconds);
4458f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    mIFramesIntervalSec = seconds;
446ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong    return OK;
447ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong}
448ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong
4492dec2b5be2056c6d9428897dc672185872d30d17James Dongstatus_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit) {
4503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParam64BitFileOffset: %s",
4512dec2b5be2056c6d9428897dc672185872d30d17James Dong        use64Bit? "use 64 bit file offset": "use 32 bit file offset");
4522dec2b5be2056c6d9428897dc672185872d30d17James Dong    mUse64BitFileOffset = use64Bit;
4532dec2b5be2056c6d9428897dc672185872d30d17James Dong    return OK;
4542dec2b5be2056c6d9428897dc672185872d30d17James Dong}
4552dec2b5be2056c6d9428897dc672185872d30d17James Dong
45693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dongstatus_t StagefrightRecorder::setParamVideoCameraId(int32_t cameraId) {
4573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamVideoCameraId: %d", cameraId);
45893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    if (cameraId < 0) {
45993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        return BAD_VALUE;
46093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    }
46193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    mCameraId = cameraId;
46293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    return OK;
46393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong}
46493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong
46593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dongstatus_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
4663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamTrackTimeStatus: %lld", timeDurationUs);
46793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    if (timeDurationUs < 20000) {  // Infeasible if shorter than 20 ms?
46829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Tracking time duration too short: %lld us", timeDurationUs);
46993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        return BAD_VALUE;
47093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    }
47193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    mTrackEveryTimeDurationUs = timeDurationUs;
47293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    return OK;
47393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong}
47493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong
475145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dongstatus_t StagefrightRecorder::setParamVideoEncoderProfile(int32_t profile) {
4763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamVideoEncoderProfile: %d", profile);
477145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong
478145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    // Additional check will be done later when we load the encoder.
479145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    // For now, we are accepting values defined in OpenMAX IL.
480145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    mVideoEncoderProfile = profile;
481145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    return OK;
482145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong}
483145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong
484145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dongstatus_t StagefrightRecorder::setParamVideoEncoderLevel(int32_t level) {
4853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamVideoEncoderLevel: %d", level);
486145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong
487145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    // Additional check will be done later when we load the encoder.
488145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    // For now, we are accepting values defined in OpenMAX IL.
489145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    mVideoEncoderLevel = level;
490145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    return OK;
491145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong}
492145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong
4938f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamMovieTimeScale(int32_t timeScale) {
4943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamMovieTimeScale: %d", timeScale);
4958f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong
4968f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    // The range is set to be the same as the audio's time scale range
4978f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    // since audio's time scale has a wider range.
4988f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    if (timeScale < 600 || timeScale > 96000) {
49929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Time scale (%d) for movie is out of range [600, 96000]", timeScale);
5008f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        return BAD_VALUE;
5018f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    }
5028f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    mMovieTimeScale = timeScale;
5038f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    return OK;
5048f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong}
5058f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong
5068f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamVideoTimeScale(int32_t timeScale) {
5073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamVideoTimeScale: %d", timeScale);
5088f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong
5098f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    // 60000 is chosen to make sure that each video frame from a 60-fps
5108f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    // video has 1000 ticks.
5118f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    if (timeScale < 600 || timeScale > 60000) {
51229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Time scale (%d) for video is out of range [600, 60000]", timeScale);
5138f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        return BAD_VALUE;
5148f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    }
5158f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    mVideoTimeScale = timeScale;
5168f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    return OK;
5178f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong}
5188f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong
5198f5f2fcee5c12d08df71d17017410c50951fc2e3James Dongstatus_t StagefrightRecorder::setParamAudioTimeScale(int32_t timeScale) {
5203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamAudioTimeScale: %d", timeScale);
5218f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong
5228f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    // 96000 Hz is the highest sampling rate support in AAC.
5238f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    if (timeScale < 600 || timeScale > 96000) {
52429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Time scale (%d) for audio is out of range [600, 96000]", timeScale);
5258f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        return BAD_VALUE;
5268f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    }
5278f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    mAudioTimeScale = timeScale;
5288f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    return OK;
5298f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong}
5308f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong
531e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatrastatus_t StagefrightRecorder::setParamTimeLapseEnable(int32_t timeLapseEnable) {
5323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamTimeLapseEnable: %d", timeLapseEnable);
533e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra
534e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    if(timeLapseEnable == 0) {
535e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        mCaptureTimeLapse = false;
536e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    } else if (timeLapseEnable == 1) {
537e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        mCaptureTimeLapse = true;
538e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    } else {
539e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        return BAD_VALUE;
540e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    }
541e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    return OK;
542e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra}
543e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra
544e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatrastatus_t StagefrightRecorder::setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs) {
5453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParamTimeBetweenTimeLapseFrameCapture: %lld us", timeUs);
546e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra
547e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    // Not allowing time more than a day
548e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    if (timeUs <= 0 || timeUs > 86400*1E6) {
54929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Time between time lapse frame capture (%lld) is out of range [0, 1 Day]", timeUs);
550e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        return BAD_VALUE;
551e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    }
552e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra
553e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    mTimeBetweenTimeLapseFrameCaptureUs = timeUs;
554e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    return OK;
555e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra}
556e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra
55707b1bb529a1ae76c46a71b01338c166f9490629dJames Dongstatus_t StagefrightRecorder::setParamGeoDataLongitude(
558b832a03d563dd000faa44f2577e92237525edc32James Dong    int64_t longitudex10000) {
55907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong
56007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
56107b1bb529a1ae76c46a71b01338c166f9490629dJames Dong        return BAD_VALUE;
56207b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    }
56307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    mLongitudex10000 = longitudex10000;
56407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    return OK;
56507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong}
56607b1bb529a1ae76c46a71b01338c166f9490629dJames Dong
56707b1bb529a1ae76c46a71b01338c166f9490629dJames Dongstatus_t StagefrightRecorder::setParamGeoDataLatitude(
568b832a03d563dd000faa44f2577e92237525edc32James Dong    int64_t latitudex10000) {
56907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong
57007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    if (latitudex10000 > 900000 || latitudex10000 < -900000) {
57107b1bb529a1ae76c46a71b01338c166f9490629dJames Dong        return BAD_VALUE;
57207b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    }
57307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    mLatitudex10000 = latitudex10000;
57407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    return OK;
57507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong}
57607b1bb529a1ae76c46a71b01338c166f9490629dJames Dong
577050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParameter(
578050b28a593350047845a45a14cc5026221ac1620James Dong        const String8 &key, const String8 &value) {
5793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
580050b28a593350047845a45a14cc5026221ac1620James Dong    if (key == "max-duration") {
581ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        int64_t max_duration_ms;
582050b28a593350047845a45a14cc5026221ac1620James Dong        if (safe_strtoi64(value.string(), &max_duration_ms)) {
583934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            return setParamMaxFileDurationUs(1000LL * max_duration_ms);
584050b28a593350047845a45a14cc5026221ac1620James Dong        }
585050b28a593350047845a45a14cc5026221ac1620James Dong    } else if (key == "max-filesize") {
586ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        int64_t max_filesize_bytes;
587050b28a593350047845a45a14cc5026221ac1620James Dong        if (safe_strtoi64(value.string(), &max_filesize_bytes)) {
588934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            return setParamMaxFileSizeBytes(max_filesize_bytes);
589050b28a593350047845a45a14cc5026221ac1620James Dong        }
59093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    } else if (key == "interleave-duration-us") {
59193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        int32_t durationUs;
59293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        if (safe_strtoi32(value.string(), &durationUs)) {
59393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong            return setParamInterleaveDuration(durationUs);
59493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        }
5958f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    } else if (key == "param-movie-time-scale") {
5968f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        int32_t timeScale;
5978f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        if (safe_strtoi32(value.string(), &timeScale)) {
5988f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong            return setParamMovieTimeScale(timeScale);
5998f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        }
60093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    } else if (key == "param-use-64bit-offset") {
60193d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        int32_t use64BitOffset;
60293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        if (safe_strtoi32(value.string(), &use64BitOffset)) {
60393d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong            return setParam64BitFileOffset(use64BitOffset != 0);
60493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        }
60507b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    } else if (key == "param-geotag-longitude") {
606b832a03d563dd000faa44f2577e92237525edc32James Dong        int64_t longitudex10000;
607b832a03d563dd000faa44f2577e92237525edc32James Dong        if (safe_strtoi64(value.string(), &longitudex10000)) {
60807b1bb529a1ae76c46a71b01338c166f9490629dJames Dong            return setParamGeoDataLongitude(longitudex10000);
60907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong        }
61007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    } else if (key == "param-geotag-latitude") {
611b832a03d563dd000faa44f2577e92237525edc32James Dong        int64_t latitudex10000;
612b832a03d563dd000faa44f2577e92237525edc32James Dong        if (safe_strtoi64(value.string(), &latitudex10000)) {
61307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong            return setParamGeoDataLatitude(latitudex10000);
61407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong        }
61593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    } else if (key == "param-track-time-status") {
61693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        int64_t timeDurationUs;
61793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        if (safe_strtoi64(value.string(), &timeDurationUs)) {
61893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong            return setParamTrackTimeStatus(timeDurationUs);
61993d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        }
620050b28a593350047845a45a14cc5026221ac1620James Dong    } else if (key == "audio-param-sampling-rate") {
621050b28a593350047845a45a14cc5026221ac1620James Dong        int32_t sampling_rate;
622ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        if (safe_strtoi32(value.string(), &sampling_rate)) {
623050b28a593350047845a45a14cc5026221ac1620James Dong            return setParamAudioSamplingRate(sampling_rate);
624050b28a593350047845a45a14cc5026221ac1620James Dong        }
625050b28a593350047845a45a14cc5026221ac1620James Dong    } else if (key == "audio-param-number-of-channels") {
626050b28a593350047845a45a14cc5026221ac1620James Dong        int32_t number_of_channels;
627ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        if (safe_strtoi32(value.string(), &number_of_channels)) {
628050b28a593350047845a45a14cc5026221ac1620James Dong            return setParamAudioNumberOfChannels(number_of_channels);
629050b28a593350047845a45a14cc5026221ac1620James Dong        }
630050b28a593350047845a45a14cc5026221ac1620James Dong    } else if (key == "audio-param-encoding-bitrate") {
631050b28a593350047845a45a14cc5026221ac1620James Dong        int32_t audio_bitrate;
632ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        if (safe_strtoi32(value.string(), &audio_bitrate)) {
633050b28a593350047845a45a14cc5026221ac1620James Dong            return setParamAudioEncodingBitRate(audio_bitrate);
634050b28a593350047845a45a14cc5026221ac1620James Dong        }
6358f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    } else if (key == "audio-param-time-scale") {
6368f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        int32_t timeScale;
6378f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        if (safe_strtoi32(value.string(), &timeScale)) {
6388f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong            return setParamAudioTimeScale(timeScale);
6398f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        }
640050b28a593350047845a45a14cc5026221ac1620James Dong    } else if (key == "video-param-encoding-bitrate") {
641050b28a593350047845a45a14cc5026221ac1620James Dong        int32_t video_bitrate;
642ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        if (safe_strtoi32(value.string(), &video_bitrate)) {
643050b28a593350047845a45a14cc5026221ac1620James Dong            return setParamVideoEncodingBitRate(video_bitrate);
644050b28a593350047845a45a14cc5026221ac1620James Dong        }
64513f6284305e4b27395a23db7882d670bdb1bcae1James Dong    } else if (key == "video-param-rotation-angle-degrees") {
64613f6284305e4b27395a23db7882d670bdb1bcae1James Dong        int32_t degrees;
64713f6284305e4b27395a23db7882d670bdb1bcae1James Dong        if (safe_strtoi32(value.string(), &degrees)) {
64813f6284305e4b27395a23db7882d670bdb1bcae1James Dong            return setParamVideoRotation(degrees);
64913f6284305e4b27395a23db7882d670bdb1bcae1James Dong        }
65093d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    } else if (key == "video-param-i-frames-interval") {
6518f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        int32_t seconds;
6528f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        if (safe_strtoi32(value.string(), &seconds)) {
6538f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong            return setParamVideoIFramesInterval(seconds);
654ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong        }
655145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    } else if (key == "video-param-encoder-profile") {
656145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong        int32_t profile;
657145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong        if (safe_strtoi32(value.string(), &profile)) {
658145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong            return setParamVideoEncoderProfile(profile);
659145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong        }
660145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    } else if (key == "video-param-encoder-level") {
661145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong        int32_t level;
662145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong        if (safe_strtoi32(value.string(), &level)) {
663145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong            return setParamVideoEncoderLevel(level);
664145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong        }
66593d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    } else if (key == "video-param-camera-id") {
66693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        int32_t cameraId;
66793d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong        if (safe_strtoi32(value.string(), &cameraId)) {
66893d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong            return setParamVideoCameraId(cameraId);
6692dec2b5be2056c6d9428897dc672185872d30d17James Dong        }
6708f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    } else if (key == "video-param-time-scale") {
6718f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        int32_t timeScale;
6728f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        if (safe_strtoi32(value.string(), &timeScale)) {
6738f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong            return setParamVideoTimeScale(timeScale);
6748f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong        }
675e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    } else if (key == "time-lapse-enable") {
676e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        int32_t timeLapseEnable;
677e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        if (safe_strtoi32(value.string(), &timeLapseEnable)) {
678e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra            return setParamTimeLapseEnable(timeLapseEnable);
679e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        }
680e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    } else if (key == "time-between-time-lapse-frame-capture") {
681e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        int64_t timeBetweenTimeLapseFrameCaptureMs;
682e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        if (safe_strtoi64(value.string(), &timeBetweenTimeLapseFrameCaptureMs)) {
683e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra            return setParamTimeBetweenTimeLapseFrameCapture(
684e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra                    1000LL * timeBetweenTimeLapseFrameCaptureMs);
685e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        }
686050b28a593350047845a45a14cc5026221ac1620James Dong    } else {
68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setParameter: failed to find key %s", key.string());
688050b28a593350047845a45a14cc5026221ac1620James Dong    }
689ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    return BAD_VALUE;
690050b28a593350047845a45a14cc5026221ac1620James Dong}
69130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
692050b28a593350047845a45a14cc5026221ac1620James Dongstatus_t StagefrightRecorder::setParameters(const String8 &params) {
6933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setParameters: %s", params.string());
694050b28a593350047845a45a14cc5026221ac1620James Dong    const char *cparams = params.string();
695050b28a593350047845a45a14cc5026221ac1620James Dong    const char *key_start = cparams;
696050b28a593350047845a45a14cc5026221ac1620James Dong    for (;;) {
697050b28a593350047845a45a14cc5026221ac1620James Dong        const char *equal_pos = strchr(key_start, '=');
698050b28a593350047845a45a14cc5026221ac1620James Dong        if (equal_pos == NULL) {
69929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Parameters %s miss a value", cparams);
700050b28a593350047845a45a14cc5026221ac1620James Dong            return BAD_VALUE;
701050b28a593350047845a45a14cc5026221ac1620James Dong        }
702050b28a593350047845a45a14cc5026221ac1620James Dong        String8 key(key_start, equal_pos - key_start);
703050b28a593350047845a45a14cc5026221ac1620James Dong        TrimString(&key);
704050b28a593350047845a45a14cc5026221ac1620James Dong        if (key.length() == 0) {
70529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Parameters %s contains an empty key", cparams);
706050b28a593350047845a45a14cc5026221ac1620James Dong            return BAD_VALUE;
707050b28a593350047845a45a14cc5026221ac1620James Dong        }
708050b28a593350047845a45a14cc5026221ac1620James Dong        const char *value_start = equal_pos + 1;
709050b28a593350047845a45a14cc5026221ac1620James Dong        const char *semicolon_pos = strchr(value_start, ';');
710050b28a593350047845a45a14cc5026221ac1620James Dong        String8 value;
711050b28a593350047845a45a14cc5026221ac1620James Dong        if (semicolon_pos == NULL) {
712050b28a593350047845a45a14cc5026221ac1620James Dong            value.setTo(value_start);
713050b28a593350047845a45a14cc5026221ac1620James Dong        } else {
714050b28a593350047845a45a14cc5026221ac1620James Dong            value.setTo(value_start, semicolon_pos - value_start);
715050b28a593350047845a45a14cc5026221ac1620James Dong        }
716050b28a593350047845a45a14cc5026221ac1620James Dong        if (setParameter(key, value) != OK) {
717050b28a593350047845a45a14cc5026221ac1620James Dong            return BAD_VALUE;
718050b28a593350047845a45a14cc5026221ac1620James Dong        }
719050b28a593350047845a45a14cc5026221ac1620James Dong        if (semicolon_pos == NULL) {
720050b28a593350047845a45a14cc5026221ac1620James Dong            break;  // Reaches the end
721050b28a593350047845a45a14cc5026221ac1620James Dong        }
722050b28a593350047845a45a14cc5026221ac1620James Dong        key_start = semicolon_pos + 1;
723050b28a593350047845a45a14cc5026221ac1620James Dong    }
72430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
72530ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
72630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
72737047fceba836f341d0108beed0991b0f8dfc543James Dongstatus_t StagefrightRecorder::setListener(const sp<IMediaRecorderClient> &listener) {
72830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    mListener = listener;
72930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
73030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
73130ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
73230ab66297501757d745b9ae10da61adcd891f497Andreas Huber
73330ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::prepare() {
73430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
73530ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
73630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
73730ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::start() {
738f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK_GE(mOutputFd, 0);
739934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong
74030ab66297501757d745b9ae10da61adcd891f497Andreas Huber    if (mWriter != NULL) {
74129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("File writer is not avaialble");
74230ab66297501757d745b9ae10da61adcd891f497Andreas Huber        return UNKNOWN_ERROR;
74330ab66297501757d745b9ae10da61adcd891f497Andreas Huber    }
74430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
74575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    status_t status = OK;
74675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
7472dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    switch (mOutputFormat) {
7482dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        case OUTPUT_FORMAT_DEFAULT:
7492dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        case OUTPUT_FORMAT_THREE_GPP:
7502dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        case OUTPUT_FORMAT_MPEG_4:
75175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            status = startMPEG4Recording();
75275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            break;
7532dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
7542dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        case OUTPUT_FORMAT_AMR_NB:
7552dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        case OUTPUT_FORMAT_AMR_WB:
75675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            status = startAMRRecording();
75775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            break;
7582dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
759ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        case OUTPUT_FORMAT_AAC_ADIF:
760ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        case OUTPUT_FORMAT_AAC_ADTS:
76175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            status = startAACRecording();
76275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            break;
763ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
76439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        case OUTPUT_FORMAT_RTP_AVP:
76575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            status = startRTPRecording();
76675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            break;
76739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
76859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        case OUTPUT_FORMAT_MPEG2TS:
76975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            status = startMPEG2TSRecording();
77075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            break;
77159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
7722dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        default:
77329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Unsupported output file format: %d", mOutputFormat);
77475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            status = UNKNOWN_ERROR;
77575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            break;
77675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    }
77775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
77875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    if ((status == OK) && (!mStarted)) {
77975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        mStarted = true;
78075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
78175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted;
782fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (mAudioSource != AUDIO_SOURCE_CNT) {
78375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            params |= IMediaPlayerService::kBatteryDataTrackAudio;
78475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        }
78575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        if (mVideoSource != VIDEO_SOURCE_LIST_END) {
78675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            params |= IMediaPlayerService::kBatteryDataTrackVideo;
78775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        }
78875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
78975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        addBatteryData(params);
7902dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    }
79175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
79275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    return status;
7932dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber}
7942dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
795050b28a593350047845a45a14cc5026221ac1620James Dongsp<MediaSource> StagefrightRecorder::createAudioSource() {
7962dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    sp<AudioSource> audioSource =
7972dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        new AudioSource(
7982dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber                mAudioSource,
799050b28a593350047845a45a14cc5026221ac1620James Dong                mSampleRate,
800be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong                mAudioChannels);
8012dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
8022dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    status_t err = audioSource->initCheck();
8032dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
8042dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    if (err != OK) {
80529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("audio source is not initialized");
8062dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        return NULL;
8072dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    }
8082dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
8092dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    sp<MetaData> encMeta = new MetaData;
810050b28a593350047845a45a14cc5026221ac1620James Dong    const char *mime;
811050b28a593350047845a45a14cc5026221ac1620James Dong    switch (mAudioEncoder) {
812050b28a593350047845a45a14cc5026221ac1620James Dong        case AUDIO_ENCODER_AMR_NB:
813050b28a593350047845a45a14cc5026221ac1620James Dong        case AUDIO_ENCODER_DEFAULT:
814050b28a593350047845a45a14cc5026221ac1620James Dong            mime = MEDIA_MIMETYPE_AUDIO_AMR_NB;
815050b28a593350047845a45a14cc5026221ac1620James Dong            break;
816050b28a593350047845a45a14cc5026221ac1620James Dong        case AUDIO_ENCODER_AMR_WB:
817050b28a593350047845a45a14cc5026221ac1620James Dong            mime = MEDIA_MIMETYPE_AUDIO_AMR_WB;
818050b28a593350047845a45a14cc5026221ac1620James Dong            break;
819050b28a593350047845a45a14cc5026221ac1620James Dong        case AUDIO_ENCODER_AAC:
820050b28a593350047845a45a14cc5026221ac1620James Dong            mime = MEDIA_MIMETYPE_AUDIO_AAC;
821aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectLC);
822aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            break;
823f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        case AUDIO_ENCODER_HE_AAC:
824f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            mime = MEDIA_MIMETYPE_AUDIO_AAC;
825f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectHE);
826f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            break;
827aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case AUDIO_ENCODER_AAC_ELD:
828aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mime = MEDIA_MIMETYPE_AUDIO_AAC;
829aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectELD);
830050b28a593350047845a45a14cc5026221ac1620James Dong            break;
831f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke
832050b28a593350047845a45a14cc5026221ac1620James Dong        default:
83329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Unknown audio encoder: %d", mAudioEncoder);
834050b28a593350047845a45a14cc5026221ac1620James Dong            return NULL;
835050b28a593350047845a45a14cc5026221ac1620James Dong    }
836050b28a593350047845a45a14cc5026221ac1620James Dong    encMeta->setCString(kKeyMIMEType, mime);
8372dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
838b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber    int32_t maxInputSize;
839b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber    CHECK(audioSource->getFormat()->findInt32(
840b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber                kKeyMaxInputSize, &maxInputSize));
841b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber
842b45c62c8e9b05c2703bdae18cc298ae55550db8aAndreas Huber    encMeta->setInt32(kKeyMaxInputSize, maxInputSize);
843050b28a593350047845a45a14cc5026221ac1620James Dong    encMeta->setInt32(kKeyChannelCount, mAudioChannels);
844050b28a593350047845a45a14cc5026221ac1620James Dong    encMeta->setInt32(kKeySampleRate, mSampleRate);
845ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    encMeta->setInt32(kKeyBitRate, mAudioBitRate);
846c059860c73678a202bfa33062723e8f82fb779d9James Dong    if (mAudioTimeScale > 0) {
847c059860c73678a202bfa33062723e8f82fb779d9James Dong        encMeta->setInt32(kKeyTimeScale, mAudioTimeScale);
848c059860c73678a202bfa33062723e8f82fb779d9James Dong    }
8492dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
8502dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    OMXClient client;
851f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK_EQ(client.connect(), (status_t)OK);
8522dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    sp<MediaSource> audioEncoder =
8532dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        OMXCodec::Create(client.interface(), encMeta,
8542dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber                         true /* createEncoder */, audioSource);
855d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    mAudioSourceNode = audioSource;
8562dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
8572dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    return audioEncoder;
8582dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber}
8592dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
860ef9d0cd72e476a4b7556833fb09505a51b626797James Dongstatus_t StagefrightRecorder::startAACRecording() {
861760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    // FIXME:
862760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    // Add support for OUTPUT_FORMAT_AAC_ADIF
863f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_AAC_ADTS);
864ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
865aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    CHECK(mAudioEncoder == AUDIO_ENCODER_AAC ||
866f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke          mAudioEncoder == AUDIO_ENCODER_HE_AAC ||
867aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke          mAudioEncoder == AUDIO_ENCODER_AAC_ELD);
868fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    CHECK(mAudioSource != AUDIO_SOURCE_CNT);
869ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
870760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    mWriter = new AACWriter(mOutputFd);
871760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    status_t status = startRawAudioRecording();
872760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    if (status != OK) {
873760943b5e7a09b602aba04ec451e97662f48b0a4James Dong        mWriter.clear();
874760943b5e7a09b602aba04ec451e97662f48b0a4James Dong        mWriter = NULL;
875760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    }
876ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
877760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    return status;
878ef9d0cd72e476a4b7556833fb09505a51b626797James Dong}
879ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
8802dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huberstatus_t StagefrightRecorder::startAMRRecording() {
881ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB ||
882ef9d0cd72e476a4b7556833fb09505a51b626797James Dong          mOutputFormat == OUTPUT_FORMAT_AMR_WB);
883ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
884ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    if (mOutputFormat == OUTPUT_FORMAT_AMR_NB) {
885ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        if (mAudioEncoder != AUDIO_ENCODER_DEFAULT &&
886ef9d0cd72e476a4b7556833fb09505a51b626797James Dong            mAudioEncoder != AUDIO_ENCODER_AMR_NB) {
88729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Invalid encoder %d used for AMRNB recording",
888ef9d0cd72e476a4b7556833fb09505a51b626797James Dong                    mAudioEncoder);
889934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            return BAD_VALUE;
890ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        }
891ef9d0cd72e476a4b7556833fb09505a51b626797James Dong    } else {  // mOutputFormat must be OUTPUT_FORMAT_AMR_WB
892ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) {
89329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Invlaid encoder %d used for AMRWB recording",
894ef9d0cd72e476a4b7556833fb09505a51b626797James Dong                    mAudioEncoder);
895934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            return BAD_VALUE;
896ef9d0cd72e476a4b7556833fb09505a51b626797James Dong        }
8972dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    }
8982dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
899760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    mWriter = new AMRWriter(mOutputFd);
900760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    status_t status = startRawAudioRecording();
901760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    if (status != OK) {
902760943b5e7a09b602aba04ec451e97662f48b0a4James Dong        mWriter.clear();
903760943b5e7a09b602aba04ec451e97662f48b0a4James Dong        mWriter = NULL;
904760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    }
905760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    return status;
906760943b5e7a09b602aba04ec451e97662f48b0a4James Dong}
907760943b5e7a09b602aba04ec451e97662f48b0a4James Dong
908760943b5e7a09b602aba04ec451e97662f48b0a4James Dongstatus_t StagefrightRecorder::startRawAudioRecording() {
909fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mAudioSource >= AUDIO_SOURCE_CNT) {
91029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid audio source: %d", mAudioSource);
911934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        return BAD_VALUE;
9122dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    }
9132dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
91442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    status_t status = BAD_VALUE;
91542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    if (OK != (status = checkAudioEncoderCapabilities())) {
91642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong        return status;
91742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    }
9182dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
91942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    sp<MediaSource> audioEncoder = createAudioSource();
9202dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    if (audioEncoder == NULL) {
9212dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber        return UNKNOWN_ERROR;
9222dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    }
9232dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
924760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    CHECK(mWriter != 0);
9252dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    mWriter->addSource(audioEncoder);
926d599cd4573b5a2d5914c5040e0565ef866749b77James Dong
927d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    if (mMaxFileDurationUs != 0) {
928d599cd4573b5a2d5914c5040e0565ef866749b77James Dong        mWriter->setMaxFileDuration(mMaxFileDurationUs);
929d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    }
930d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    if (mMaxFileSizeBytes != 0) {
931d599cd4573b5a2d5914c5040e0565ef866749b77James Dong        mWriter->setMaxFileSize(mMaxFileSizeBytes);
932d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    }
933d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    mWriter->setListener(mListener);
9342dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    mWriter->start();
9352dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
9362dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    return OK;
9372dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber}
9382dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
93939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t StagefrightRecorder::startRTPRecording() {
94039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_RTP_AVP);
94139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
942fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if ((mAudioSource != AUDIO_SOURCE_CNT
94339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                && mVideoSource != VIDEO_SOURCE_LIST_END)
944fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            || (mAudioSource == AUDIO_SOURCE_CNT
94539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                && mVideoSource == VIDEO_SOURCE_LIST_END)) {
94639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        // Must have exactly one source.
94739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return BAD_VALUE;
94839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
94939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
95039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mOutputFd < 0) {
95139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return BAD_VALUE;
95239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
95339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
95439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<MediaSource> source;
95539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
956fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mAudioSource != AUDIO_SOURCE_CNT) {
95739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        source = createAudioSource();
95839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else {
9599c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
960b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        sp<MediaSource> mediaSource;
961b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        status_t err = setupMediaSource(&mediaSource);
9629c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        if (err != OK) {
9639c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra            return err;
9649c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        }
9659c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
966b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        err = setupVideoEncoder(mediaSource, mVideoBitRate, &source);
96739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (err != OK) {
96839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return err;
96939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
97039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
97139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
972674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong    mWriter = new ARTPWriter(mOutputFd);
97339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mWriter->addSource(source);
97439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mWriter->setListener(mListener);
97539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
97639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return mWriter->start();
97739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
97839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
97959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huberstatus_t StagefrightRecorder::startMPEG2TSRecording() {
98059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_MPEG2TS);
98159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
982674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong    sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd);
98359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
984fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mAudioSource != AUDIO_SOURCE_CNT) {
985f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        if (mAudioEncoder != AUDIO_ENCODER_AAC &&
986f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            mAudioEncoder != AUDIO_ENCODER_HE_AAC &&
987f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            mAudioEncoder != AUDIO_ENCODER_AAC_ELD) {
98859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber            return ERROR_UNSUPPORTED;
98959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        }
99059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
99159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        status_t err = setupAudioEncoder(writer);
99259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
99359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        if (err != OK) {
99459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber            return err;
99559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        }
99659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    }
99759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
998b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    if (mVideoSource < VIDEO_SOURCE_LIST_END) {
99959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        if (mVideoEncoder != VIDEO_ENCODER_H264) {
100059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber            return ERROR_UNSUPPORTED;
100159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        }
100259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
1003b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        sp<MediaSource> mediaSource;
1004b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        status_t err = setupMediaSource(&mediaSource);
1005f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root        if (err != OK) {
1006f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root            return err;
1007f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root        }
1008f9f083e2853740c97588f4db82c24645ae5880e4Kenny Root
100959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        sp<MediaSource> encoder;
1010b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        err = setupVideoEncoder(mediaSource, mVideoBitRate, &encoder);
101159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
101259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        if (err != OK) {
101359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber            return err;
101459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        }
101559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
101659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        writer->addSource(encoder);
101759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    }
101859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
101959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    if (mMaxFileDurationUs != 0) {
102059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        writer->setMaxFileDuration(mMaxFileDurationUs);
102159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    }
102259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
102359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    if (mMaxFileSizeBytes != 0) {
102459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        writer->setMaxFileSize(mMaxFileSizeBytes);
102559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    }
102659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
102759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    mWriter = writer;
102859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
102959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    return mWriter->start();
103059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber}
103159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
103299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameRate() {
10333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("clipVideoFrameRate: encoder %d", mVideoEncoder);
103499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName(
103599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong                        "enc.vid.fps.min", mVideoEncoder);
103699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName(
103799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong                        "enc.vid.fps.max", mVideoEncoder);
1038b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (mFrameRate < minFrameRate && minFrameRate != -1) {
10395ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended video encoding frame rate (%d fps) is too small"
104099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong             " and will be set to (%d fps)", mFrameRate, minFrameRate);
104199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong        mFrameRate = minFrameRate;
1042b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    } else if (mFrameRate > maxFrameRate && maxFrameRate != -1) {
10435ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended video encoding frame rate (%d fps) is too large"
104499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong             " and will be set to (%d fps)", mFrameRate, maxFrameRate);
104599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong        mFrameRate = maxFrameRate;
104699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    }
104799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong}
104899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong
104999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoBitRate() {
10503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("clipVideoBitRate: encoder %d", mVideoEncoder);
105199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    int minBitRate = mEncoderProfiles->getVideoEncoderParamByName(
105299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong                        "enc.vid.bps.min", mVideoEncoder);
105399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    int maxBitRate = mEncoderProfiles->getVideoEncoderParamByName(
105499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong                        "enc.vid.bps.max", mVideoEncoder);
1055b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (mVideoBitRate < minBitRate && minBitRate != -1) {
10565ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended video encoding bit rate (%d bps) is too small"
105799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong             " and will be set to (%d bps)", mVideoBitRate, minBitRate);
105899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong        mVideoBitRate = minBitRate;
1059b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    } else if (mVideoBitRate > maxBitRate && maxBitRate != -1) {
10605ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended video encoding bit rate (%d bps) is too large"
106199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong             " and will be set to (%d bps)", mVideoBitRate, maxBitRate);
106299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong        mVideoBitRate = maxBitRate;
106399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    }
106499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong}
106599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong
106699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameWidth() {
10673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("clipVideoFrameWidth: encoder %d", mVideoEncoder);
106899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    int minFrameWidth = mEncoderProfiles->getVideoEncoderParamByName(
106999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong                        "enc.vid.width.min", mVideoEncoder);
107099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    int maxFrameWidth = mEncoderProfiles->getVideoEncoderParamByName(
107199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong                        "enc.vid.width.max", mVideoEncoder);
1072b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (mVideoWidth < minFrameWidth && minFrameWidth != -1) {
10735ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended video encoding frame width (%d) is too small"
107499c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong             " and will be set to (%d)", mVideoWidth, minFrameWidth);
107599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong        mVideoWidth = minFrameWidth;
1076b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    } else if (mVideoWidth > maxFrameWidth && maxFrameWidth != -1) {
10775ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended video encoding frame width (%d) is too large"
107899c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong             " and will be set to (%d)", mVideoWidth, maxFrameWidth);
107999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong        mVideoWidth = maxFrameWidth;
108099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    }
108199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong}
108299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong
108354ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t StagefrightRecorder::checkVideoEncoderCapabilities() {
1084ca2fa61ef03cac008ea86e6fe16b2e5f9f1a2be3Nipun Kwatra    if (!mCaptureTimeLapse) {
1085e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        // Dont clip for time lapse capture as encoder will have enough
1086e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        // time to encode because of slow capture rate of time lapse.
1087e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        clipVideoBitRate();
1088e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        clipVideoFrameRate();
1089e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        clipVideoFrameWidth();
1090e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra        clipVideoFrameHeight();
1091d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        setDefaultProfileIfNecessary();
1092e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    }
1093934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    return OK;
1094934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong}
1095934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong
1096d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong// Set to use AVC baseline profile if the encoding parameters matches
1097d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong// CAMCORDER_QUALITY_LOW profile; this is for the sake of MMS service.
1098d552b88515c6ccd18695e5db5e6032a6425d8c63James Dongvoid StagefrightRecorder::setDefaultProfileIfNecessary() {
10993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setDefaultProfileIfNecessary");
1100d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1101d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    camcorder_quality quality = CAMCORDER_QUALITY_LOW;
1102d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1103d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int64_t durationUs   = mEncoderProfiles->getCamcorderProfileParamByName(
1104d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "duration", mCameraId, quality) * 1000000LL;
1105d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1106d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int fileFormat       = mEncoderProfiles->getCamcorderProfileParamByName(
1107d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "file.format", mCameraId, quality);
1108d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1109d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int videoCodec       = mEncoderProfiles->getCamcorderProfileParamByName(
1110d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "vid.codec", mCameraId, quality);
1111d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1112d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int videoBitRate     = mEncoderProfiles->getCamcorderProfileParamByName(
1113d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "vid.bps", mCameraId, quality);
1114d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1115d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int videoFrameRate   = mEncoderProfiles->getCamcorderProfileParamByName(
1116d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "vid.fps", mCameraId, quality);
1117d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1118d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int videoFrameWidth  = mEncoderProfiles->getCamcorderProfileParamByName(
1119d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "vid.width", mCameraId, quality);
1120d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1121d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int videoFrameHeight = mEncoderProfiles->getCamcorderProfileParamByName(
1122d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "vid.height", mCameraId, quality);
1123d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1124d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int audioCodec       = mEncoderProfiles->getCamcorderProfileParamByName(
1125d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "aud.codec", mCameraId, quality);
1126d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1127d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int audioBitRate     = mEncoderProfiles->getCamcorderProfileParamByName(
1128d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "aud.bps", mCameraId, quality);
1129d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1130d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int audioSampleRate  = mEncoderProfiles->getCamcorderProfileParamByName(
1131d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "aud.hz", mCameraId, quality);
1132d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1133d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    int audioChannels    = mEncoderProfiles->getCamcorderProfileParamByName(
1134d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong                                "aud.ch", mCameraId, quality);
1135d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
1136d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    if (durationUs == mMaxFileDurationUs &&
1137d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        fileFormat == mOutputFormat &&
1138d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        videoCodec == mVideoEncoder &&
1139d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        videoBitRate == mVideoBitRate &&
1140d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        videoFrameRate == mFrameRate &&
1141d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        videoFrameWidth == mVideoWidth &&
1142d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        videoFrameHeight == mVideoHeight &&
1143d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        audioCodec == mAudioEncoder &&
1144d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        audioBitRate == mAudioBitRate &&
1145d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        audioSampleRate == mSampleRate &&
1146d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        audioChannels == mAudioChannels) {
1147d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        if (videoCodec == VIDEO_ENCODER_H264) {
1148df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("Force to use AVC baseline profile");
1149d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong            setParamVideoEncoderProfile(OMX_VIDEO_AVCProfileBaseline);
1150d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong        }
1151d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong    }
1152d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong}
1153d552b88515c6ccd18695e5db5e6032a6425d8c63James Dong
115442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongstatus_t StagefrightRecorder::checkAudioEncoderCapabilities() {
115542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    clipAudioBitRate();
115642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    clipAudioSampleRate();
115742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    clipNumberOfAudioChannels();
115842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    return OK;
115942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong}
116042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
116142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipAudioBitRate() {
11623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("clipAudioBitRate: encoder %d", mAudioEncoder);
116342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
116442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    int minAudioBitRate =
116542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            mEncoderProfiles->getAudioEncoderParamByName(
116642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong                "enc.aud.bps.min", mAudioEncoder);
1167b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (minAudioBitRate != -1 && mAudioBitRate < minAudioBitRate) {
11685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended audio encoding bit rate (%d) is too small"
116942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            " and will be set to (%d)", mAudioBitRate, minAudioBitRate);
117042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong        mAudioBitRate = minAudioBitRate;
117142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    }
117242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
117342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    int maxAudioBitRate =
117442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            mEncoderProfiles->getAudioEncoderParamByName(
117542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong                "enc.aud.bps.max", mAudioEncoder);
1176b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (maxAudioBitRate != -1 && mAudioBitRate > maxAudioBitRate) {
11775ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended audio encoding bit rate (%d) is too large"
117842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            " and will be set to (%d)", mAudioBitRate, maxAudioBitRate);
117942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong        mAudioBitRate = maxAudioBitRate;
118042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    }
118142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong}
118242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
118342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipAudioSampleRate() {
11843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("clipAudioSampleRate: encoder %d", mAudioEncoder);
118542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
118642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    int minSampleRate =
118742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            mEncoderProfiles->getAudioEncoderParamByName(
118842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong                "enc.aud.hz.min", mAudioEncoder);
1189b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (minSampleRate != -1 && mSampleRate < minSampleRate) {
11905ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended audio sample rate (%d) is too small"
119142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            " and will be set to (%d)", mSampleRate, minSampleRate);
119242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong        mSampleRate = minSampleRate;
119342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    }
119442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
119542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    int maxSampleRate =
119642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            mEncoderProfiles->getAudioEncoderParamByName(
119742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong                "enc.aud.hz.max", mAudioEncoder);
1198b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (maxSampleRate != -1 && mSampleRate > maxSampleRate) {
11995ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended audio sample rate (%d) is too large"
120042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            " and will be set to (%d)", mSampleRate, maxSampleRate);
120142dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong        mSampleRate = maxSampleRate;
120242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    }
120342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong}
120442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
120542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dongvoid StagefrightRecorder::clipNumberOfAudioChannels() {
12063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("clipNumberOfAudioChannels: encoder %d", mAudioEncoder);
120742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
120842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    int minChannels =
120942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            mEncoderProfiles->getAudioEncoderParamByName(
121042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong                "enc.aud.ch.min", mAudioEncoder);
1211b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (minChannels != -1 && mAudioChannels < minChannels) {
12125ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended number of audio channels (%d) is too small"
121342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            " and will be set to (%d)", mAudioChannels, minChannels);
121442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong        mAudioChannels = minChannels;
121542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    }
121642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
121742dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    int maxChannels =
121842dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            mEncoderProfiles->getAudioEncoderParamByName(
121942dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong                "enc.aud.ch.max", mAudioEncoder);
1220b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (maxChannels != -1 && mAudioChannels > maxChannels) {
12215ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended number of audio channels (%d) is too large"
122242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong            " and will be set to (%d)", mAudioChannels, maxChannels);
122342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong        mAudioChannels = maxChannels;
122442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    }
122542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong}
122642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
122799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dongvoid StagefrightRecorder::clipVideoFrameHeight() {
12283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("clipVideoFrameHeight: encoder %d", mVideoEncoder);
122999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    int minFrameHeight = mEncoderProfiles->getVideoEncoderParamByName(
123099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong                        "enc.vid.height.min", mVideoEncoder);
123199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    int maxFrameHeight = mEncoderProfiles->getVideoEncoderParamByName(
123299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong                        "enc.vid.height.max", mVideoEncoder);
1233b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    if (minFrameHeight != -1 && mVideoHeight < minFrameHeight) {
12345ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended video encoding frame height (%d) is too small"
123599c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong             " and will be set to (%d)", mVideoHeight, minFrameHeight);
123699c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong        mVideoHeight = minFrameHeight;
1237b4a55269a5b39c73de2cc1d4013d0631ef18c77dJames Dong    } else if (maxFrameHeight != -1 && mVideoHeight > maxFrameHeight) {
12385ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Intended video encoding frame height (%d) is too large"
123999c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong             " and will be set to (%d)", mVideoHeight, maxFrameHeight);
124099c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong        mVideoHeight = maxFrameHeight;
124199c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    }
124299c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong}
124399c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong
1244b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// Set up the appropriate MediaSource depending on the chosen option
1245b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketistatus_t StagefrightRecorder::setupMediaSource(
1246b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                      sp<MediaSource> *mediaSource) {
1247b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    if (mVideoSource == VIDEO_SOURCE_DEFAULT
1248b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi            || mVideoSource == VIDEO_SOURCE_CAMERA) {
1249b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        sp<CameraSource> cameraSource;
1250b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        status_t err = setupCameraSource(&cameraSource);
1251b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        if (err != OK) {
1252b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi            return err;
1253b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        }
1254b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        *mediaSource = cameraSource;
1255b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
1256b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        // If using GRAlloc buffers, setup surfacemediasource.
1257b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        // Later a handle to that will be passed
1258b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        // to the client side when queried
1259b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        status_t err = setupSurfaceMediaSource();
1260b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        if (err != OK) {
1261b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi            return err;
1262b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        }
1263b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        *mediaSource = mSurfaceMediaSource;
1264b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    } else {
1265b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        return INVALID_OPERATION;
1266b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    }
1267b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    return OK;
1268b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi}
1269b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
1270b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// setupSurfaceMediaSource creates a source with the given
1271b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// width and height and framerate.
1272b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// TODO: This could go in a static function inside SurfaceMediaSource
1273b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi// similar to that in CameraSource
1274b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketistatus_t StagefrightRecorder::setupSurfaceMediaSource() {
1275b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    status_t err = OK;
1276b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    mSurfaceMediaSource = new SurfaceMediaSource(mVideoWidth, mVideoHeight);
1277b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    if (mSurfaceMediaSource == NULL) {
1278b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        return NO_INIT;
1279b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    }
1280b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
1281b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    if (mFrameRate == -1) {
1282b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        int32_t frameRate = 0;
1283b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        CHECK (mSurfaceMediaSource->getFormat()->findInt32(
1284b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                                        kKeyFrameRate, &frameRate));
1285df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("Frame rate is not explicitly set. Use the current frame "
1286b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi             "rate (%d fps)", frameRate);
1287b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        mFrameRate = frameRate;
1288b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    } else {
1289b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        err = mSurfaceMediaSource->setFrameRate(mFrameRate);
1290b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    }
1291b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    CHECK(mFrameRate != -1);
1292b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
1293b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    mIsMetaDataStoredInVideoBuffers =
1294b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        mSurfaceMediaSource->isMetaDataStoredInVideoBuffers();
1295b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    return err;
1296b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi}
1297b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
12988480835b4bc1350646376aa7f3ae33742a7adeb1James Dongstatus_t StagefrightRecorder::setupCameraSource(
12998480835b4bc1350646376aa7f3ae33742a7adeb1James Dong        sp<CameraSource> *cameraSource) {
1300635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    status_t err = OK;
1301635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    if ((err = checkVideoEncoderCapabilities()) != OK) {
1302635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        return err;
1303635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    }
130454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Size videoSize;
130554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    videoSize.width = mVideoWidth;
130654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    videoSize.height = mVideoHeight;
130778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mCaptureTimeLapse) {
13082e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong        if (mTimeBetweenTimeLapseFrameCaptureUs < 0) {
13092e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong            ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %lld",
13102e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong                mTimeBetweenTimeLapseFrameCaptureUs);
13112e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong            return BAD_VALUE;
13122e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong        }
13132e77ad2a9f7afb57b6f9127dd7c229e774baa9c8James Dong
131454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(
13154ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li                mCamera, mCameraProxy, mCameraId,
131654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                videoSize, mFrameRate, mPreviewSurface,
131754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                mTimeBetweenTimeLapseFrameCaptureUs);
131878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        *cameraSource = mCameraSourceTimeLapse;
131978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    } else {
132054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        *cameraSource = CameraSource::CreateFromCamera(
13214ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li                mCamera, mCameraProxy, mCameraId, videoSize, mFrameRate,
13228480835b4bc1350646376aa7f3ae33742a7adeb1James Dong                mPreviewSurface, true /*storeMetaDataInVideoBuffers*/);
132378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
13244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mCamera.clear();
13254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mCameraProxy.clear();
1326ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong    if (*cameraSource == NULL) {
1327ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong        return UNKNOWN_ERROR;
1328ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong    }
1329ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong
1330ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong    if ((*cameraSource)->initCheck() != OK) {
1331ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong        (*cameraSource).clear();
1332ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong        *cameraSource = NULL;
1333ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong        return NO_INIT;
1334ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong    }
13359c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
1336635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    // When frame rate is not set, the actual frame rate will be set to
1337635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    // the current frame rate being used.
1338635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    if (mFrameRate == -1) {
1339635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        int32_t frameRate = 0;
1340635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        CHECK ((*cameraSource)->getFormat()->findInt32(
1341393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong                    kKeyFrameRate, &frameRate));
1342df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("Frame rate is not explicitly set. Use the current frame "
1343635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong             "rate (%d fps)", frameRate);
1344635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        mFrameRate = frameRate;
1345635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    }
1346635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong
1347635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    CHECK(mFrameRate != -1);
13488480835b4bc1350646376aa7f3ae33742a7adeb1James Dong
13498480835b4bc1350646376aa7f3ae33742a7adeb1James Dong    mIsMetaDataStoredInVideoBuffers =
13508480835b4bc1350646376aa7f3ae33742a7adeb1James Dong        (*cameraSource)->isMetaDataStoredInVideoBuffers();
13518480835b4bc1350646376aa7f3ae33742a7adeb1James Dong
13529c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    return OK;
13539c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra}
13549c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
13559c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatrastatus_t StagefrightRecorder::setupVideoEncoder(
13569c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        sp<MediaSource> cameraSource,
13579c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        int32_t videoBitRate,
13589c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        sp<MediaSource> *source) {
13599c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    source->clear();
1360050b28a593350047845a45a14cc5026221ac1620James Dong
1361934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    sp<MetaData> enc_meta = new MetaData;
13629c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    enc_meta->setInt32(kKeyBitRate, videoBitRate);
1363393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong    enc_meta->setInt32(kKeyFrameRate, mFrameRate);
1364ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
1365934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    switch (mVideoEncoder) {
1366934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        case VIDEO_ENCODER_H263:
1367934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
1368934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            break;
136965ae665befd929efd1a7d1c9addac41c699f04b2James Dong
1370934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        case VIDEO_ENCODER_MPEG_4_SP:
1371934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
1372934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            break;
137330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1374934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        case VIDEO_ENCODER_H264:
1375934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
1376934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            break;
137730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1378934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        default:
1379934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            CHECK(!"Should not be here, unsupported video encoding.");
1380934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            break;
1381934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    }
1382ef9d0cd72e476a4b7556833fb09505a51b626797James Dong
1383934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    sp<MetaData> meta = cameraSource->getFormat();
138430ab66297501757d745b9ae10da61adcd891f497Andreas Huber
138529a84457aed4c45bc900998b5e11c03023264208James Dong    int32_t width, height, stride, sliceHeight, colorFormat;
1386934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    CHECK(meta->findInt32(kKeyWidth, &width));
1387934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    CHECK(meta->findInt32(kKeyHeight, &height));
1388934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    CHECK(meta->findInt32(kKeyStride, &stride));
1389934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
139029a84457aed4c45bc900998b5e11c03023264208James Dong    CHECK(meta->findInt32(kKeyColorFormat, &colorFormat));
139130ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1392934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    enc_meta->setInt32(kKeyWidth, width);
1393934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    enc_meta->setInt32(kKeyHeight, height);
13948f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    enc_meta->setInt32(kKeyIFramesInterval, mIFramesIntervalSec);
1395934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    enc_meta->setInt32(kKeyStride, stride);
1396934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    enc_meta->setInt32(kKeySliceHeight, sliceHeight);
139729a84457aed4c45bc900998b5e11c03023264208James Dong    enc_meta->setInt32(kKeyColorFormat, colorFormat);
1398c059860c73678a202bfa33062723e8f82fb779d9James Dong    if (mVideoTimeScale > 0) {
1399c059860c73678a202bfa33062723e8f82fb779d9James Dong        enc_meta->setInt32(kKeyTimeScale, mVideoTimeScale);
1400c059860c73678a202bfa33062723e8f82fb779d9James Dong    }
1401145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    if (mVideoEncoderProfile != -1) {
1402145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong        enc_meta->setInt32(kKeyVideoProfile, mVideoEncoderProfile);
1403145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    }
1404145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    if (mVideoEncoderLevel != -1) {
1405145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong        enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel);
1406145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    }
140730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1408934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    OMXClient client;
1409f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK_EQ(client.connect(), (status_t)OK);
141030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
14111cc73922339a110d7ffc47e8842f958492dd85bfJames Dong    uint32_t encoder_flags = 0;
14122b4883641e324c50a2ee24c5bd15170c7d31e57dJames Dong    if (mIsMetaDataStoredInVideoBuffers) {
14138480835b4bc1350646376aa7f3ae33742a7adeb1James Dong        encoder_flags |= OMXCodec::kStoreMetaDataInVideoBuffers;
14148480835b4bc1350646376aa7f3ae33742a7adeb1James Dong    }
14157757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong
14167757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong    // Do not wait for all the input buffers to become available.
14177757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong    // This give timelapse video recording faster response in
14187757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong    // receiving output from video encoder component.
14197757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong    if (mCaptureTimeLapse) {
14207757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong        encoder_flags |= OMXCodec::kOnlySubmitOneInputBufferAtOneTime;
14217757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong    }
14227757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong
1423934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    sp<MediaSource> encoder = OMXCodec::Create(
1424934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            client.interface(), enc_meta,
14257a42770f47225483a885b168d05e81b6a81189c0Nipun Kwatra            true /* createEncoder */, cameraSource,
14267a42770f47225483a885b168d05e81b6a81189c0Nipun Kwatra            NULL, encoder_flags);
1427934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    if (encoder == NULL) {
14285ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Failed to create the encoder");
14291cc73922339a110d7ffc47e8842f958492dd85bfJames Dong        // When the encoder fails to be created, we need
14301cc73922339a110d7ffc47e8842f958492dd85bfJames Dong        // release the camera source due to the camera's lock
14311cc73922339a110d7ffc47e8842f958492dd85bfJames Dong        // and unlock mechanism.
14321cc73922339a110d7ffc47e8842f958492dd85bfJames Dong        cameraSource->stop();
1433934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        return UNKNOWN_ERROR;
1434934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    }
143530ab66297501757d745b9ae10da61adcd891f497Andreas Huber
143639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    *source = encoder;
143739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
1438934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    return OK;
1439934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong}
144030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1441934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dongstatus_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) {
144242dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    status_t status = BAD_VALUE;
144342dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    if (OK != (status = checkAudioEncoderCapabilities())) {
144442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong        return status;
144542dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    }
144642dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
1447934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    switch(mAudioEncoder) {
1448934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        case AUDIO_ENCODER_AMR_NB:
1449934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        case AUDIO_ENCODER_AMR_WB:
1450934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        case AUDIO_ENCODER_AAC:
1451f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        case AUDIO_ENCODER_HE_AAC:
1452aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case AUDIO_ENCODER_AAC_ELD:
1453934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            break;
145442dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong
1455934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        default:
145629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Unsupported audio encoder: %d", mAudioEncoder);
1457934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong            return UNKNOWN_ERROR;
1458934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    }
145930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
146042dd1d5f186252a7f09f8fb1a46ea82e3877b2d3James Dong    sp<MediaSource> audioEncoder = createAudioSource();
1461934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    if (audioEncoder == NULL) {
1462934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        return UNKNOWN_ERROR;
1463934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    }
14648f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong
1465934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    writer->addSource(audioEncoder);
1466934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    return OK;
1467934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong}
146830ab66297501757d745b9ae10da61adcd891f497Andreas Huber
14699c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatrastatus_t StagefrightRecorder::setupMPEG4Recording(
1470cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra        int outputFd,
1471cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra        int32_t videoWidth, int32_t videoHeight,
1472cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra        int32_t videoBitRate,
14739c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        int32_t *totalBitRate,
14749c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        sp<MediaWriter> *mediaWriter) {
14759c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    mediaWriter->clear();
14769c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    *totalBitRate = 0;
1477934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong    status_t err = OK;
1478674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong    sp<MediaWriter> writer = new MPEG4Writer(outputFd);
147930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1480b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    if (mVideoSource < VIDEO_SOURCE_LIST_END) {
14819c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
1482b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        sp<MediaSource> mediaSource;
14833cecf640c4daf2df616b278bd9986018c8182908James Dong        err = setupMediaSource(&mediaSource);
14849c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        if (err != OK) {
14859c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra            return err;
14869c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        }
14879c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
148839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        sp<MediaSource> encoder;
1489b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        err = setupVideoEncoder(mediaSource, videoBitRate, &encoder);
14909c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        if (err != OK) {
14919c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra            return err;
14929c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        }
14939c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
149439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        writer->addSource(encoder);
14959c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        *totalBitRate += videoBitRate;
149630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    }
149730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
14987bd460110b27a979384dda351788eac95d8467f5James Dong    // Audio source is added at the end if it exists.
14997bd460110b27a979384dda351788eac95d8467f5James Dong    // This help make sure that the "recoding" sound is suppressed for
15007bd460110b27a979384dda351788eac95d8467f5James Dong    // camcorder applications in the recorded files.
1501fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_CNT)) {
15027bd460110b27a979384dda351788eac95d8467f5James Dong        err = setupAudioEncoder(writer);
15037bd460110b27a979384dda351788eac95d8467f5James Dong        if (err != OK) return err;
15047bd460110b27a979384dda351788eac95d8467f5James Dong        *totalBitRate += mAudioBitRate;
15057bd460110b27a979384dda351788eac95d8467f5James Dong    }
15067bd460110b27a979384dda351788eac95d8467f5James Dong
1507f01528f435e6b1f02d118fcd8305a148c27a89f1James Dong    if (mInterleaveDurationUs > 0) {
1508f01528f435e6b1f02d118fcd8305a148c27a89f1James Dong        reinterpret_cast<MPEG4Writer *>(writer.get())->
1509f01528f435e6b1f02d118fcd8305a148c27a89f1James Dong            setInterleaveDuration(mInterleaveDurationUs);
1510f01528f435e6b1f02d118fcd8305a148c27a89f1James Dong    }
151107b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) {
151207b1bb529a1ae76c46a71b01338c166f9490629dJames Dong        reinterpret_cast<MPEG4Writer *>(writer.get())->
151307b1bb529a1ae76c46a71b01338c166f9490629dJames Dong            setGeoData(mLatitudex10000, mLongitudex10000);
151407b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    }
1515d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    if (mMaxFileDurationUs != 0) {
1516934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        writer->setMaxFileDuration(mMaxFileDurationUs);
1517d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    }
1518d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    if (mMaxFileSizeBytes != 0) {
1519934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        writer->setMaxFileSize(mMaxFileSizeBytes);
1520d599cd4573b5a2d5914c5040e0565ef866749b77James Dong    }
15219c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
152286b7f47aa7482424cf8fd248f1315311919be3b0James Dong    mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId);
152386b7f47aa7482424cf8fd248f1315311919be3b0James Dong    if (mStartTimeOffsetMs > 0) {
152486b7f47aa7482424cf8fd248f1315311919be3b0James Dong        reinterpret_cast<MPEG4Writer *>(writer.get())->
152586b7f47aa7482424cf8fd248f1315311919be3b0James Dong            setStartTimeOffsetMs(mStartTimeOffsetMs);
152686b7f47aa7482424cf8fd248f1315311919be3b0James Dong    }
152786b7f47aa7482424cf8fd248f1315311919be3b0James Dong
15289c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    writer->setListener(mListener);
15299c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    *mediaWriter = writer;
15309c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    return OK;
15319c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra}
15329c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
15339c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatravoid StagefrightRecorder::setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate,
15349c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        sp<MetaData> *meta) {
15359c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    (*meta)->setInt64(kKeyTime, startTimeUs);
15369c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    (*meta)->setInt32(kKeyFileType, mOutputFormat);
15379c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    (*meta)->setInt32(kKeyBitRate, totalBitRate);
15389c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
1539c059860c73678a202bfa33062723e8f82fb779d9James Dong    if (mMovieTimeScale > 0) {
15409c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale);
1541c059860c73678a202bfa33062723e8f82fb779d9James Dong    }
154293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    if (mTrackEveryTimeDurationUs > 0) {
15439c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
154493d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    }
154513f6284305e4b27395a23db7882d670bdb1bcae1James Dong    if (mRotationDegrees != 0) {
154613f6284305e4b27395a23db7882d670bdb1bcae1James Dong        (*meta)->setInt32(kKeyRotation, mRotationDegrees);
154713f6284305e4b27395a23db7882d670bdb1bcae1James Dong    }
15489c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra}
15499c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
15509c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatrastatus_t StagefrightRecorder::startMPEG4Recording() {
15519c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    int32_t totalBitRate;
15523cecf640c4daf2df616b278bd9986018c8182908James Dong    status_t err = setupMPEG4Recording(
1553cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra            mOutputFd, mVideoWidth, mVideoHeight,
1554cfe88a20345dad981842b2c8092e4c704d3f98b4Nipun Kwatra            mVideoBitRate, &totalBitRate, &mWriter);
15559c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    if (err != OK) {
15569c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        return err;
15579c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    }
15589c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
15599c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    int64_t startTimeUs = systemTime() / 1000;
15609c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    sp<MetaData> meta = new MetaData;
15619c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    setupMPEG4MetaData(startTimeUs, totalBitRate, &meta);
15629c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
15639c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    err = mWriter->start(meta.get());
15649c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    if (err != OK) {
15659c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra        return err;
15669c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    }
15679c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
15689c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra    return OK;
156930ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
157030ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1571a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dongstatus_t StagefrightRecorder::pause() {
15723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("pause");
1573a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    if (mWriter == NULL) {
1574a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong        return UNKNOWN_ERROR;
1575a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    }
1576a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    mWriter->pause();
15779c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
157875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    if (mStarted) {
157975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        mStarted = false;
158075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
158175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        uint32_t params = 0;
1582fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (mAudioSource != AUDIO_SOURCE_CNT) {
158375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            params |= IMediaPlayerService::kBatteryDataTrackAudio;
158475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        }
158575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        if (mVideoSource != VIDEO_SOURCE_LIST_END) {
158675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            params |= IMediaPlayerService::kBatteryDataTrackVideo;
158775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        }
158875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
158975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        addBatteryData(params);
159075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    }
159175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
159275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
1593a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    return OK;
1594a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong}
1595a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong
159630ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::stop() {
15973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stop");
159837187916a486504acaf83bea30147eb5fbf46ae5James Dong    status_t err = OK;
15999c075bca0b75093ca0514a3c8f74d73c8e9e83fdNipun Kwatra
160078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mCaptureTimeLapse && mCameraSourceTimeLapse != NULL) {
160178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        mCameraSourceTimeLapse->startQuickReadReturns();
160278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        mCameraSourceTimeLapse = NULL;
160378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
160478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1605d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (mWriter != NULL) {
160637187916a486504acaf83bea30147eb5fbf46ae5James Dong        err = mWriter->stop();
1607934da11c4cc598d3dd3b53726c362bcdcc0fd37fJames Dong        mWriter.clear();
160830ab66297501757d745b9ae10da61adcd891f497Andreas Huber    }
160930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
161025d83125cee222993673d3ba261ae1186bcad8c2James Dong    if (mOutputFd >= 0) {
161125d83125cee222993673d3ba261ae1186bcad8c2James Dong        ::close(mOutputFd);
161225d83125cee222993673d3ba261ae1186bcad8c2James Dong        mOutputFd = -1;
161325d83125cee222993673d3ba261ae1186bcad8c2James Dong    }
161425d83125cee222993673d3ba261ae1186bcad8c2James Dong
161575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    if (mStarted) {
161675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        mStarted = false;
161775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
161875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        uint32_t params = 0;
1619fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (mAudioSource != AUDIO_SOURCE_CNT) {
162075b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            params |= IMediaPlayerService::kBatteryDataTrackAudio;
162175b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        }
162275b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        if (mVideoSource != VIDEO_SOURCE_LIST_END) {
162375b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang            params |= IMediaPlayerService::kBatteryDataTrackVideo;
162475b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        }
162575b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
162675b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang        addBatteryData(params);
162775b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang    }
162875b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
162975b0b5473c7b43f8c5972db7e6e8930988ead751Gloria Wang
163037187916a486504acaf83bea30147eb5fbf46ae5James Dong    return err;
1631d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong}
1632d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
1633d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dongstatus_t StagefrightRecorder::close() {
16343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("close");
1635d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    stop();
1636d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
163730ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
163830ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
163930ab66297501757d745b9ae10da61adcd891f497Andreas Huber
164030ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::reset() {
16413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("reset");
164230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    stop();
164330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1644050b28a593350047845a45a14cc5026221ac1620James Dong    // No audio or video source by default
1645fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mAudioSource = AUDIO_SOURCE_CNT;
164630ab66297501757d745b9ae10da61adcd891f497Andreas Huber    mVideoSource = VIDEO_SOURCE_LIST_END;
1647050b28a593350047845a45a14cc5026221ac1620James Dong
1648050b28a593350047845a45a14cc5026221ac1620James Dong    // Default parameters
1649050b28a593350047845a45a14cc5026221ac1620James Dong    mOutputFormat  = OUTPUT_FORMAT_THREE_GPP;
1650050b28a593350047845a45a14cc5026221ac1620James Dong    mAudioEncoder  = AUDIO_ENCODER_AMR_NB;
1651050b28a593350047845a45a14cc5026221ac1620James Dong    mVideoEncoder  = VIDEO_ENCODER_H263;
1652050b28a593350047845a45a14cc5026221ac1620James Dong    mVideoWidth    = 176;
1653050b28a593350047845a45a14cc5026221ac1620James Dong    mVideoHeight   = 144;
1654635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong    mFrameRate     = -1;
1655050b28a593350047845a45a14cc5026221ac1620James Dong    mVideoBitRate  = 192000;
1656050b28a593350047845a45a14cc5026221ac1620James Dong    mSampleRate    = 8000;
1657050b28a593350047845a45a14cc5026221ac1620James Dong    mAudioChannels = 1;
1658050b28a593350047845a45a14cc5026221ac1620James Dong    mAudioBitRate  = 12200;
1659e136c3bb38e88315bf8797a464ebf2c788296b22James Dong    mInterleaveDurationUs = 0;
16608f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    mIFramesIntervalSec = 1;
1661d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    mAudioSourceNode = 0;
16622dec2b5be2056c6d9428897dc672185872d30d17James Dong    mUse64BitFileOffset = false;
1663c059860c73678a202bfa33062723e8f82fb779d9James Dong    mMovieTimeScale  = -1;
1664c059860c73678a202bfa33062723e8f82fb779d9James Dong    mAudioTimeScale  = -1;
1665c059860c73678a202bfa33062723e8f82fb779d9James Dong    mVideoTimeScale  = -1;
166693d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    mCameraId        = 0;
166786b7f47aa7482424cf8fd248f1315311919be3b0James Dong    mStartTimeOffsetMs = -1;
1668145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    mVideoEncoderProfile = -1;
1669145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    mVideoEncoderLevel   = -1;
1670145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    mMaxFileDurationUs = 0;
1671145bfe5eb3e08c9689c28f6bf3287a979438b04bJames Dong    mMaxFileSizeBytes = 0;
167293d6b102a13afa23bfa80d74c399d93d542e6ad6James Dong    mTrackEveryTimeDurationUs = 0;
1673fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra    mCaptureTimeLapse = false;
1674e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra    mTimeBetweenTimeLapseFrameCaptureUs = -1;
167578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mCameraSourceTimeLapse = NULL;
16768480835b4bc1350646376aa7f3ae33742a7adeb1James Dong    mIsMetaDataStoredInVideoBuffers = false;
167799c2a076b4a46762a22bbb4dfbd51d107e0532d9James Dong    mEncoderProfiles = MediaProfiles::getInstance();
167862db7db731c47a00ee1493e94f3e1d953c6e297aJames Dong    mRotationDegrees = 0;
167907b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    mLatitudex10000 = -3600000;
168007b1bb529a1ae76c46a71b01338c166f9490629dJames Dong    mLongitudex10000 = -3600000;
1681050b28a593350047845a45a14cc5026221ac1620James Dong
168230ab66297501757d745b9ae10da61adcd891f497Andreas Huber    mOutputFd = -1;
168330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
168430ab66297501757d745b9ae10da61adcd891f497Andreas Huber    return OK;
168530ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
168630ab66297501757d745b9ae10da61adcd891f497Andreas Huber
168730ab66297501757d745b9ae10da61adcd891f497Andreas Huberstatus_t StagefrightRecorder::getMaxAmplitude(int *max) {
16883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getMaxAmplitude");
1689d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
1690d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (max == NULL) {
169129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Null pointer argument");
1692d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return BAD_VALUE;
1693d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
1694d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong
1695d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    if (mAudioSourceNode != 0) {
1696d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong        *max = mAudioSourceNode->getMaxAmplitude();
1697d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    } else {
1698d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong        *max = 0;
1699d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    }
17002dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber
17012dce41ad26cb3e9e15c9e456a84bcf5309548ca0Andreas Huber    return OK;
170230ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
170330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
1704dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dongstatus_t StagefrightRecorder::dump(
1705dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong        int fd, const Vector<String16>& args) const {
17063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("dump");
1707b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    const size_t SIZE = 256;
1708b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    char buffer[SIZE];
1709b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    String8 result;
1710dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong    if (mWriter != 0) {
1711dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong        mWriter->dump(fd, args);
1712dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong    } else {
1713dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong        snprintf(buffer, SIZE, "   No file writer\n");
1714dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong        result.append(buffer);
1715dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong    }
1716dedf414d3fe2e79ee0aad0f1c82ca16ebd886ff6James Dong    snprintf(buffer, SIZE, "   Recorder: %p\n", this);
1717b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "   Output file (fd %d):\n", mOutputFd);
1718b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1719b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     File format: %d\n", mOutputFormat);
1720b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1721b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Max file size (bytes): %lld\n", mMaxFileSizeBytes);
1722b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1723b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Max file duration (us): %lld\n", mMaxFileDurationUs);
1724b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1725b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32);
1726b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1727b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Interleave duration (us): %d\n", mInterleaveDurationUs);
1728b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1729b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Progress notification: %lld us\n", mTrackEveryTimeDurationUs);
1730b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1731b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "   Audio\n");
1732b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1733b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Source: %d\n", mAudioSource);
1734b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1735b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Encoder: %d\n", mAudioEncoder);
1736b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1737b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mAudioBitRate);
1738b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1739b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Sampling rate (hz): %d\n", mSampleRate);
1740b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1741b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Number of channels: %d\n", mAudioChannels);
1742b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1743b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Max amplitude: %d\n", mAudioSourceNode == 0? 0: mAudioSourceNode->getMaxAmplitude());
1744b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1745b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "   Video\n");
1746b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1747b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Source: %d\n", mVideoSource);
1748b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1749b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Camera Id: %d\n", mCameraId);
1750b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
175186b7f47aa7482424cf8fd248f1315311919be3b0James Dong    snprintf(buffer, SIZE, "     Start time offset (ms): %d\n", mStartTimeOffsetMs);
175286b7f47aa7482424cf8fd248f1315311919be3b0James Dong    result.append(buffer);
1753b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Encoder: %d\n", mVideoEncoder);
1754b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1755b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Encoder profile: %d\n", mVideoEncoderProfile);
1756b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1757b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Encoder level: %d\n", mVideoEncoderLevel);
1758b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
17598f5f2fcee5c12d08df71d17017410c50951fc2e3James Dong    snprintf(buffer, SIZE, "     I frames interval (s): %d\n", mIFramesIntervalSec);
1760b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1761b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight);
1762b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1763b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Frame rate (fps): %d\n", mFrameRate);
1764b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1765b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mVideoBitRate);
1766b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    result.append(buffer);
1767b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    ::write(fd, result.string(), result.size());
1768b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong    return OK;
1769b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong}
177030ab66297501757d745b9ae10da61adcd891f497Andreas Huber}  // namespace android
1771