blob: 8d947d862549f776f608c7f1557f6db738ea6c01 [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>
Mathias Agopian000479f2010-02-09 17:46:37 -080021#include <surfaceflinger/Surface.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022#include <media/mediarecorder.h>
Mathias Agopian07952722009-05-19 19:08:10 -070023#include <binder/IServiceManager.h>
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070024#include <utils/String8.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025#include <media/IMediaPlayerService.h>
26#include <media/IMediaRecorder.h>
James Dong34bbc222010-01-15 18:13:58 -080027#include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED
Pannag Sanketi897e27b2011-07-01 17:39:39 -070028#include <gui/ISurfaceTexture.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
30namespace android {
31
Wu-cheng Li42419ce2011-06-01 17:22:24 +080032status_t MediaRecorder::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033{
Steve Block06ade6a2011-10-20 11:56:00 +010034 ALOGV("setCamera(%p,%p)", camera.get(), proxy.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +000036 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 return INVALID_OPERATION;
38 }
39 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
Steve Blockc6aacce2012-01-06 19:20:56 +000040 ALOGE("setCamera called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041 return INVALID_OPERATION;
42 }
43
Wu-cheng Li42419ce2011-06-01 17:22:24 +080044 status_t ret = mMediaRecorder->setCamera(camera, proxy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +010046 ALOGV("setCamera failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080048 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049 }
50 return ret;
51}
52
53status_t MediaRecorder::setPreviewSurface(const sp<Surface>& surface)
54{
Steve Block06ade6a2011-10-20 11:56:00 +010055 ALOGV("setPreviewSurface(%p)", surface.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +000057 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 return INVALID_OPERATION;
59 }
60 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +000061 ALOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 return INVALID_OPERATION;
63 }
64 if (!mIsVideoSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +000065 ALOGE("try to set preview surface without setting the video source first");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 return INVALID_OPERATION;
67 }
68
Jamie Gennis85cfdd02010-08-10 16:37:53 -070069 status_t ret = mMediaRecorder->setPreviewSurface(surface);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +010071 ALOGV("setPreviewSurface failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080073 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 }
75 return ret;
76}
77
78status_t MediaRecorder::init()
79{
Steve Block06ade6a2011-10-20 11:56:00 +010080 ALOGV("init");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +000082 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 return INVALID_OPERATION;
84 }
85 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
Steve Blockc6aacce2012-01-06 19:20:56 +000086 ALOGE("init called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 return INVALID_OPERATION;
88 }
89
90 status_t ret = mMediaRecorder->init();
91 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +010092 ALOGV("init failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080094 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 }
96
97 ret = mMediaRecorder->setListener(this);
98 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +010099 ALOGV("setListener failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800101 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 }
103
104 mCurrentState = MEDIA_RECORDER_INITIALIZED;
105 return ret;
106}
107
108status_t MediaRecorder::setVideoSource(int vs)
109{
Steve Block06ade6a2011-10-20 11:56:00 +0100110 ALOGV("setVideoSource(%d)", vs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000112 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 return INVALID_OPERATION;
114 }
115 if (mIsVideoSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000116 ALOGE("video source has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 return INVALID_OPERATION;
118 }
119 if (mCurrentState & MEDIA_RECORDER_IDLE) {
Steve Block06ade6a2011-10-20 11:56:00 +0100120 ALOGV("Call init() since the media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 status_t ret = init();
122 if (OK != ret) {
123 return ret;
124 }
125 }
126 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000127 ALOGE("setVideoSource called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 return INVALID_OPERATION;
129 }
130
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700131 // following call is made over the Binder Interface
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 status_t ret = mMediaRecorder->setVideoSource(vs);
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +0100135 ALOGV("setVideoSource failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800137 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 }
139 mIsVideoSourceSet = true;
140 return ret;
141}
142
143status_t MediaRecorder::setAudioSource(int as)
144{
Steve Block06ade6a2011-10-20 11:56:00 +0100145 ALOGV("setAudioSource(%d)", as);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000147 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 return INVALID_OPERATION;
149 }
150 if (mCurrentState & MEDIA_RECORDER_IDLE) {
Steve Block06ade6a2011-10-20 11:56:00 +0100151 ALOGV("Call init() since the media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 status_t ret = init();
153 if (OK != ret) {
154 return ret;
155 }
156 }
157 if (mIsAudioSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000158 ALOGE("audio source has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 return INVALID_OPERATION;
160 }
161 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000162 ALOGE("setAudioSource called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 return INVALID_OPERATION;
164 }
165
166 status_t ret = mMediaRecorder->setAudioSource(as);
167 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +0100168 ALOGV("setAudioSource failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800170 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 }
172 mIsAudioSourceSet = true;
173 return ret;
174}
175
176status_t MediaRecorder::setOutputFormat(int of)
177{
Steve Block06ade6a2011-10-20 11:56:00 +0100178 ALOGV("setOutputFormat(%d)", of);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000180 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 return INVALID_OPERATION;
182 }
183 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000184 ALOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 return INVALID_OPERATION;
186 }
Andreas Huber9adf4662010-10-12 14:17:45 -0700187 if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START && of != OUTPUT_FORMAT_RTP_AVP && of != OUTPUT_FORMAT_MPEG2TS) { //first non-video output format
Steve Blockc6aacce2012-01-06 19:20:56 +0000188 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 -0800189 return INVALID_OPERATION;
190 }
191
192 status_t ret = mMediaRecorder->setOutputFormat(of);
193 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000194 ALOGE("setOutputFormat failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800196 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 }
198 mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED;
199 return ret;
200}
201
202status_t MediaRecorder::setVideoEncoder(int ve)
203{
Steve Block06ade6a2011-10-20 11:56:00 +0100204 ALOGV("setVideoEncoder(%d)", ve);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000206 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 return INVALID_OPERATION;
208 }
209 if (!mIsVideoSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000210 ALOGE("try to set the video encoder without setting the video source first");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 return INVALID_OPERATION;
212 }
213 if (mIsVideoEncoderSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000214 ALOGE("video encoder has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 return INVALID_OPERATION;
216 }
217 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000218 ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 return INVALID_OPERATION;
220 }
221
222 status_t ret = mMediaRecorder->setVideoEncoder(ve);
223 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +0100224 ALOGV("setVideoEncoder failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800226 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 }
228 mIsVideoEncoderSet = true;
229 return ret;
230}
231
232status_t MediaRecorder::setAudioEncoder(int ae)
233{
Steve Block06ade6a2011-10-20 11:56:00 +0100234 ALOGV("setAudioEncoder(%d)", ae);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000236 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 return INVALID_OPERATION;
238 }
239 if (!mIsAudioSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000240 ALOGE("try to set the audio encoder without setting the audio source first");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 return INVALID_OPERATION;
242 }
243 if (mIsAudioEncoderSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000244 ALOGE("audio encoder has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 return INVALID_OPERATION;
246 }
247 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000248 ALOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 return INVALID_OPERATION;
250 }
251
252 status_t ret = mMediaRecorder->setAudioEncoder(ae);
253 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +0100254 ALOGV("setAudioEncoder failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800256 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 }
258 mIsAudioEncoderSet = true;
259 return ret;
260}
261
262status_t MediaRecorder::setOutputFile(const char* path)
263{
Steve Block06ade6a2011-10-20 11:56:00 +0100264 ALOGV("setOutputFile(%s)", path);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000266 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 return INVALID_OPERATION;
268 }
269 if (mIsOutputFileSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000270 ALOGE("output file has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 return INVALID_OPERATION;
272 }
273 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000274 ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 return INVALID_OPERATION;
276 }
277
278 status_t ret = mMediaRecorder->setOutputFile(path);
279 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +0100280 ALOGV("setOutputFile failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800282 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 }
284 mIsOutputFileSet = true;
285 return ret;
286}
287
288status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
289{
Steve Block06ade6a2011-10-20 11:56:00 +0100290 ALOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000292 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 return INVALID_OPERATION;
294 }
295 if (mIsOutputFileSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000296 ALOGE("output file has already been set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 return INVALID_OPERATION;
298 }
299 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000300 ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 return INVALID_OPERATION;
302 }
303
James Dongbafa7ea2011-02-22 12:34:02 -0800304 // It appears that if an invalid file descriptor is passed through
305 // binder calls, the server-side of the inter-process function call
306 // is skipped. As a result, the check at the server-side to catch
307 // the invalid file descritpor never gets invoked. This is to workaround
308 // this issue by checking the file descriptor first before passing
309 // it through binder call.
310 if (fd < 0) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000311 ALOGE("Invalid file descriptor: %d", fd);
James Dongbafa7ea2011-02-22 12:34:02 -0800312 return BAD_VALUE;
313 }
314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
316 if (OK != ret) {
Steve Block06ade6a2011-10-20 11:56:00 +0100317 ALOGV("setOutputFile failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800319 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 }
321 mIsOutputFileSet = true;
322 return ret;
323}
324
325status_t MediaRecorder::setVideoSize(int width, int height)
326{
Steve Block06ade6a2011-10-20 11:56:00 +0100327 ALOGV("setVideoSize(%d, %d)", width, height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000329 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 return INVALID_OPERATION;
331 }
332 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000333 ALOGE("setVideoSize called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 return INVALID_OPERATION;
335 }
336 if (!mIsVideoSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000337 ALOGE("Cannot set video size without setting video source first");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 return INVALID_OPERATION;
339 }
340
341 status_t ret = mMediaRecorder->setVideoSize(width, height);
342 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000343 ALOGE("setVideoSize failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800345 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 }
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 return ret;
349}
350
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700351// Query a SurfaceMediaSurface through the Mediaserver, over the
352// binder interface. This is used by the Filter Framework (MeidaEncoder)
353// to get an <ISurfaceTexture> object to hook up to ANativeWindow.
354sp<ISurfaceTexture> MediaRecorder::
355 querySurfaceMediaSourceFromMediaServer()
356{
357 Mutex::Autolock _l(mLock);
358 mSurfaceMediaSource =
359 mMediaRecorder->querySurfaceMediaSource();
360 if (mSurfaceMediaSource == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000361 ALOGE("SurfaceMediaSource could not be initialized!");
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700362 }
363 return mSurfaceMediaSource;
364}
365
366
367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
369{
Steve Block06ade6a2011-10-20 11:56:00 +0100370 ALOGV("setVideoFrameRate(%d)", frames_per_second);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000372 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 return INVALID_OPERATION;
374 }
375 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000376 ALOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 return INVALID_OPERATION;
378 }
379 if (!mIsVideoSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000380 ALOGE("Cannot set video frame rate without setting video source first");
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700381 return INVALID_OPERATION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 }
383
384 status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second);
385 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000386 ALOGE("setVideoFrameRate failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800388 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 }
390 return ret;
391}
392
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700393status_t MediaRecorder::setParameters(const String8& params) {
Steve Block06ade6a2011-10-20 11:56:00 +0100394 ALOGV("setParameters(%s)", params.string());
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700395 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000396 ALOGE("media recorder is not initialized yet");
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700397 return INVALID_OPERATION;
398 }
399
James Dong61701ce2010-02-25 18:41:46 -0800400 bool isInvalidState = (mCurrentState &
401 (MEDIA_RECORDER_PREPARED |
402 MEDIA_RECORDER_RECORDING |
403 MEDIA_RECORDER_ERROR));
404 if (isInvalidState) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000405 ALOGE("setParameters is called in an invalid state: %d", mCurrentState);
James Dong61701ce2010-02-25 18:41:46 -0800406 return INVALID_OPERATION;
407 }
408
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700409 status_t ret = mMediaRecorder->setParameters(params);
410 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000411 ALOGE("setParameters(%s) failed: %d", params.string(), ret);
The Android Open Source Project10592532009-03-18 17:39:46 -0700412 // Do not change our current state to MEDIA_RECORDER_ERROR, failures
413 // of the only currently supported parameters, "max-duration" and
414 // "max-filesize" are _not_ fatal.
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700415 }
416
417 return ret;
418}
419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420status_t MediaRecorder::prepare()
421{
Steve Block06ade6a2011-10-20 11:56:00 +0100422 ALOGV("prepare");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000424 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 return INVALID_OPERATION;
426 }
427 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000428 ALOGE("prepare called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 return INVALID_OPERATION;
430 }
431 if (mIsAudioSourceSet != mIsAudioEncoderSet) {
432 if (mIsAudioSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000433 ALOGE("audio source is set, but audio encoder is not set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 } else { // must not happen, since setAudioEncoder checks this already
Steve Blockc6aacce2012-01-06 19:20:56 +0000435 ALOGE("audio encoder is set, but audio source is not set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 }
437 return INVALID_OPERATION;
438 }
439
440 if (mIsVideoSourceSet != mIsVideoEncoderSet) {
441 if (mIsVideoSourceSet) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000442 ALOGE("video source is set, but video encoder is not set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 } else { // must not happen, since setVideoEncoder checks this already
Steve Blockc6aacce2012-01-06 19:20:56 +0000444 ALOGE("video encoder is set, but video source is not set");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 }
446 return INVALID_OPERATION;
447 }
448
449 status_t ret = mMediaRecorder->prepare();
450 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000451 ALOGE("prepare failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800453 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 }
455 mCurrentState = MEDIA_RECORDER_PREPARED;
456 return ret;
457}
458
459status_t MediaRecorder::getMaxAmplitude(int* max)
460{
Steve Block06ade6a2011-10-20 11:56:00 +0100461 ALOGV("getMaxAmplitude");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 if(mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000463 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 return INVALID_OPERATION;
465 }
466 if (mCurrentState & MEDIA_RECORDER_ERROR) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000467 ALOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468 return INVALID_OPERATION;
469 }
470
471 status_t ret = mMediaRecorder->getMaxAmplitude(max);
472 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000473 ALOGE("getMaxAmplitude failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800475 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 }
477 return ret;
478}
479
480status_t MediaRecorder::start()
481{
Steve Block06ade6a2011-10-20 11:56:00 +0100482 ALOGV("start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 if (mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000484 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 return INVALID_OPERATION;
486 }
487 if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000488 ALOGE("start called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 return INVALID_OPERATION;
490 }
491
492 status_t ret = mMediaRecorder->start();
493 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000494 ALOGE("start failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800496 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 }
498 mCurrentState = MEDIA_RECORDER_RECORDING;
499 return ret;
500}
501
502status_t MediaRecorder::stop()
503{
Steve Block06ade6a2011-10-20 11:56:00 +0100504 ALOGV("stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 if (mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000506 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 return INVALID_OPERATION;
508 }
509 if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000510 ALOGE("stop called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 return INVALID_OPERATION;
512 }
513
514 status_t ret = mMediaRecorder->stop();
515 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000516 ALOGE("stop failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800518 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 }
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700520
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700521 // FIXME:
522 // stop and reset are semantically different.
523 // We treat them the same for now, and will change this in the future.
524 doCleanUp();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 mCurrentState = MEDIA_RECORDER_IDLE;
526 return ret;
527}
528
529// Reset should be OK in any state
530status_t MediaRecorder::reset()
531{
Steve Block06ade6a2011-10-20 11:56:00 +0100532 ALOGV("reset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 if (mMediaRecorder == NULL) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000534 ALOGE("media recorder is not initialized yet");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 return INVALID_OPERATION;
536 }
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 doCleanUp();
539 status_t ret = UNKNOWN_ERROR;
540 switch(mCurrentState) {
541 case MEDIA_RECORDER_IDLE:
542 ret = OK;
543 break;
544
545 case MEDIA_RECORDER_RECORDING:
546 case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
547 case MEDIA_RECORDER_PREPARED:
548 case MEDIA_RECORDER_ERROR: {
549 ret = doReset();
550 if (OK != ret) {
551 return ret; // No need to continue
552 }
553 } // Intentional fall through
554 case MEDIA_RECORDER_INITIALIZED:
555 ret = close();
556 break;
557
558 default: {
Steve Blockc6aacce2012-01-06 19:20:56 +0000559 ALOGE("Unexpected non-existing state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 break;
561 }
562 }
563 return ret;
564}
565
566status_t MediaRecorder::close()
567{
Steve Block06ade6a2011-10-20 11:56:00 +0100568 ALOGV("close");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000570 ALOGE("close called in an invalid state: %d", mCurrentState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 return INVALID_OPERATION;
572 }
573 status_t ret = mMediaRecorder->close();
574 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000575 ALOGE("close failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 mCurrentState = MEDIA_RECORDER_ERROR;
577 return UNKNOWN_ERROR;
578 } else {
579 mCurrentState = MEDIA_RECORDER_IDLE;
580 }
581 return ret;
582}
583
584status_t MediaRecorder::doReset()
585{
Steve Block06ade6a2011-10-20 11:56:00 +0100586 ALOGV("doReset");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 status_t ret = mMediaRecorder->reset();
588 if (OK != ret) {
Steve Blockc6aacce2012-01-06 19:20:56 +0000589 ALOGE("doReset failed: %d", ret);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800591 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 } else {
593 mCurrentState = MEDIA_RECORDER_INITIALIZED;
594 }
595 return ret;
596}
597
598void MediaRecorder::doCleanUp()
599{
Steve Block06ade6a2011-10-20 11:56:00 +0100600 ALOGV("doCleanUp");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 mIsAudioSourceSet = false;
602 mIsVideoSourceSet = false;
603 mIsAudioEncoderSet = false;
604 mIsVideoEncoderSet = false;
605 mIsOutputFileSet = false;
606}
607
608// Release should be OK in any state
609status_t MediaRecorder::release()
610{
Steve Block06ade6a2011-10-20 11:56:00 +0100611 ALOGV("release");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 if (mMediaRecorder != NULL) {
613 return mMediaRecorder->release();
614 }
615 return INVALID_OPERATION;
616}
617
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700618MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619{
Steve Block06ade6a2011-10-20 11:56:00 +0100620 ALOGV("constructor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621
James Dong34bbc222010-01-15 18:13:58 -0800622 const sp<IMediaPlayerService>& service(getMediaPlayerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 if (service != NULL) {
624 mMediaRecorder = service->createMediaRecorder(getpid());
625 }
626 if (mMediaRecorder != NULL) {
627 mCurrentState = MEDIA_RECORDER_IDLE;
628 }
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700629
630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 doCleanUp();
632}
633
634status_t MediaRecorder::initCheck()
635{
636 return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
637}
638
639MediaRecorder::~MediaRecorder()
640{
Steve Block06ade6a2011-10-20 11:56:00 +0100641 ALOGV("destructor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800642 if (mMediaRecorder != NULL) {
643 mMediaRecorder.clear();
644 }
Pannag Sanketi897e27b2011-07-01 17:39:39 -0700645
646 if (mSurfaceMediaSource != NULL) {
647 mSurfaceMediaSource.clear();
648 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649}
650
651status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
652{
Steve Block06ade6a2011-10-20 11:56:00 +0100653 ALOGV("setListener");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 Mutex::Autolock _l(mLock);
655 mListener = listener;
656
657 return NO_ERROR;
658}
659
660void MediaRecorder::notify(int msg, int ext1, int ext2)
661{
Steve Block06ade6a2011-10-20 11:56:00 +0100662 ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663
664 sp<MediaRecorderListener> listener;
665 mLock.lock();
666 listener = mListener;
667 mLock.unlock();
668
669 if (listener != NULL) {
670 Mutex::Autolock _l(mNotifyLock);
Steve Block06ade6a2011-10-20 11:56:00 +0100671 ALOGV("callback application");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 listener->notify(msg, ext1, ext2);
Steve Block06ade6a2011-10-20 11:56:00 +0100673 ALOGV("back from callback");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 }
675}
676
James Dong34bbc222010-01-15 18:13:58 -0800677void MediaRecorder::died()
678{
Steve Block06ade6a2011-10-20 11:56:00 +0100679 ALOGV("died");
James Dong34bbc222010-01-15 18:13:58 -0800680 notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
681}
682
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800683}; // namespace android