blob: 9541015699b135836d770a5b465f1054ab2c2e0c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 **
3 ** Copyright (c) 2008 The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18//#define LOG_NDEBUG 0
19#define LOG_TAG "MediaRecorder"
20#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021#include <media/mediarecorder.h>
Mathias Agopian07952722009-05-19 19:08:10 -070022#include <binder/IServiceManager.h>
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070023#include <utils/String8.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024#include <media/IMediaPlayerService.h>
25#include <media/IMediaRecorder.h>
James Dong34bbc222010-01-15 18:13:58 -080026#include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED
Pannag Sanketi897e27b2011-07-01 17:39:39 -070027#include <gui/ISurfaceTexture.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
29namespace android {
30
Wu-cheng Li42419ce2011-06-01 17:22:24 +080031status_t MediaRecorder::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032{
Steve Block71f2cf12011-10-20 11:56:00 +010033 ALOGV("setCamera(%p,%p)", camera.get(), proxy.get());
Glenn Kasten18db49a2012-03-12 16:29:55 -070034 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +000035 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036 return INVALID_OPERATION;
37 }
38 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
Steve Block3762c312012-01-06 19:20:56 +000039 ALOGE("setCamera called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 return INVALID_OPERATION;
41 }
42
Wu-cheng Li42419ce2011-06-01 17:22:24 +080043 status_t ret = mMediaRecorder->setCamera(camera, proxy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +010045 ALOGV("setCamera failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080047 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 }
49 return ret;
50}
51
52status_t MediaRecorder::setPreviewSurface(const sp<Surface>& surface)
53{
Steve Block71f2cf12011-10-20 11:56:00 +010054 ALOGV("setPreviewSurface(%p)", surface.get());
Glenn Kasten18db49a2012-03-12 16:29:55 -070055 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +000056 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 return INVALID_OPERATION;
58 }
59 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Block3762c312012-01-06 19:20:56 +000060 ALOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 return INVALID_OPERATION;
62 }
63 if (!mIsVideoSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +000064 ALOGE("try to set preview surface without setting the video source first");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065 return INVALID_OPERATION;
66 }
67
Jamie Gennis85cfdd02010-08-10 16:37:53 -070068 status_t ret = mMediaRecorder->setPreviewSurface(surface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +010070 ALOGV("setPreviewSurface failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080072 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 }
74 return ret;
75}
76
77status_t MediaRecorder::init()
78{
Steve Block71f2cf12011-10-20 11:56:00 +010079 ALOGV("init");
Glenn Kasten18db49a2012-03-12 16:29:55 -070080 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +000081 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 return INVALID_OPERATION;
83 }
84 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
Steve Block3762c312012-01-06 19:20:56 +000085 ALOGE("init called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 return INVALID_OPERATION;
87 }
88
89 status_t ret = mMediaRecorder->init();
90 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +010091 ALOGV("init failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080093 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 }
95
96 ret = mMediaRecorder->setListener(this);
97 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +010098 ALOGV("setListener failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800100 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 }
102
103 mCurrentState = MEDIA_RECORDER_INITIALIZED;
104 return ret;
105}
106
107status_t MediaRecorder::setVideoSource(int vs)
108{
Steve Block71f2cf12011-10-20 11:56:00 +0100109 ALOGV("setVideoSource(%d)", vs);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700110 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000111 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 return INVALID_OPERATION;
113 }
114 if (mIsVideoSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +0000115 ALOGE("video source has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 return INVALID_OPERATION;
117 }
118 if (mCurrentState & MEDIA_RECORDER_IDLE) {
Steve Block71f2cf12011-10-20 11:56:00 +0100119 ALOGV("Call init() since the media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 status_t ret = init();
121 if (OK != ret) {
122 return ret;
123 }
124 }
125 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
Steve Block3762c312012-01-06 19:20:56 +0000126 ALOGE("setVideoSource called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 return INVALID_OPERATION;
128 }
129
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700130 // following call is made over the Binder Interface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 status_t ret = mMediaRecorder->setVideoSource(vs);
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +0100134 ALOGV("setVideoSource failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800136 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 }
138 mIsVideoSourceSet = true;
139 return ret;
140}
141
142status_t MediaRecorder::setAudioSource(int as)
143{
Steve Block71f2cf12011-10-20 11:56:00 +0100144 ALOGV("setAudioSource(%d)", as);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700145 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000146 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 return INVALID_OPERATION;
148 }
149 if (mCurrentState & MEDIA_RECORDER_IDLE) {
Steve Block71f2cf12011-10-20 11:56:00 +0100150 ALOGV("Call init() since the media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 status_t ret = init();
152 if (OK != ret) {
153 return ret;
154 }
155 }
156 if (mIsAudioSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +0000157 ALOGE("audio source has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 return INVALID_OPERATION;
159 }
160 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
Steve Block3762c312012-01-06 19:20:56 +0000161 ALOGE("setAudioSource called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 return INVALID_OPERATION;
163 }
164
165 status_t ret = mMediaRecorder->setAudioSource(as);
166 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +0100167 ALOGV("setAudioSource failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800169 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 }
171 mIsAudioSourceSet = true;
172 return ret;
173}
174
175status_t MediaRecorder::setOutputFormat(int of)
176{
Steve Block71f2cf12011-10-20 11:56:00 +0100177 ALOGV("setOutputFormat(%d)", of);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700178 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000179 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 return INVALID_OPERATION;
181 }
182 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
Steve Block3762c312012-01-06 19:20:56 +0000183 ALOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 return INVALID_OPERATION;
185 }
Andreas Huber9adf4662010-10-12 14:17:45 -0700186 if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START && of != OUTPUT_FORMAT_RTP_AVP && of != OUTPUT_FORMAT_MPEG2TS) { //first non-video output format
Steve Block3762c312012-01-06 19:20:56 +0000187 ALOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 return INVALID_OPERATION;
189 }
190
191 status_t ret = mMediaRecorder->setOutputFormat(of);
192 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000193 ALOGE("setOutputFormat failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800195 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 }
197 mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED;
198 return ret;
199}
200
201status_t MediaRecorder::setVideoEncoder(int ve)
202{
Steve Block71f2cf12011-10-20 11:56:00 +0100203 ALOGV("setVideoEncoder(%d)", ve);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700204 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000205 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 return INVALID_OPERATION;
207 }
208 if (!mIsVideoSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +0000209 ALOGE("try to set the video encoder without setting the video source first");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 return INVALID_OPERATION;
211 }
212 if (mIsVideoEncoderSet) {
Steve Block3762c312012-01-06 19:20:56 +0000213 ALOGE("video encoder has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 return INVALID_OPERATION;
215 }
216 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Block3762c312012-01-06 19:20:56 +0000217 ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 return INVALID_OPERATION;
219 }
220
221 status_t ret = mMediaRecorder->setVideoEncoder(ve);
222 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +0100223 ALOGV("setVideoEncoder failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800225 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 }
227 mIsVideoEncoderSet = true;
228 return ret;
229}
230
231status_t MediaRecorder::setAudioEncoder(int ae)
232{
Steve Block71f2cf12011-10-20 11:56:00 +0100233 ALOGV("setAudioEncoder(%d)", ae);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700234 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000235 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 return INVALID_OPERATION;
237 }
238 if (!mIsAudioSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +0000239 ALOGE("try to set the audio encoder without setting the audio source first");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 return INVALID_OPERATION;
241 }
242 if (mIsAudioEncoderSet) {
Steve Block3762c312012-01-06 19:20:56 +0000243 ALOGE("audio encoder has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 return INVALID_OPERATION;
245 }
246 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Block3762c312012-01-06 19:20:56 +0000247 ALOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 return INVALID_OPERATION;
249 }
250
251 status_t ret = mMediaRecorder->setAudioEncoder(ae);
252 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +0100253 ALOGV("setAudioEncoder failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800255 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 }
257 mIsAudioEncoderSet = true;
258 return ret;
259}
260
261status_t MediaRecorder::setOutputFile(const char* path)
262{
Steve Block71f2cf12011-10-20 11:56:00 +0100263 ALOGV("setOutputFile(%s)", path);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700264 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000265 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 return INVALID_OPERATION;
267 }
268 if (mIsOutputFileSet) {
Steve Block3762c312012-01-06 19:20:56 +0000269 ALOGE("output file has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 return INVALID_OPERATION;
271 }
272 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Block3762c312012-01-06 19:20:56 +0000273 ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 return INVALID_OPERATION;
275 }
276
277 status_t ret = mMediaRecorder->setOutputFile(path);
278 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +0100279 ALOGV("setOutputFile failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800281 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 }
283 mIsOutputFileSet = true;
284 return ret;
285}
286
287status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
288{
Steve Block71f2cf12011-10-20 11:56:00 +0100289 ALOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700290 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000291 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 return INVALID_OPERATION;
293 }
294 if (mIsOutputFileSet) {
Steve Block3762c312012-01-06 19:20:56 +0000295 ALOGE("output file has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 return INVALID_OPERATION;
297 }
298 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Block3762c312012-01-06 19:20:56 +0000299 ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 return INVALID_OPERATION;
301 }
302
James Dongbafa7ea2011-02-22 12:34:02 -0800303 // It appears that if an invalid file descriptor is passed through
304 // binder calls, the server-side of the inter-process function call
305 // is skipped. As a result, the check at the server-side to catch
306 // the invalid file descritpor never gets invoked. This is to workaround
307 // this issue by checking the file descriptor first before passing
308 // it through binder call.
309 if (fd < 0) {
Steve Block3762c312012-01-06 19:20:56 +0000310 ALOGE("Invalid file descriptor: %d", fd);
James Dongbafa7ea2011-02-22 12:34:02 -0800311 return BAD_VALUE;
312 }
313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
315 if (OK != ret) {
Steve Block71f2cf12011-10-20 11:56:00 +0100316 ALOGV("setOutputFile failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800318 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 }
320 mIsOutputFileSet = true;
321 return ret;
322}
323
324status_t MediaRecorder::setVideoSize(int width, int height)
325{
Steve Block71f2cf12011-10-20 11:56:00 +0100326 ALOGV("setVideoSize(%d, %d)", width, height);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700327 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000328 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 return INVALID_OPERATION;
330 }
331 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Block3762c312012-01-06 19:20:56 +0000332 ALOGE("setVideoSize called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 return INVALID_OPERATION;
334 }
335 if (!mIsVideoSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +0000336 ALOGE("Cannot set video size without setting video source first");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 return INVALID_OPERATION;
338 }
339
340 status_t ret = mMediaRecorder->setVideoSize(width, height);
341 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000342 ALOGE("setVideoSize failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800344 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 }
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 return ret;
348}
349
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700350// Query a SurfaceMediaSurface through the Mediaserver, over the
351// binder interface. This is used by the Filter Framework (MeidaEncoder)
352// to get an <ISurfaceTexture> object to hook up to ANativeWindow.
353sp<ISurfaceTexture> MediaRecorder::
354 querySurfaceMediaSourceFromMediaServer()
355{
356 Mutex::Autolock _l(mLock);
357 mSurfaceMediaSource =
358 mMediaRecorder->querySurfaceMediaSource();
359 if (mSurfaceMediaSource == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000360 ALOGE("SurfaceMediaSource could not be initialized!");
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700361 }
362 return mSurfaceMediaSource;
363}
364
365
366
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
368{
Steve Block71f2cf12011-10-20 11:56:00 +0100369 ALOGV("setVideoFrameRate(%d)", frames_per_second);
Glenn Kasten18db49a2012-03-12 16:29:55 -0700370 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000371 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 return INVALID_OPERATION;
373 }
374 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Block3762c312012-01-06 19:20:56 +0000375 ALOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 return INVALID_OPERATION;
377 }
378 if (!mIsVideoSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +0000379 ALOGE("Cannot set video frame rate without setting video source first");
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700380 return INVALID_OPERATION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 }
382
383 status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second);
384 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000385 ALOGE("setVideoFrameRate failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800387 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 }
389 return ret;
390}
391
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700392status_t MediaRecorder::setParameters(const String8& params) {
Steve Block71f2cf12011-10-20 11:56:00 +0100393 ALOGV("setParameters(%s)", params.string());
Glenn Kasten18db49a2012-03-12 16:29:55 -0700394 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000395 ALOGE("media recorder is not initialized yet");
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700396 return INVALID_OPERATION;
397 }
398
James Dong61701ce2010-02-25 18:41:46 -0800399 bool isInvalidState = (mCurrentState &
400 (MEDIA_RECORDER_PREPARED |
401 MEDIA_RECORDER_RECORDING |
402 MEDIA_RECORDER_ERROR));
403 if (isInvalidState) {
Steve Block3762c312012-01-06 19:20:56 +0000404 ALOGE("setParameters is called in an invalid state: %d", mCurrentState);
James Dong61701ce2010-02-25 18:41:46 -0800405 return INVALID_OPERATION;
406 }
407
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700408 status_t ret = mMediaRecorder->setParameters(params);
409 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000410 ALOGE("setParameters(%s) failed: %d", params.string(), ret);
The Android Open Source Project10592532009-03-18 17:39:46 -0700411 // Do not change our current state to MEDIA_RECORDER_ERROR, failures
412 // of the only currently supported parameters, "max-duration" and
413 // "max-filesize" are _not_ fatal.
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700414 }
415
416 return ret;
417}
418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419status_t MediaRecorder::prepare()
420{
Steve Block71f2cf12011-10-20 11:56:00 +0100421 ALOGV("prepare");
Glenn Kasten18db49a2012-03-12 16:29:55 -0700422 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000423 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 return INVALID_OPERATION;
425 }
426 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Block3762c312012-01-06 19:20:56 +0000427 ALOGE("prepare called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 return INVALID_OPERATION;
429 }
430 if (mIsAudioSourceSet != mIsAudioEncoderSet) {
431 if (mIsAudioSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +0000432 ALOGE("audio source is set, but audio encoder is not set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 } else { // must not happen, since setAudioEncoder checks this already
Steve Block3762c312012-01-06 19:20:56 +0000434 ALOGE("audio encoder is set, but audio source is not set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 }
436 return INVALID_OPERATION;
437 }
438
439 if (mIsVideoSourceSet != mIsVideoEncoderSet) {
440 if (mIsVideoSourceSet) {
Steve Block3762c312012-01-06 19:20:56 +0000441 ALOGE("video source is set, but video encoder is not set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 } else { // must not happen, since setVideoEncoder checks this already
Steve Block3762c312012-01-06 19:20:56 +0000443 ALOGE("video encoder is set, but video source is not set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 }
445 return INVALID_OPERATION;
446 }
447
448 status_t ret = mMediaRecorder->prepare();
449 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000450 ALOGE("prepare failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800452 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 }
454 mCurrentState = MEDIA_RECORDER_PREPARED;
455 return ret;
456}
457
458status_t MediaRecorder::getMaxAmplitude(int* max)
459{
Steve Block71f2cf12011-10-20 11:56:00 +0100460 ALOGV("getMaxAmplitude");
Glenn Kasten18db49a2012-03-12 16:29:55 -0700461 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000462 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 return INVALID_OPERATION;
464 }
465 if (mCurrentState & MEDIA_RECORDER_ERROR) {
Steve Block3762c312012-01-06 19:20:56 +0000466 ALOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 return INVALID_OPERATION;
468 }
469
470 status_t ret = mMediaRecorder->getMaxAmplitude(max);
471 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000472 ALOGE("getMaxAmplitude failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800474 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 }
476 return ret;
477}
478
479status_t MediaRecorder::start()
480{
Steve Block71f2cf12011-10-20 11:56:00 +0100481 ALOGV("start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000483 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 return INVALID_OPERATION;
485 }
486 if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
Steve Block3762c312012-01-06 19:20:56 +0000487 ALOGE("start called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 return INVALID_OPERATION;
489 }
490
491 status_t ret = mMediaRecorder->start();
492 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000493 ALOGE("start failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800495 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 }
497 mCurrentState = MEDIA_RECORDER_RECORDING;
498 return ret;
499}
500
501status_t MediaRecorder::stop()
502{
Steve Block71f2cf12011-10-20 11:56:00 +0100503 ALOGV("stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000505 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 return INVALID_OPERATION;
507 }
508 if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
Steve Block3762c312012-01-06 19:20:56 +0000509 ALOGE("stop called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510 return INVALID_OPERATION;
511 }
512
513 status_t ret = mMediaRecorder->stop();
514 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000515 ALOGE("stop failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800517 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 }
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700519
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700520 // FIXME:
521 // stop and reset are semantically different.
522 // We treat them the same for now, and will change this in the future.
523 doCleanUp();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 mCurrentState = MEDIA_RECORDER_IDLE;
525 return ret;
526}
527
528// Reset should be OK in any state
529status_t MediaRecorder::reset()
530{
Steve Block71f2cf12011-10-20 11:56:00 +0100531 ALOGV("reset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 if (mMediaRecorder == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000533 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 return INVALID_OPERATION;
535 }
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 doCleanUp();
538 status_t ret = UNKNOWN_ERROR;
Glenn Kasten18db49a2012-03-12 16:29:55 -0700539 switch (mCurrentState) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 case MEDIA_RECORDER_IDLE:
541 ret = OK;
542 break;
543
544 case MEDIA_RECORDER_RECORDING:
545 case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
546 case MEDIA_RECORDER_PREPARED:
547 case MEDIA_RECORDER_ERROR: {
548 ret = doReset();
549 if (OK != ret) {
Glenn Kasten18db49a2012-03-12 16:29:55 -0700550 return ret; // No need to continue
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 }
552 } // Intentional fall through
553 case MEDIA_RECORDER_INITIALIZED:
554 ret = close();
555 break;
556
557 default: {
Steve Block3762c312012-01-06 19:20:56 +0000558 ALOGE("Unexpected non-existing state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 break;
560 }
561 }
562 return ret;
563}
564
565status_t MediaRecorder::close()
566{
Steve Block71f2cf12011-10-20 11:56:00 +0100567 ALOGV("close");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
Steve Block3762c312012-01-06 19:20:56 +0000569 ALOGE("close called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 return INVALID_OPERATION;
571 }
572 status_t ret = mMediaRecorder->close();
573 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000574 ALOGE("close failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 mCurrentState = MEDIA_RECORDER_ERROR;
576 return UNKNOWN_ERROR;
577 } else {
578 mCurrentState = MEDIA_RECORDER_IDLE;
579 }
580 return ret;
581}
582
583status_t MediaRecorder::doReset()
584{
Steve Block71f2cf12011-10-20 11:56:00 +0100585 ALOGV("doReset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 status_t ret = mMediaRecorder->reset();
587 if (OK != ret) {
Steve Block3762c312012-01-06 19:20:56 +0000588 ALOGE("doReset failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800590 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 } else {
592 mCurrentState = MEDIA_RECORDER_INITIALIZED;
593 }
594 return ret;
595}
596
597void MediaRecorder::doCleanUp()
598{
Steve Block71f2cf12011-10-20 11:56:00 +0100599 ALOGV("doCleanUp");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 mIsAudioSourceSet = false;
601 mIsVideoSourceSet = false;
602 mIsAudioEncoderSet = false;
603 mIsVideoEncoderSet = false;
604 mIsOutputFileSet = false;
605}
606
607// Release should be OK in any state
608status_t MediaRecorder::release()
609{
Steve Block71f2cf12011-10-20 11:56:00 +0100610 ALOGV("release");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 if (mMediaRecorder != NULL) {
612 return mMediaRecorder->release();
613 }
614 return INVALID_OPERATION;
615}
616
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700617MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618{
Steve Block71f2cf12011-10-20 11:56:00 +0100619 ALOGV("constructor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800620
James Dong34bbc222010-01-15 18:13:58 -0800621 const sp<IMediaPlayerService>& service(getMediaPlayerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 if (service != NULL) {
623 mMediaRecorder = service->createMediaRecorder(getpid());
624 }
625 if (mMediaRecorder != NULL) {
626 mCurrentState = MEDIA_RECORDER_IDLE;
627 }
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700628
629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 doCleanUp();
631}
632
633status_t MediaRecorder::initCheck()
634{
635 return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
636}
637
638MediaRecorder::~MediaRecorder()
639{
Steve Block71f2cf12011-10-20 11:56:00 +0100640 ALOGV("destructor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 if (mMediaRecorder != NULL) {
642 mMediaRecorder.clear();
643 }
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700644
645 if (mSurfaceMediaSource != NULL) {
646 mSurfaceMediaSource.clear();
647 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648}
649
650status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
651{
Steve Block71f2cf12011-10-20 11:56:00 +0100652 ALOGV("setListener");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800653 Mutex::Autolock _l(mLock);
654 mListener = listener;
655
656 return NO_ERROR;
657}
658
659void MediaRecorder::notify(int msg, int ext1, int ext2)
660{
Steve Block71f2cf12011-10-20 11:56:00 +0100661 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662
663 sp<MediaRecorderListener> listener;
664 mLock.lock();
665 listener = mListener;
666 mLock.unlock();
667
668 if (listener != NULL) {
669 Mutex::Autolock _l(mNotifyLock);
Steve Block71f2cf12011-10-20 11:56:00 +0100670 ALOGV("callback application");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 listener->notify(msg, ext1, ext2);
Steve Block71f2cf12011-10-20 11:56:00 +0100672 ALOGV("back from callback");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673 }
674}
675
James Dong34bbc222010-01-15 18:13:58 -0800676void MediaRecorder::died()
677{
Steve Block71f2cf12011-10-20 11:56:00 +0100678 ALOGV("died");
James Dong34bbc222010-01-15 18:13:58 -0800679 notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
680}
681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800682}; // namespace android