StagefrightRecorder.cpp revision b4a55269a5b39c73de2cc1d4013d0631ef18c77d
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2009 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "StagefrightRecorder"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h>
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "StagefrightRecorder.h"
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/IPCThreadState.h>
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/IServiceManager.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/IMediaPlayerService.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/openmax/OMX_Audio.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/AudioSource.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/AMRWriter.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/AACWriter.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/CameraSource.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/CameraSourceTimeLapse.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/MPEG2TSWriter.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MPEG4Writer.h>
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/stagefright/MediaDefs.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/stagefright/MetaData.h>
3897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <media/stagefright/OMXClient.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXCodec.h>
4097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <media/stagefright/SurfaceMediaSource.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/MediaProfiles.h>
42496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include <camera/ICamera.h>
43496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include <camera/CameraParameters.h>
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <gui/Surface.h>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Errors.h>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <sys/types.h>
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <ctype.h>
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <unistd.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <system/audio.h>
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "ARTPWriter.h"
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// To collect the encoder usage for the battery app
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void addBatteryData(uint32_t params) {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IBinder> binder =
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        defaultServiceManager()->getService(String16("media.player"));
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(service.get() != NULL);
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    service->addBatteryData(params);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68f933441648ef6a71dee783d733aac17b9508b452Andreas HuberStagefrightRecorder::StagefrightRecorder()
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : mWriter(NULL),
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mOutputFd(-1),
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mAudioSource(AUDIO_SOURCE_CNT),
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mVideoSource(VIDEO_SOURCE_LIST_END),
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mStarted(false), mSurfaceMediaSource(NULL) {
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("Constructor");
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reset();
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79f933441648ef6a71dee783d733aac17b9508b452Andreas HuberStagefrightRecorder::~StagefrightRecorder() {
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("Destructor");
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    stop();
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::init() {
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("init");
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// The client side of mediaserver asks it to creat a SurfaceMediaSource
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// and return a interface reference. The client side will use that
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// while encoding GL Frames
92f933441648ef6a71dee783d733aac17b9508b452Andreas Hubersp<ISurfaceTexture> StagefrightRecorder::querySurfaceMediaSource() const {
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("Get SurfaceMediaSource");
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mSurfaceMediaSource->getBufferQueue();
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setAudioSource(audio_source_t as) {
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setAudioSource: %d", as);
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (as < AUDIO_SOURCE_DEFAULT ||
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        as >= AUDIO_SOURCE_CNT) {
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid audio source: %d", as);
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (as == AUDIO_SOURCE_DEFAULT) {
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mAudioSource = AUDIO_SOURCE_MIC;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mAudioSource = as;
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setVideoSource(video_source vs) {
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setVideoSource: %d", vs);
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (vs < VIDEO_SOURCE_DEFAULT ||
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        vs >= VIDEO_SOURCE_LIST_END) {
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid video source: %d", vs);
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (vs == VIDEO_SOURCE_DEFAULT) {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mVideoSource = VIDEO_SOURCE_CAMERA;
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mVideoSource = vs;
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setOutputFormat(output_format of) {
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setOutputFormat: %d", of);
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (of < OUTPUT_FORMAT_DEFAULT ||
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        of >= OUTPUT_FORMAT_LIST_END) {
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid output format: %d", of);
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (of == OUTPUT_FORMAT_DEFAULT) {
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mOutputFormat = OUTPUT_FORMAT_THREE_GPP;
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mOutputFormat = of;
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setAudioEncoder(audio_encoder ae) {
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setAudioEncoder: %d", ae);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (ae < AUDIO_ENCODER_DEFAULT ||
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ae >= AUDIO_ENCODER_LIST_END) {
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid audio encoder: %d", ae);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (ae == AUDIO_ENCODER_DEFAULT) {
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mAudioEncoder = AUDIO_ENCODER_AMR_NB;
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mAudioEncoder = ae;
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setVideoEncoder(video_encoder ve) {
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setVideoEncoder: %d", ve);
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (ve < VIDEO_ENCODER_DEFAULT ||
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ve >= VIDEO_ENCODER_LIST_END) {
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid video encoder: %d", ve);
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (ve == VIDEO_ENCODER_DEFAULT) {
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mVideoEncoder = VIDEO_ENCODER_H263;
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    } else {
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mVideoEncoder = ve;
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    return OK;
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber}
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstatus_t StagefrightRecorder::setVideoSize(int width, int height) {
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    ALOGV("setVideoSize: %dx%d", width, height);
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (width <= 0 || height <= 0) {
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        ALOGE("Invalid video size: %dx%d", width, height);
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        return BAD_VALUE;
187ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Additional check on the dimension will be performed later
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mVideoWidth = width;
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mVideoHeight = height;
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) {
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setVideoFrameRate: %d", frames_per_second);
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if ((frames_per_second <= 0 && frames_per_second != -1) ||
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        frames_per_second > 120) {
200ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        ALOGE("Invalid video frame rate: %d", frames_per_second);
201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        return BAD_VALUE;
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Additional check on the frame rate will be performed later
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFrameRate = frames_per_second;
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return OK;
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t StagefrightRecorder::setCamera(const sp<ICamera> &camera,
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                                        const sp<ICameraRecordingProxy> &proxy) {
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("setCamera");
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (camera == 0) {
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        ALOGE("camera is NULL");
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return BAD_VALUE;
216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (proxy == 0) {
2187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("camera proxy is NULL");
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return BAD_VALUE;
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCamera = camera;
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCameraProxy = proxy;
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return OK;
225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setPreviewSurface(const sp<Surface> &surface) {
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setPreviewSurface: %p", surface.get());
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPreviewSurface = surface;
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setOutputFile(const char *path) {
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGE("setOutputFile(const char*) must not be called");
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // We don't actually support this at all, as the media_server process
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // no longer has permissions to create files.
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return -EPERM;
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) {
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setOutputFile: %d, %lld, %lld", fd, offset, length);
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // These don't make any sense, do they?
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(offset, 0ll);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(length, 0ll);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (fd < 0) {
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid file descriptor: %d", fd);
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EBADF;
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mOutputFd >= 0) {
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ::close(mOutputFd);
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputFd = dup(fd);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar// Attempt to parse an int64 literal optionally surrounded by whitespace,
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// returns true on success, false otherwise.
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic bool safe_strtoi64(const char *s, int64_t *val) {
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    char *end;
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // It is lame, but according to man page, we have to set errno to 0
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // before calling strtoll().
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    errno = 0;
269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    *val = strtoll(s, &end, 10);
270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (end == s || errno == ERANGE) {
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Skip trailing whitespace
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (isspace(*end)) {
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++end;
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // For a successful return, the string must contain nothing but a valid
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // int64 literal optionally surrounded by whitespace.
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return *end == '\0';
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// Return true if the value is in [0, 0x007FFFFFFF]
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic bool safe_strtoi32(const char *s, int32_t *val) {
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t temp;
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (safe_strtoi64(s, &temp)) {
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (temp >= 0 && temp <= 0x007FFFFFFF) {
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            *val = static_cast<int32_t>(temp);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return false;
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// Trim both leading and trailing whitespace from the given string.
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void TrimString(String8 *s) {
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t num_bytes = s->bytes();
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *data = s->string();
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t leading_space = 0;
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (leading_space < num_bytes && isspace(data[leading_space])) {
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++leading_space;
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i = num_bytes;
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (i > leading_space && isspace(data[i - 1])) {
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        --i;
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    s->setTo(String8(&data[leading_space], i - leading_space));
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamAudioSamplingRate(int32_t sampleRate) {
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("setParamAudioSamplingRate: %d", sampleRate);
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (sampleRate <= 0) {
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid audio sampling rate: %d", sampleRate);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Additional check on the sample rate will be performed later.
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mSampleRate = sampleRate;
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) {
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setParamAudioNumberOfChannels: %d", channels);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (channels <= 0 || channels >= 3) {
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid number of audio channels: %d", channels);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Additional check on the number of channels will be performed later.
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mAudioChannels = channels;
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamAudioEncodingBitRate(int32_t bitRate) {
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setParamAudioEncodingBitRate: %d", bitRate);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (bitRate <= 0) {
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid audio encoding bit rate: %d", bitRate);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // The target bit rate may not be exactly the same as the requested.
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // It depends on many factors, such as rate control, and the bit rate
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // range that a specific encoder supports. The mismatch between the
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // the target and requested bit rate will NOT be treated as an error.
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mAudioBitRate = bitRate;
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamVideoEncodingBitRate(int32_t bitRate) {
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setParamVideoEncodingBitRate: %d", bitRate);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (bitRate <= 0) {
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid video encoding bit rate: %d", bitRate);
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    // The target bit rate may not be exactly the same as the requested.
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    // It depends on many factors, such as rate control, and the bit rate
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // range that a specific encoder supports. The mismatch between the
365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    // the target and requested bit rate will NOT be treated as an error.
366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mVideoBitRate = bitRate;
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber    return OK;
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber}
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber// Always rotate clockwise, and only support 0, 90, 180 and 270 for now.
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t StagefrightRecorder::setParamVideoRotation(int32_t degrees) {
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("setParamVideoRotation: %d", degrees);
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (degrees < 0 || degrees % 90 != 0) {
374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        ALOGE("Unsupported video rotation angle: %d", degrees);
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        return BAD_VALUE;
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
377c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mRotationDegrees = degrees % 360;
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) {
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setParamMaxFileDurationUs: %lld us", timeUs);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // This is meant for backward compatibility for MediaRecorder.java
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (timeUs <= 0) {
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", timeUs);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        timeUs = 0; // Disable the duration limit for zero or negative values.
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (timeUs <= 100000LL) {  // XXX: 100 milli-seconds
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Max file duration is too short: %lld us", timeUs);
390dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        return BAD_VALUE;
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (timeUs <= 15 * 1000000LL) {
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGW("Target duration (%lld us) too short to be respected", timeUs);
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mMaxFileDurationUs = timeUs;
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setParamMaxFileSizeBytes: %lld bytes", bytes);
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // This is meant for backward compatibility for MediaRecorder.java
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (bytes <= 0) {
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGW("Max file size is not positive: %lld bytes. "
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             "Disabling file size limit.", bytes);
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bytes = 0; // Disable the file size limit for zero or negative values.
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    } else if (bytes <= 1024) {  // XXX: 1 kB
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        ALOGE("Max file size is too small: %lld bytes", bytes);
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        return BAD_VALUE;
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    if (bytes <= 100 * 1024) {
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGW("Target file size (%lld bytes) is too small to be respected", bytes);
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mMaxFileSizeBytes = bytes;
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamInterleaveDuration(int32_t durationUs) {
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("setParamInterleaveDuration: %d", durationUs);
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (durationUs <= 500000) {           //  500 ms
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // If interleave duration is too small, it is very inefficient to do
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // interleaving since the metadata overhead will count for a significant
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // portion of the saved contents
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("Audio/video interleave duration is too small: %d us", durationUs);
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        return BAD_VALUE;
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else if (durationUs >= 10000000) {  // 10 seconds
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // If interleaving duration is too large, it can cause the recording
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // session to use too much memory since we have to save the output
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // data before we write them out
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("Audio/video interleave duration is too large: %d us", durationUs);
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return BAD_VALUE;
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mInterleaveDurationUs = durationUs;
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4397a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// If seconds <  0, only the first frame is I frame, and rest are all P frames
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// If seconds == 0, all frames are encoded as I frames. No P frames
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// If seconds >  0, it is the time spacing (seconds) between 2 neighboring I frames
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamVideoIFramesInterval(int32_t seconds) {
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setParamVideoIFramesInterval: %d seconds", seconds);
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIFramesIntervalSec = seconds;
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t StagefrightRecorder::setParam64BitFileOffset(bool use64Bit) {
450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("setParam64BitFileOffset: %s",
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        use64Bit? "use 64 bit file offset": "use 32 bit file offset");
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUse64BitFileOffset = use64Bit;
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t StagefrightRecorder::setParamVideoCameraId(int32_t cameraId) {
4574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    ALOGV("setParamVideoCameraId: %d", cameraId);
4584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (cameraId < 0) {
4594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        return BAD_VALUE;
4604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCameraId = cameraId;
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    return OK;
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarstatus_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    ALOGV("setParamTrackTimeStatus: %lld", timeDurationUs);
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (timeDurationUs < 20000) {  // Infeasible if shorter than 20 ms?
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        ALOGE("Tracking time duration too short: %lld us", timeDurationUs);
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mTrackEveryTimeDurationUs = timeDurationUs;
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamVideoEncoderProfile(int32_t profile) {
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setParamVideoEncoderProfile: %d", profile);
477054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Additional check will be done later when we load the encoder.
479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // For now, we are accepting values defined in OpenMAX IL.
480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mVideoEncoderProfile = profile;
481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamVideoEncoderLevel(int32_t level) {
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("setParamVideoEncoderLevel: %d", level);
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Additional check will be done later when we load the encoder.
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // For now, we are accepting values defined in OpenMAX IL.
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mVideoEncoderLevel = level;
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamMovieTimeScale(int32_t timeScale) {
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("setParamMovieTimeScale: %d", timeScale);
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // The range is set to be the same as the audio's time scale range
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // since audio's time scale has a wider range.
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (timeScale < 600 || timeScale > 96000) {
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("Time scale (%d) for movie is out of range [600, 96000]", timeScale);
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return BAD_VALUE;
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mMovieTimeScale = timeScale;
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    return OK;
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huberstatus_t StagefrightRecorder::setParamVideoTimeScale(int32_t timeScale) {
507afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    ALOGV("setParamVideoTimeScale: %d", timeScale);
508afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    // 60000 is chosen to make sure that each video frame from a 60-fps
5101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    // video has 1000 ticks.
511308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (timeScale < 600 || timeScale > 60000) {
512308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        ALOGE("Time scale (%d) for video is out of range [600, 60000]", timeScale);
513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return BAD_VALUE;
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mVideoTimeScale = timeScale;
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    return OK;
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t StagefrightRecorder::setParamAudioTimeScale(int32_t timeScale) {
520308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    ALOGV("setParamAudioTimeScale: %d", timeScale);
521308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
522308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // 96000 Hz is the highest sampling rate support in AAC.
523308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (timeScale < 600 || timeScale > 96000) {
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        ALOGE("Time scale (%d) for audio is out of range [600, 96000]", timeScale);
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return BAD_VALUE;
526ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAudioTimeScale = timeScale;
528ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    return OK;
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t StagefrightRecorder::setParamTimeLapseEnable(int32_t timeLapseEnable) {
532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    ALOGV("setParamTimeLapseEnable: %d", timeLapseEnable);
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    if(timeLapseEnable == 0) {
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCaptureTimeLapse = false;
5361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    } else if (timeLapseEnable == 1) {
5371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        mCaptureTimeLapse = true;
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs) {
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("setParamTimeBetweenTimeLapseFrameCapture: %lld us", timeUs);
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Not allowing time more than a day
548eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    if (timeUs <= 0 || timeUs > 86400*1E6) {
549eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        ALOGE("Time between time lapse frame capture (%lld) is out of range [0, 1 Day]", timeUs);
550eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        return BAD_VALUE;
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
552eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mTimeBetweenTimeLapseFrameCaptureUs = timeUs;
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return OK;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huberstatus_t StagefrightRecorder::setParamGeoDataLongitude(
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t longitudex10000) {
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
563054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mLongitudex10000 = longitudex10000;
564054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
565054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParamGeoDataLatitude(
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t latitudex10000) {
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (latitudex10000 > 900000 || latitudex10000 < -900000) {
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLatitudex10000 = latitudex10000;
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setParameter(
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const String8 &key, const String8 &value) {
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (key == "max-duration") {
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t max_duration_ms;
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (safe_strtoi64(value.string(), &max_duration_ms)) {
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return setParamMaxFileDurationUs(1000LL * max_duration_ms);
58429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        }
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (key == "max-filesize") {
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t max_filesize_bytes;
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (safe_strtoi64(value.string(), &max_filesize_bytes)) {
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return setParamMaxFileSizeBytes(max_filesize_bytes);
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5903c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    } else if (key == "interleave-duration-us") {
5913c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        int32_t durationUs;
5923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        if (safe_strtoi32(value.string(), &durationUs)) {
5935ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            return setParamInterleaveDuration(durationUs);
5943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        }
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    } else if (key == "param-movie-time-scale") {
5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        int32_t timeScale;
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        if (safe_strtoi32(value.string(), &timeScale)) {
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return setParamMovieTimeScale(timeScale);
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else if (key == "param-use-64bit-offset") {
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int32_t use64BitOffset;
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (safe_strtoi32(value.string(), &use64BitOffset)) {
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return setParam64BitFileOffset(use64BitOffset != 0);
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else if (key == "param-geotag-longitude") {
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int64_t longitudex10000;
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (safe_strtoi64(value.string(), &longitudex10000)) {
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return setParamGeoDataLongitude(longitudex10000);
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else if (key == "param-geotag-latitude") {
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int64_t latitudex10000;
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (safe_strtoi64(value.string(), &latitudex10000)) {
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return setParamGeoDataLatitude(latitudex10000);
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else if (key == "param-track-time-status") {
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int64_t timeDurationUs;
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (safe_strtoi64(value.string(), &timeDurationUs)) {
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return setParamTrackTimeStatus(timeDurationUs);
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else if (key == "audio-param-sampling-rate") {
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t sampling_rate;
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (safe_strtoi32(value.string(), &sampling_rate)) {
6233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            return setParamAudioSamplingRate(sampling_rate);
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (key == "audio-param-number-of-channels") {
62629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        int32_t number_of_channels;
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (safe_strtoi32(value.string(), &number_of_channels)) {
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return setParamAudioNumberOfChannels(number_of_channels);
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    } else if (key == "audio-param-encoding-bitrate") {
631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        int32_t audio_bitrate;
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (safe_strtoi32(value.string(), &audio_bitrate)) {
633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            return setParamAudioEncodingBitRate(audio_bitrate);
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    } else if (key == "audio-param-time-scale") {
63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        int32_t timeScale;
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (safe_strtoi32(value.string(), &timeScale)) {
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return setParamAudioTimeScale(timeScale);
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    } else if (key == "video-param-encoding-bitrate") {
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        int32_t video_bitrate;
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (safe_strtoi32(value.string(), &video_bitrate)) {
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return setParamVideoEncodingBitRate(video_bitrate);
644054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
645054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    } else if (key == "video-param-rotation-angle-degrees") {
646258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        int32_t degrees;
647258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (safe_strtoi32(value.string(), &degrees)) {
648258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return setParamVideoRotation(degrees);
649258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
650258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    } else if (key == "video-param-i-frames-interval") {
65129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        int32_t seconds;
652258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (safe_strtoi32(value.string(), &seconds)) {
653258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return setParamVideoIFramesInterval(seconds);
654258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
655258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    } else if (key == "video-param-encoder-profile") {
656258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        int32_t profile;
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (safe_strtoi32(value.string(), &profile)) {
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return setParamVideoEncoderProfile(profile);
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (key == "video-param-encoder-level") {
66129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        int32_t level;
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (safe_strtoi32(value.string(), &level)) {
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return setParamVideoEncoderLevel(level);
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (key == "video-param-camera-id") {
666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        int32_t cameraId;
667054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (safe_strtoi32(value.string(), &cameraId)) {
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            return setParamVideoCameraId(cameraId);
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
670054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    } else if (key == "video-param-time-scale") {
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        int32_t timeScale;
672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (safe_strtoi32(value.string(), &timeScale)) {
673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            return setParamVideoTimeScale(timeScale);
674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    } else if (key == "time-lapse-enable") {
676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        int32_t timeLapseEnable;
677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (safe_strtoi32(value.string(), &timeLapseEnable)) {
6783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            return setParamTimeLapseEnable(timeLapseEnable);
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    } else if (key == "time-between-time-lapse-frame-capture") {
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeBetweenTimeLapseFrameCaptureMs;
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (safe_strtoi64(value.string(), &timeBetweenTimeLapseFrameCaptureMs)) {
683054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            return setParamTimeBetweenTimeLapseFrameCapture(
6848ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev                    1000LL * timeBetweenTimeLapseFrameCaptureMs);
6851e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        }
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setParameter: failed to find key %s", key.string());
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return BAD_VALUE;
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69274006804065941841883c4b46ee785070164023fJamie Gennisstatus_t StagefrightRecorder::setParameters(const String8 &params) {
69374006804065941841883c4b46ee785070164023fJamie Gennis    ALOGV("setParameters: %s", params.string());
694054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    const char *cparams = params.string();
69574006804065941841883c4b46ee785070164023fJamie Gennis    const char *key_start = cparams;
69674006804065941841883c4b46ee785070164023fJamie Gennis    for (;;) {
69774006804065941841883c4b46ee785070164023fJamie Gennis        const char *equal_pos = strchr(key_start, '=');
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (equal_pos == NULL) {
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("Parameters %s miss a value", cparams);
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BAD_VALUE;
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
70229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        String8 key(key_start, equal_pos - key_start);
70374006804065941841883c4b46ee785070164023fJamie Gennis        TrimString(&key);
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (key.length() == 0) {
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("Parameters %s contains an empty key", cparams);
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BAD_VALUE;
70774006804065941841883c4b46ee785070164023fJamie Gennis        }
70874006804065941841883c4b46ee785070164023fJamie Gennis        const char *value_start = equal_pos + 1;
7093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        const char *semicolon_pos = strchr(value_start, ';');
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        String8 value;
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (semicolon_pos == NULL) {
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            value.setTo(value_start);
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            value.setTo(value_start, semicolon_pos - value_start);
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (setParameter(key, value) != OK) {
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BAD_VALUE;
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (semicolon_pos == NULL) {
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;  // Reaches the end
72174006804065941841883c4b46ee785070164023fJamie Gennis        }
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        key_start = semicolon_pos + 1;
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setListener(const sp<IMediaRecorderClient> &listener) {
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mListener = listener;
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::prepare() {
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t StagefrightRecorder::start() {
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_GE(mOutputFd, 0);
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mWriter != NULL) {
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGE("File writer is not avaialble");
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return UNKNOWN_ERROR;
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t status = OK;
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    switch (mOutputFormat) {
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_DEFAULT:
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_THREE_GPP:
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_MPEG_4:
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            status = startMPEG4Recording();
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            break;
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_AMR_NB:
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_AMR_WB:
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            status = startAMRRecording();
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            break;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_AAC_ADIF:
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_AAC_ADTS:
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            status = startAACRecording();
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            break;
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_RTP_AVP:
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            status = startRTPRecording();
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            break;
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        case OUTPUT_FORMAT_MPEG2TS:
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            status = startMPEG2TSRecording();
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            break;
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        default:
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("Unsupported output file format: %d", mOutputFormat);
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            status = UNKNOWN_ERROR;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            break;
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if ((status == OK) && (!mStarted)) {
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mStarted = true;
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted;
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mAudioSource != AUDIO_SOURCE_CNT) {
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            params |= IMediaPlayerService::kBatteryDataTrackAudio;
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mVideoSource != VIDEO_SOURCE_LIST_END) {
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            params |= IMediaPlayerService::kBatteryDataTrackVideo;
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        addBatteryData(params);
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return status;
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
795f933441648ef6a71dee783d733aac17b9508b452Andreas Hubersp<MediaSource> StagefrightRecorder::createAudioSource() {
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AudioSource> audioSource =
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new AudioSource(
7983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                mAudioSource,
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mSampleRate,
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mAudioChannels);
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8021e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    status_t err = audioSource->initCheck();
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("audio source is not initialized");
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return NULL;
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<MetaData> encMeta = new MetaData;
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *mime;
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mAudioEncoder) {
8128ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        case AUDIO_ENCODER_AMR_NB:
8131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        case AUDIO_ENCODER_DEFAULT:
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mime = MEDIA_MIMETYPE_AUDIO_AMR_NB;
8151e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            break;
81629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        case AUDIO_ENCODER_AMR_WB:
817c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            mime = MEDIA_MIMETYPE_AUDIO_AMR_WB;
818c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case AUDIO_ENCODER_AAC:
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mime = MEDIA_MIMETYPE_AUDIO_AAC;
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectLC);
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case AUDIO_ENCODER_HE_AAC:
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mime = MEDIA_MIMETYPE_AUDIO_AAC;
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectHE);
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            break;
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case AUDIO_ENCODER_AAC_ELD:
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mime = MEDIA_MIMETYPE_AUDIO_AAC;
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            encMeta->setInt32(kKeyAACProfile, OMX_AUDIO_AACObjectELD);
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("Unknown audio encoder: %d", mAudioEncoder);
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            return NULL;
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    encMeta->setCString(kKeyMIMEType, mime);
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t maxInputSize;
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(audioSource->getFormat()->findInt32(
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                kKeyMaxInputSize, &maxInputSize));
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    encMeta->setInt32(kKeyMaxInputSize, maxInputSize);
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    encMeta->setInt32(kKeyChannelCount, mAudioChannels);
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    encMeta->setInt32(kKeySampleRate, mSampleRate);
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    encMeta->setInt32(kKeyBitRate, mAudioBitRate);
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mAudioTimeScale > 0) {
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        encMeta->setInt32(kKeyTimeScale, mAudioTimeScale);
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMXClient client;
851d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    CHECK_EQ(client.connect(), (status_t)OK);
852d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    sp<MediaSource> audioEncoder =
853d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        OMXCodec::Create(client.interface(), encMeta,
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                         true /* createEncoder */, audioSource);
855d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    mAudioSourceNode = audioSource;
856d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
857d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    return audioEncoder;
858d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar}
859d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
860d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnarstatus_t StagefrightRecorder::startAACRecording() {
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // FIXME:
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Add support for OUTPUT_FORMAT_AAC_ADIF
863d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_AAC_ADTS);
864d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mAudioEncoder == AUDIO_ENCODER_AAC ||
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mAudioEncoder == AUDIO_ENCODER_HE_AAC ||
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          mAudioEncoder == AUDIO_ENCODER_AAC_ELD);
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mAudioSource != AUDIO_SOURCE_CNT);
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mWriter = new AACWriter(mOutputFd);
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t status = startRawAudioRecording();
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (status != OK) {
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mWriter.clear();
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mWriter = NULL;
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return status;
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::startAMRRecording() {
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mOutputFormat == OUTPUT_FORMAT_AMR_NB ||
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          mOutputFormat == OUTPUT_FORMAT_AMR_WB);
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
884349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mOutputFormat == OUTPUT_FORMAT_AMR_NB) {
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mAudioEncoder != AUDIO_ENCODER_DEFAULT &&
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioEncoder != AUDIO_ENCODER_AMR_NB) {
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("Invalid encoder %d used for AMRNB recording",
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioEncoder);
8892ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            return BAD_VALUE;
8902ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        }
8912ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar    } else {  // mOutputFormat must be OUTPUT_FORMAT_AMR_WB
8922ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (mAudioEncoder != AUDIO_ENCODER_AMR_WB) {
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("Invlaid encoder %d used for AMRWB recording",
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mAudioEncoder);
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BAD_VALUE;
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mWriter = new AMRWriter(mOutputFd);
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t status = startRawAudioRecording();
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (status != OK) {
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mWriter.clear();
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mWriter = NULL;
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return status;
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::startRawAudioRecording() {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mAudioSource >= AUDIO_SOURCE_CNT) {
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Invalid audio source: %d", mAudioSource);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t status = BAD_VALUE;
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (OK != (status = checkAudioEncoderCapabilities())) {
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return status;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<MediaSource> audioEncoder = createAudioSource();
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (audioEncoder == NULL) {
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mWriter != 0);
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mWriter->addSource(audioEncoder);
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mMaxFileDurationUs != 0) {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mWriter->setMaxFileDuration(mMaxFileDurationUs);
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mMaxFileSizeBytes != 0) {
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mWriter->setMaxFileSize(mMaxFileSizeBytes);
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mWriter->setListener(mListener);
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mWriter->start();
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::startRTPRecording() {
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_RTP_AVP);
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if ((mAudioSource != AUDIO_SOURCE_CNT
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && mVideoSource != VIDEO_SOURCE_LIST_END)
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || (mAudioSource == AUDIO_SOURCE_CNT
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && mVideoSource == VIDEO_SOURCE_LIST_END)) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Must have exactly one source.
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9502944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber    if (mOutputFd < 0) {
9512944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        return BAD_VALUE;
9522944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber    }
9532944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<MediaSource> source;
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mAudioSource != AUDIO_SOURCE_CNT) {
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        source = createAudioSource();
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
960729de186450f78c099637e1fce743fe531862c52Andreas Huber        sp<MediaSource> mediaSource;
961729de186450f78c099637e1fce743fe531862c52Andreas Huber        status_t err = setupMediaSource(&mediaSource);
962c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        if (err != OK) {
963c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            return err;
964c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        }
965c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = setupVideoEncoder(mediaSource, mVideoBitRate, &source);
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
97294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    mWriter = new ARTPWriter(mOutputFd);
97394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    mWriter->addSource(source);
97494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    mWriter->setListener(mListener);
97594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang
976ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    return mWriter->start();
977ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber}
9782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
9792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t StagefrightRecorder::startMPEG2TSRecording() {
980ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_MPEG2TS);
981ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen
982774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu    sp<MediaWriter> writer = new MPEG2TSWriter(mOutputFd);
983774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu
98497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (mAudioSource != AUDIO_SOURCE_CNT) {
98597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (mAudioEncoder != AUDIO_ENCODER_AAC &&
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioEncoder != AUDIO_ENCODER_HE_AAC &&
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mAudioEncoder != AUDIO_ENCODER_AAC_ELD) {
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return ERROR_UNSUPPORTED;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = setupAudioEncoder(writer);
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mVideoSource < VIDEO_SOURCE_LIST_END) {
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mVideoEncoder != VIDEO_ENCODER_H264) {
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return ERROR_UNSUPPORTED;
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<MediaSource> mediaSource;
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = setupMediaSource(&mediaSource);
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<MediaSource> encoder;
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = setupVideoEncoder(mediaSource, mVideoBitRate, &encoder);
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        writer->addSource(encoder);
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mMaxFileDurationUs != 0) {
10205ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        writer->setMaxFileDuration(mMaxFileDurationUs);
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mMaxFileSizeBytes != 0) {
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        writer->setMaxFileSize(mMaxFileSizeBytes);
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mWriter = writer;
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mWriter->start();
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10325778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid StagefrightRecorder::clipVideoFrameRate() {
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("clipVideoFrameRate: encoder %d", mVideoEncoder);
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName(
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "enc.vid.fps.min", mVideoEncoder);
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName(
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "enc.vid.fps.max", mVideoEncoder);
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFrameRate < minFrameRate && minFrameRate != -1) {
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGW("Intended video encoding frame rate (%d fps) is too small"
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber             " and will be set to (%d fps)", mFrameRate, minFrameRate);
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFrameRate = minFrameRate;
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFrameRate > maxFrameRate && maxFrameRate != -1) {
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGW("Intended video encoding frame rate (%d fps) is too large"
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber             " and will be set to (%d fps)", mFrameRate, maxFrameRate);
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFrameRate = maxFrameRate;
10462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
10472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
10482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
10495778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid StagefrightRecorder::clipVideoBitRate() {
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("clipVideoBitRate: encoder %d", mVideoEncoder);
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int minBitRate = mEncoderProfiles->getVideoEncoderParamByName(
1052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        "enc.vid.bps.min", mVideoEncoder);
1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int maxBitRate = mEncoderProfiles->getVideoEncoderParamByName(
1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        "enc.vid.bps.max", mVideoEncoder);
1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mVideoBitRate < minBitRate && minBitRate != -1) {
1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGW("Intended video encoding bit rate (%d bps) is too small"
1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber             " and will be set to (%d bps)", mVideoBitRate, minBitRate);
1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mVideoBitRate = minBitRate;
1059308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    } else if (mVideoBitRate > maxBitRate && maxBitRate != -1) {
1060308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        ALOGW("Intended video encoding bit rate (%d bps) is too large"
1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber             " and will be set to (%d bps)", mVideoBitRate, maxBitRate);
1062308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        mVideoBitRate = maxBitRate;
1063308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1064308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang}
1065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1066308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid StagefrightRecorder::clipVideoFrameWidth() {
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    ALOGV("clipVideoFrameWidth: encoder %d", mVideoEncoder);
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    int minFrameWidth = mEncoderProfiles->getVideoEncoderParamByName(
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                        "enc.vid.width.min", mVideoEncoder);
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    int maxFrameWidth = mEncoderProfiles->getVideoEncoderParamByName(
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                        "enc.vid.width.max", mVideoEncoder);
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (mVideoWidth < minFrameWidth && minFrameWidth != -1) {
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        ALOGW("Intended video encoding frame width (%d) is too small"
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber             " and will be set to (%d)", mVideoWidth, minFrameWidth);
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        mVideoWidth = minFrameWidth;
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    } else if (mVideoWidth > maxFrameWidth && maxFrameWidth != -1) {
10773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        ALOGW("Intended video encoding frame width (%d) is too large"
10783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber             " and will be set to (%d)", mVideoWidth, maxFrameWidth);
10793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        mVideoWidth = maxFrameWidth;
10803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber}
10823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huberstatus_t StagefrightRecorder::checkVideoEncoderCapabilities() {
10843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (!mCaptureTimeLapse) {
10853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        // Dont clip for time lapse capture as encoder will have enough
10863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        // time to encode because of slow capture rate of time lapse.
10873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        clipVideoBitRate();
10883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        clipVideoFrameRate();
10893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        clipVideoFrameWidth();
10903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        clipVideoFrameHeight();
10913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        setDefaultProfileIfNecessary();
10923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    return OK;
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang}
1095308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1096308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang// Set to use AVC baseline profile if the encoding parameters matches
1097308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang// CAMCORDER_QUALITY_LOW profile; this is for the sake of MMS service.
1098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid StagefrightRecorder::setDefaultProfileIfNecessary() {
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    ALOGV("setDefaultProfileIfNecessary");
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    camcorder_quality quality = CAMCORDER_QUALITY_LOW;
1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int64_t durationUs   = mEncoderProfiles->getCamcorderProfileParamByName(
1104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                                "duration", mCameraId, quality) * 1000000LL;
1105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int fileFormat       = mEncoderProfiles->getCamcorderProfileParamByName(
1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                                "file.format", mCameraId, quality);
1108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int videoCodec       = mEncoderProfiles->getCamcorderProfileParamByName(
1110308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                                "vid.codec", mCameraId, quality);
1111a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1112a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    int videoBitRate     = mEncoderProfiles->getCamcorderProfileParamByName(
1113a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                                "vid.bps", mCameraId, quality);
1114a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1115a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    int videoFrameRate   = mEncoderProfiles->getCamcorderProfileParamByName(
1116a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                                "vid.fps", mCameraId, quality);
1117308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1118308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int videoFrameWidth  = mEncoderProfiles->getCamcorderProfileParamByName(
1119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                "vid.width", mCameraId, quality);
1120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int videoFrameHeight = mEncoderProfiles->getCamcorderProfileParamByName(
1122054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                "vid.height", mCameraId, quality);
1123054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1124054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int audioCodec       = mEncoderProfiles->getCamcorderProfileParamByName(
1125054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                "aud.codec", mCameraId, quality);
1126054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1127054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int audioBitRate     = mEncoderProfiles->getCamcorderProfileParamByName(
1128054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                "aud.bps", mCameraId, quality);
1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    int audioSampleRate  = mEncoderProfiles->getCamcorderProfileParamByName(
1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                                "aud.hz", mCameraId, quality);
1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    int audioChannels    = mEncoderProfiles->getCamcorderProfileParamByName(
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                                "aud.ch", mCameraId, quality);
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    if (durationUs == mMaxFileDurationUs &&
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        fileFormat == mOutputFormat &&
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        videoCodec == mVideoEncoder &&
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        videoBitRate == mVideoBitRate &&
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        videoFrameRate == mFrameRate &&
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        videoFrameWidth == mVideoWidth &&
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        videoFrameHeight == mVideoHeight &&
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        audioCodec == mAudioEncoder &&
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        audioBitRate == mAudioBitRate &&
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        audioSampleRate == mSampleRate &&
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        audioChannels == mAudioChannels) {
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        if (videoCodec == VIDEO_ENCODER_H264) {
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            ALOGI("Force to use AVC baseline profile");
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            setParamVideoEncoderProfile(OMX_VIDEO_AVCProfileBaseline);
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        }
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    }
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar}
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnarstatus_t StagefrightRecorder::checkAudioEncoderCapabilities() {
1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    clipAudioBitRate();
1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    clipAudioSampleRate();
1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    clipNumberOfAudioChannels();
1158fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    return OK;
1159fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar}
1160fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1161fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnarvoid StagefrightRecorder::clipAudioBitRate() {
1162fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    ALOGV("clipAudioBitRate: encoder %d", mAudioEncoder);
1163fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1164fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    int minAudioBitRate =
1165fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            mEncoderProfiles->getAudioEncoderParamByName(
1166fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                "enc.aud.bps.min", mAudioEncoder);
1167fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar    if (minAudioBitRate != -1 && mAudioBitRate < minAudioBitRate) {
1168fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar        ALOGW("Intended audio encoding bit rate (%d) is too small"
1169fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            " and will be set to (%d)", mAudioBitRate, minAudioBitRate);
1170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mAudioBitRate = minAudioBitRate;
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1173054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int maxAudioBitRate =
1174054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mEncoderProfiles->getAudioEncoderParamByName(
11750167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                "enc.aud.bps.max", mAudioEncoder);
11760167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber    if (maxAudioBitRate != -1 && mAudioBitRate > maxAudioBitRate) {
11770167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        ALOGW("Intended audio encoding bit rate (%d) is too large"
11780167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            " and will be set to (%d)", mAudioBitRate, maxAudioBitRate);
11790167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mAudioBitRate = maxAudioBitRate;
11800167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber    }
1181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1183308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhangvoid StagefrightRecorder::clipAudioSampleRate() {
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("clipAudioSampleRate: encoder %d", mAudioEncoder);
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int minSampleRate =
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mEncoderProfiles->getAudioEncoderParamByName(
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                "enc.aud.hz.min", mAudioEncoder);
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minSampleRate != -1 && mSampleRate < minSampleRate) {
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGW("Intended audio sample rate (%d) is too small"
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            " and will be set to (%d)", mSampleRate, minSampleRate);
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSampleRate = minSampleRate;
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
119542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    int maxSampleRate =
119642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            mEncoderProfiles->getAudioEncoderParamByName(
119742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                "enc.aud.hz.max", mAudioEncoder);
119842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    if (maxSampleRate != -1 && mSampleRate > maxSampleRate) {
119942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        ALOGW("Intended audio sample rate (%d) is too large"
120042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            " and will be set to (%d)", mSampleRate, maxSampleRate);
120142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        mSampleRate = maxSampleRate;
120242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    }
120342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber}
120442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber
120542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Hubervoid StagefrightRecorder::clipNumberOfAudioChannels() {
120642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    ALOGV("clipNumberOfAudioChannels: encoder %d", mAudioEncoder);
120742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int minChannels =
1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mEncoderProfiles->getAudioEncoderParamByName(
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                "enc.aud.ch.min", mAudioEncoder);
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (minChannels != -1 && mAudioChannels < minChannels) {
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGW("Intended number of audio channels (%d) is too small"
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            " and will be set to (%d)", mAudioChannels, minChannels);
1214aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        mAudioChannels = minChannels;
1215ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1216ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1217ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    int maxChannels =
1218aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mEncoderProfiles->getAudioEncoderParamByName(
1219aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                "enc.aud.ch.max", mAudioEncoder);
1220aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (maxChannels != -1 && mAudioChannels > maxChannels) {
1221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        ALOGW("Intended number of audio channels (%d) is too large"
1222ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            " and will be set to (%d)", mAudioChannels, maxChannels);
12234471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        mAudioChannels = maxChannels;
12244471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1226729de186450f78c099637e1fce743fe531862c52Andreas Huber
12275778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid StagefrightRecorder::clipVideoFrameHeight() {
1228729de186450f78c099637e1fce743fe531862c52Andreas Huber    ALOGV("clipVideoFrameHeight: encoder %d", mVideoEncoder);
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int minFrameHeight = mEncoderProfiles->getVideoEncoderParamByName(
1230729de186450f78c099637e1fce743fe531862c52Andreas Huber                        "enc.vid.height.min", mVideoEncoder);
1231729de186450f78c099637e1fce743fe531862c52Andreas Huber    int maxFrameHeight = mEncoderProfiles->getVideoEncoderParamByName(
1232729de186450f78c099637e1fce743fe531862c52Andreas Huber                        "enc.vid.height.max", mVideoEncoder);
1233729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (minFrameHeight != -1 && mVideoHeight < minFrameHeight) {
1234729de186450f78c099637e1fce743fe531862c52Andreas Huber        ALOGW("Intended video encoding frame height (%d) is too small"
1235729de186450f78c099637e1fce743fe531862c52Andreas Huber             " and will be set to (%d)", mVideoHeight, minFrameHeight);
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mVideoHeight = minFrameHeight;
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (maxFrameHeight != -1 && mVideoHeight > maxFrameHeight) {
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGW("Intended video encoding frame height (%d) is too large"
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber             " and will be set to (%d)", mVideoHeight, maxFrameHeight);
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mVideoHeight = maxFrameHeight;
12412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
12422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
12432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi// Set up the appropriate MediaSource depending on the chosen option
12452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t StagefrightRecorder::setupMediaSource(
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                      sp<MediaSource> *mediaSource) {
12472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (mVideoSource == VIDEO_SOURCE_DEFAULT
12482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            || mVideoSource == VIDEO_SOURCE_CAMERA) {
12492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        sp<CameraSource> cameraSource;
1250516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        status_t err = setupCameraSource(&cameraSource);
1251516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (err != OK) {
12522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
12532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1254516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        *mediaSource = cameraSource;
1255516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber    } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
1256516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        // If using GRAlloc buffers, setup surfacemediasource.
12572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // Later a handle to that will be passed
12582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // to the client side when queried
1259516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        status_t err = setupSurfaceMediaSource();
1260516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (err != OK) {
1261516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            return err;
12622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
12632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        *mediaSource = mSurfaceMediaSource;
12642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else {
1265516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        return INVALID_OPERATION;
1266516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber    }
12672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return OK;
1268ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber}
1269ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber
1270ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber// setupSurfaceMediaSource creates a source with the given
1271ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber// width and height and framerate.
1272ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber// TODO: This could go in a static function inside SurfaceMediaSource
1273ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber// similar to that in CameraSource
1274ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huberstatus_t StagefrightRecorder::setupSurfaceMediaSource() {
1275ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    status_t err = OK;
1276ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    mSurfaceMediaSource = new SurfaceMediaSource(mVideoWidth, mVideoHeight);
127797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (mSurfaceMediaSource == NULL) {
127897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return NO_INIT;
127997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
128097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
128197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (mFrameRate == -1) {
128297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t frameRate = 0;
128397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        CHECK (mSurfaceMediaSource->getFormat()->findInt32(
128497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                                        kKeyFrameRate, &frameRate));
128597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGI("Frame rate is not explicitly set. Use the current frame "
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber             "rate (%d fps)", frameRate);
1287729de186450f78c099637e1fce743fe531862c52Andreas Huber        mFrameRate = frameRate;
12884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    } else {
12894471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        err = mSurfaceMediaSource->setFrameRate(mFrameRate);
12904471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12914471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    CHECK(mFrameRate != -1);
12928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    mIsMetaDataStoredInVideoBuffers =
12948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mSurfaceMediaSource->isMetaDataStoredInVideoBuffers();
12959806555d3930be43e11106281dee354820ac1c88Andreas Huber    return err;
12968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen}
12978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissenstatus_t StagefrightRecorder::setupCameraSource(
12998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        sp<CameraSource> *cameraSource) {
13009806555d3930be43e11106281dee354820ac1c88Andreas Huber    status_t err = OK;
13019806555d3930be43e11106281dee354820ac1c88Andreas Huber    if ((err = checkVideoEncoderCapabilities()) != OK) {
13029806555d3930be43e11106281dee354820ac1c88Andreas Huber        return err;
13039806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13049806555d3930be43e11106281dee354820ac1c88Andreas Huber    Size videoSize;
13059806555d3930be43e11106281dee354820ac1c88Andreas Huber    videoSize.width = mVideoWidth;
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    videoSize.height = mVideoHeight;
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCaptureTimeLapse) {
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mTimeBetweenTimeLapseFrameCaptureUs < 0) {
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %lld",
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mTimeBetweenTimeLapseFrameCaptureUs);
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BAD_VALUE;
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCamera, mCameraProxy, mCameraId,
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                videoSize, mFrameRate, mPreviewSurface,
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mTimeBetweenTimeLapseFrameCaptureUs);
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *cameraSource = mCameraSourceTimeLapse;
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *cameraSource = CameraSource::CreateFromCamera(
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCamera, mCameraProxy, mCameraId, videoSize, mFrameRate,
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mPreviewSurface, true /*storeMetaDataInVideoBuffers*/);
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCamera.clear();
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCameraProxy.clear();
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (*cameraSource == NULL) {
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if ((*cameraSource)->initCheck() != OK) {
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        (*cameraSource).clear();
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *cameraSource = NULL;
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return NO_INIT;
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // When frame rate is not set, the actual frame rate will be set to
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // the current frame rate being used.
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFrameRate == -1) {
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t frameRate = 0;
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK ((*cameraSource)->getFormat()->findInt32(
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    kKeyFrameRate, &frameRate));
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGI("Frame rate is not explicitly set. Use the current frame "
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             "rate (%d fps)", frameRate);
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mFrameRate = frameRate;
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mFrameRate != -1);
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIsMetaDataStoredInVideoBuffers =
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        (*cameraSource)->isMetaDataStoredInVideoBuffers();
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setupVideoEncoder(
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<MediaSource> cameraSource,
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t videoBitRate,
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<MediaSource> *source) {
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    source->clear();
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MetaData> enc_meta = new MetaData;
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    enc_meta->setInt32(kKeyBitRate, videoBitRate);
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    enc_meta->setInt32(kKeyFrameRate, mFrameRate);
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (mVideoEncoder) {
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case VIDEO_ENCODER_H263:
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case VIDEO_ENCODER_MPEG_4_SP:
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case VIDEO_ENCODER_H264:
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(!"Should not be here, unsupported video encoding.");
1380aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            break;
1381aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
1382ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1383ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    sp<MetaData> meta = cameraSource->getFormat();
1384ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1385ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    int32_t width, height, stride, sliceHeight, colorFormat;
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(meta->findInt32(kKeyWidth, &width));
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(meta->findInt32(kKeyHeight, &height));
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(meta->findInt32(kKeyStride, &stride));
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &colorFormat));
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    enc_meta->setInt32(kKeyWidth, width);
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    enc_meta->setInt32(kKeyHeight, height);
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    enc_meta->setInt32(kKeyIFramesInterval, mIFramesIntervalSec);
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    enc_meta->setInt32(kKeyStride, stride);
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    enc_meta->setInt32(kKeySliceHeight, sliceHeight);
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    enc_meta->setInt32(kKeyColorFormat, colorFormat);
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mVideoTimeScale > 0) {
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        enc_meta->setInt32(kKeyTimeScale, mVideoTimeScale);
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mVideoEncoderProfile != -1) {
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        enc_meta->setInt32(kKeyVideoProfile, mVideoEncoderProfile);
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mVideoEncoderLevel != -1) {
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel);
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMXClient client;
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t encoder_flags = 0;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mIsMetaDataStoredInVideoBuffers) {
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder_flags |= OMXCodec::kStoreMetaDataInVideoBuffers;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Do not wait for all the input buffers to become available.
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // This give timelapse video recording faster response in
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // receiving output from video encoder component.
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mCaptureTimeLapse) {
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder_flags |= OMXCodec::kOnlySubmitOneInputBufferAtOneTime;
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaSource> encoder = OMXCodec::Create(
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            client.interface(), enc_meta,
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            true /* createEncoder */, cameraSource,
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            NULL, encoder_flags);
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder == NULL) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGW("Failed to create the encoder");
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // When the encoder fails to be created, we need
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // release the camera source due to the camera's lock
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // and unlock mechanism.
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        cameraSource->stop();
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return UNKNOWN_ERROR;
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *source = encoder;
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::setupAudioEncoder(const sp<MediaWriter>& writer) {
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t status = BAD_VALUE;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (OK != (status = checkAudioEncoderCapabilities())) {
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return status;
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1446aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch(mAudioEncoder) {
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case AUDIO_ENCODER_AMR_NB:
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case AUDIO_ENCODER_AMR_WB:
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case AUDIO_ENCODER_AAC:
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case AUDIO_ENCODER_HE_AAC:
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case AUDIO_ENCODER_AAC_ELD:
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unsupported audio encoder: %d", mAudioEncoder);
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return UNKNOWN_ERROR;
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<MediaSource> audioEncoder = createAudioSource();
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (audioEncoder == NULL) {
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    writer->addSource(audioEncoder);
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::setupMPEG4Recording(
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int outputFd,
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t videoWidth, int32_t videoHeight,
1472ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        int32_t videoBitRate,
1473ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        int32_t *totalBitRate,
1474ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        sp<MediaWriter> *mediaWriter) {
1475ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mediaWriter->clear();
1476ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    *totalBitRate = 0;
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = OK;
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaWriter> writer = new MPEG4Writer(outputFd);
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mVideoSource < VIDEO_SOURCE_LIST_END) {
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        sp<MediaSource> mediaSource;
148397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        err = setupMediaSource(&mediaSource);
148497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (err != OK) {
148597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            return err;
148697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
148797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
148897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        sp<MediaSource> encoder;
148997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        err = setupVideoEncoder(mediaSource, videoBitRate, &encoder);
149097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (err != OK) {
149197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            return err;
149297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
149397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
149497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        writer->addSource(encoder);
149597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        *totalBitRate += videoBitRate;
149697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
149797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
149897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    // Audio source is added at the end if it exists.
149997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    // This help make sure that the "recoding" sound is suppressed for
150097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    // camcorder applications in the recorded files.
150197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_CNT)) {
150297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        err = setupAudioEncoder(writer);
150397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (err != OK) return err;
150497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        *totalBitRate += mAudioBitRate;
150597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
150697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (mInterleaveDurationUs > 0) {
150897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        reinterpret_cast<MPEG4Writer *>(writer.get())->
150997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            setInterleaveDuration(mInterleaveDurationUs);
151097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
151197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (mLongitudex10000 > -3600000 && mLatitudex10000 > -3600000) {
151297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        reinterpret_cast<MPEG4Writer *>(writer.get())->
151397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            setGeoData(mLatitudex10000, mLongitudex10000);
151497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
151597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (mMaxFileDurationUs != 0) {
151697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        writer->setMaxFileDuration(mMaxFileDurationUs);
151797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
151897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (mMaxFileSizeBytes != 0) {
151997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        writer->setMaxFileSize(mMaxFileSizeBytes);
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mStartTimeOffsetMs = mEncoderProfiles->getStartTimeOffsetMs(mCameraId);
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mStartTimeOffsetMs > 0) {
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        reinterpret_cast<MPEG4Writer *>(writer.get())->
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setStartTimeOffsetMs(mStartTimeOffsetMs);
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    writer->setListener(mListener);
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    *mediaWriter = writer;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15335778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid StagefrightRecorder::setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate,
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<MetaData> *meta) {
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (*meta)->setInt64(kKeyTime, startTimeUs);
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (*meta)->setInt32(kKeyFileType, mOutputFormat);
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (*meta)->setInt32(kKeyBitRate, totalBitRate);
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mMovieTimeScale > 0) {
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale);
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mTrackEveryTimeDurationUs > 0) {
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mRotationDegrees != 0) {
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        (*meta)->setInt32(kKeyRotation, mRotationDegrees);
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t StagefrightRecorder::startMPEG4Recording() {
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t totalBitRate;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupMPEG4Recording(
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mOutputFd, mVideoWidth, mVideoHeight,
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mVideoBitRate, &totalBitRate, &mWriter);
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t startTimeUs = systemTime() / 1000;
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MetaData> meta = new MetaData;
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    setupMPEG4MetaData(startTimeUs, totalBitRate, &meta);
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mWriter->start(meta.get());
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
1566729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1567729de186450f78c099637e1fce743fe531862c52Andreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1569729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1570729de186450f78c099637e1fce743fe531862c52Andreas Huber
1571729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t StagefrightRecorder::pause() {
1572729de186450f78c099637e1fce743fe531862c52Andreas Huber    ALOGV("pause");
1573729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (mWriter == NULL) {
1574729de186450f78c099637e1fce743fe531862c52Andreas Huber        return UNKNOWN_ERROR;
1575729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber    mWriter->pause();
1577729de186450f78c099637e1fce743fe531862c52Andreas Huber
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mStarted) {
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mStarted = false;
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t params = 0;
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber        if (mAudioSource != AUDIO_SOURCE_CNT) {
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            params |= IMediaPlayerService::kBatteryDataTrackAudio;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mVideoSource != VIDEO_SOURCE_LIST_END) {
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber            params |= IMediaPlayerService::kBatteryDataTrackVideo;
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        addBatteryData(params);
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1596729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t StagefrightRecorder::stop() {
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber    ALOGV("stop");
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = OK;
1599729de186450f78c099637e1fce743fe531862c52Andreas Huber
16002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (mCaptureTimeLapse && mCameraSourceTimeLapse != NULL) {
16012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        mCameraSourceTimeLapse->startQuickReadReturns();
16022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        mCameraSourceTimeLapse = NULL;
16032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (mWriter != NULL) {
16062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mWriter->stop();
16072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        mWriter.clear();
16082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (mOutputFd >= 0) {
16112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        ::close(mOutputFd);
16122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        mOutputFd = -1;
16132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (mStarted) {
16162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        mStarted = false;
16172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        uint32_t params = 0;
16192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (mAudioSource != AUDIO_SOURCE_CNT) {
16202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            params |= IMediaPlayerService::kBatteryDataTrackAudio;
16212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (mVideoSource != VIDEO_SOURCE_LIST_END) {
16232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            params |= IMediaPlayerService::kBatteryDataTrackVideo;
16242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        addBatteryData(params);
16272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
1628729de186450f78c099637e1fce743fe531862c52Andreas Huber
1629729de186450f78c099637e1fce743fe531862c52Andreas Huber
1630729de186450f78c099637e1fce743fe531862c52Andreas Huber    return err;
1631729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1632729de186450f78c099637e1fce743fe531862c52Andreas Huber
1633729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t StagefrightRecorder::close() {
1634729de186450f78c099637e1fce743fe531862c52Andreas Huber    ALOGV("close");
1635729de186450f78c099637e1fce743fe531862c52Andreas Huber    stop();
1636729de186450f78c099637e1fce743fe531862c52Andreas Huber
1637729de186450f78c099637e1fce743fe531862c52Andreas Huber    return OK;
1638729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1639729de186450f78c099637e1fce743fe531862c52Andreas Huber
1640729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t StagefrightRecorder::reset() {
1641729de186450f78c099637e1fce743fe531862c52Andreas Huber    ALOGV("reset");
1642729de186450f78c099637e1fce743fe531862c52Andreas Huber    stop();
1643729de186450f78c099637e1fce743fe531862c52Andreas Huber
1644729de186450f78c099637e1fce743fe531862c52Andreas Huber    // No audio or video source by default
1645729de186450f78c099637e1fce743fe531862c52Andreas Huber    mAudioSource = AUDIO_SOURCE_CNT;
1646729de186450f78c099637e1fce743fe531862c52Andreas Huber    mVideoSource = VIDEO_SOURCE_LIST_END;
1647729de186450f78c099637e1fce743fe531862c52Andreas Huber
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber    // Default parameters
1649729de186450f78c099637e1fce743fe531862c52Andreas Huber    mOutputFormat  = OUTPUT_FORMAT_THREE_GPP;
1650729de186450f78c099637e1fce743fe531862c52Andreas Huber    mAudioEncoder  = AUDIO_ENCODER_AMR_NB;
1651729de186450f78c099637e1fce743fe531862c52Andreas Huber    mVideoEncoder  = VIDEO_ENCODER_H263;
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber    mVideoWidth    = 176;
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber    mVideoHeight   = 144;
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber    mFrameRate     = -1;
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber    mVideoBitRate  = 192000;
1656729de186450f78c099637e1fce743fe531862c52Andreas Huber    mSampleRate    = 8000;
1657729de186450f78c099637e1fce743fe531862c52Andreas Huber    mAudioChannels = 1;
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber    mAudioBitRate  = 12200;
1659729de186450f78c099637e1fce743fe531862c52Andreas Huber    mInterleaveDurationUs = 0;
1660729de186450f78c099637e1fce743fe531862c52Andreas Huber    mIFramesIntervalSec = 1;
1661729de186450f78c099637e1fce743fe531862c52Andreas Huber    mAudioSourceNode = 0;
1662729de186450f78c099637e1fce743fe531862c52Andreas Huber    mUse64BitFileOffset = false;
1663729de186450f78c099637e1fce743fe531862c52Andreas Huber    mMovieTimeScale  = -1;
1664729de186450f78c099637e1fce743fe531862c52Andreas Huber    mAudioTimeScale  = -1;
1665729de186450f78c099637e1fce743fe531862c52Andreas Huber    mVideoTimeScale  = -1;
1666729de186450f78c099637e1fce743fe531862c52Andreas Huber    mCameraId        = 0;
1667729de186450f78c099637e1fce743fe531862c52Andreas Huber    mStartTimeOffsetMs = -1;
1668c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    mVideoEncoderProfile = -1;
1669c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    mVideoEncoderLevel   = -1;
1670729de186450f78c099637e1fce743fe531862c52Andreas Huber    mMaxFileDurationUs = 0;
1671729de186450f78c099637e1fce743fe531862c52Andreas Huber    mMaxFileSizeBytes = 0;
1672729de186450f78c099637e1fce743fe531862c52Andreas Huber    mTrackEveryTimeDurationUs = 0;
1673729de186450f78c099637e1fce743fe531862c52Andreas Huber    mCaptureTimeLapse = false;
1674729de186450f78c099637e1fce743fe531862c52Andreas Huber    mTimeBetweenTimeLapseFrameCaptureUs = -1;
1675729de186450f78c099637e1fce743fe531862c52Andreas Huber    mCameraSourceTimeLapse = NULL;
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIsMetaDataStoredInVideoBuffers = false;
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mEncoderProfiles = MediaProfiles::getInstance();
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mRotationDegrees = 0;
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLatitudex10000 = -3600000;
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLongitudex10000 = -3600000;
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputFd = -1;
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::getMaxAmplitude(int *max) {
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("getMaxAmplitude");
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (max == NULL) {
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGE("Null pointer argument");
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return BAD_VALUE;
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mAudioSourceNode != 0) {
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *max = mAudioSourceNode->getMaxAmplitude();
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *max = 0;
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t StagefrightRecorder::dump(
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int fd, const Vector<String16>& args) const {
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ALOGV("dump");
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const size_t SIZE = 256;
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    char buffer[SIZE];
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    String8 result;
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mWriter != 0) {
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mWriter->dump(fd, args);
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        snprintf(buffer, SIZE, "   No file writer\n");
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        result.append(buffer);
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "   Recorder: %p\n", this);
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "   Output file (fd %d):\n", mOutputFd);
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     File format: %d\n", mOutputFormat);
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Max file size (bytes): %lld\n", mMaxFileSizeBytes);
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Max file duration (us): %lld\n", mMaxFileDurationUs);
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32);
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Interleave duration (us): %d\n", mInterleaveDurationUs);
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Progress notification: %lld us\n", mTrackEveryTimeDurationUs);
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "   Audio\n");
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Source: %d\n", mAudioSource);
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Encoder: %d\n", mAudioEncoder);
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mAudioBitRate);
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Sampling rate (hz): %d\n", mSampleRate);
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Number of channels: %d\n", mAudioChannels);
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Max amplitude: %d\n", mAudioSourceNode == 0? 0: mAudioSourceNode->getMaxAmplitude());
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "   Video\n");
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Source: %d\n", mVideoSource);
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Camera Id: %d\n", mCameraId);
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    result.append(buffer);
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    snprintf(buffer, SIZE, "     Start time offset (ms): %d\n", mStartTimeOffsetMs);
1752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    result.append(buffer);
1753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    snprintf(buffer, SIZE, "     Encoder: %d\n", mVideoEncoder);
1754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    result.append(buffer);
1755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    snprintf(buffer, SIZE, "     Encoder profile: %d\n", mVideoEncoderProfile);
1756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    result.append(buffer);
1757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    snprintf(buffer, SIZE, "     Encoder level: %d\n", mVideoEncoderLevel);
1758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    result.append(buffer);
1759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    snprintf(buffer, SIZE, "     I frames interval (s): %d\n", mIFramesIntervalSec);
176094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    result.append(buffer);
176194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    snprintf(buffer, SIZE, "     Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight);
1762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    result.append(buffer);
1763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    snprintf(buffer, SIZE, "     Frame rate (fps): %d\n", mFrameRate);
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    result.append(buffer);
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mVideoBitRate);
1766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    result.append(buffer);
1767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    ::write(fd, result.string(), result.size());
1768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
1769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}  // namespace android
1771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber