blob: 0100a17553271322501ca13ac6b8421fcaa13c9b [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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
29namespace android {
30
31status_t MediaRecorder::setCamera(const sp<ICamera>& camera)
32{
33 LOGV("setCamera(%p)", camera.get());
34 if(mMediaRecorder == NULL) {
35 LOGE("media recorder is not initialized yet");
36 return INVALID_OPERATION;
37 }
38 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
39 LOGE("setCamera called in an invalid state(%d)", mCurrentState);
40 return INVALID_OPERATION;
41 }
42
43 status_t ret = mMediaRecorder->setCamera(camera);
44 if (OK != ret) {
45 LOGV("setCamera failed: %d", ret);
46 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{
54 LOGV("setPreviewSurface(%p)", surface.get());
55 if(mMediaRecorder == NULL) {
56 LOGE("media recorder is not initialized yet");
57 return INVALID_OPERATION;
58 }
59 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
60 LOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState);
61 return INVALID_OPERATION;
62 }
63 if (!mIsVideoSourceSet) {
64 LOGE("try to set preview surface without setting the video source first");
65 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) {
70 LOGV("setPreviewSurface failed: %d", ret);
71 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{
79 LOGV("init");
80 if(mMediaRecorder == NULL) {
81 LOGE("media recorder is not initialized yet");
82 return INVALID_OPERATION;
83 }
84 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
85 LOGE("init called in an invalid state(%d)", mCurrentState);
86 return INVALID_OPERATION;
87 }
88
89 status_t ret = mMediaRecorder->init();
90 if (OK != ret) {
91 LOGV("init failed: %d", ret);
92 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) {
98 LOGV("setListener failed: %d", ret);
99 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{
109 LOGV("setVideoSource(%d)", vs);
110 if(mMediaRecorder == NULL) {
111 LOGE("media recorder is not initialized yet");
112 return INVALID_OPERATION;
113 }
114 if (mIsVideoSourceSet) {
115 LOGE("video source has already been set");
116 return INVALID_OPERATION;
117 }
118 if (mCurrentState & MEDIA_RECORDER_IDLE) {
119 LOGV("Call init() since the media recorder is not initialized yet");
120 status_t ret = init();
121 if (OK != ret) {
122 return ret;
123 }
124 }
125 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
126 LOGE("setVideoSource called in an invalid state(%d)", mCurrentState);
127 return INVALID_OPERATION;
128 }
129
130 status_t ret = mMediaRecorder->setVideoSource(vs);
131 if (OK != ret) {
132 LOGV("setVideoSource failed: %d", ret);
133 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800134 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 }
136 mIsVideoSourceSet = true;
137 return ret;
138}
139
140status_t MediaRecorder::setAudioSource(int as)
141{
142 LOGV("setAudioSource(%d)", as);
143 if(mMediaRecorder == NULL) {
144 LOGE("media recorder is not initialized yet");
145 return INVALID_OPERATION;
146 }
147 if (mCurrentState & MEDIA_RECORDER_IDLE) {
148 LOGV("Call init() since the media recorder is not initialized yet");
149 status_t ret = init();
150 if (OK != ret) {
151 return ret;
152 }
153 }
154 if (mIsAudioSourceSet) {
155 LOGE("audio source has already been set");
156 return INVALID_OPERATION;
157 }
158 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
159 LOGE("setAudioSource called in an invalid state(%d)", mCurrentState);
160 return INVALID_OPERATION;
161 }
162
163 status_t ret = mMediaRecorder->setAudioSource(as);
164 if (OK != ret) {
165 LOGV("setAudioSource failed: %d", ret);
166 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800167 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 }
169 mIsAudioSourceSet = true;
170 return ret;
171}
172
173status_t MediaRecorder::setOutputFormat(int of)
174{
175 LOGV("setOutputFormat(%d)", of);
176 if(mMediaRecorder == NULL) {
177 LOGE("media recorder is not initialized yet");
178 return INVALID_OPERATION;
179 }
180 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
181 LOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
182 return INVALID_OPERATION;
183 }
Andreas Huber9adf4662010-10-12 14:17:45 -0700184 if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START && of != OUTPUT_FORMAT_RTP_AVP && of != OUTPUT_FORMAT_MPEG2TS) { //first non-video output format
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 LOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of);
186 return INVALID_OPERATION;
187 }
188
189 status_t ret = mMediaRecorder->setOutputFormat(of);
190 if (OK != ret) {
191 LOGE("setOutputFormat failed: %d", ret);
192 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800193 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 }
195 mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED;
196 return ret;
197}
198
199status_t MediaRecorder::setVideoEncoder(int ve)
200{
201 LOGV("setVideoEncoder(%d)", ve);
202 if(mMediaRecorder == NULL) {
203 LOGE("media recorder is not initialized yet");
204 return INVALID_OPERATION;
205 }
206 if (!mIsVideoSourceSet) {
207 LOGE("try to set the video encoder without setting the video source first");
208 return INVALID_OPERATION;
209 }
210 if (mIsVideoEncoderSet) {
211 LOGE("video encoder has already been set");
212 return INVALID_OPERATION;
213 }
214 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
215 LOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);
216 return INVALID_OPERATION;
217 }
218
219 status_t ret = mMediaRecorder->setVideoEncoder(ve);
220 if (OK != ret) {
221 LOGV("setVideoEncoder failed: %d", ret);
222 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800223 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 }
225 mIsVideoEncoderSet = true;
226 return ret;
227}
228
229status_t MediaRecorder::setAudioEncoder(int ae)
230{
231 LOGV("setAudioEncoder(%d)", ae);
232 if(mMediaRecorder == NULL) {
233 LOGE("media recorder is not initialized yet");
234 return INVALID_OPERATION;
235 }
236 if (!mIsAudioSourceSet) {
237 LOGE("try to set the audio encoder without setting the audio source first");
238 return INVALID_OPERATION;
239 }
240 if (mIsAudioEncoderSet) {
241 LOGE("audio encoder has already been set");
242 return INVALID_OPERATION;
243 }
244 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
245 LOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState);
246 return INVALID_OPERATION;
247 }
248
249 status_t ret = mMediaRecorder->setAudioEncoder(ae);
250 if (OK != ret) {
251 LOGV("setAudioEncoder failed: %d", ret);
252 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800253 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 }
255 mIsAudioEncoderSet = true;
256 return ret;
257}
258
259status_t MediaRecorder::setOutputFile(const char* path)
260{
261 LOGV("setOutputFile(%s)", path);
262 if(mMediaRecorder == NULL) {
263 LOGE("media recorder is not initialized yet");
264 return INVALID_OPERATION;
265 }
266 if (mIsOutputFileSet) {
267 LOGE("output file has already been set");
268 return INVALID_OPERATION;
269 }
270 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
271 LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
272 return INVALID_OPERATION;
273 }
274
275 status_t ret = mMediaRecorder->setOutputFile(path);
276 if (OK != ret) {
277 LOGV("setOutputFile failed: %d", ret);
278 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800279 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 }
281 mIsOutputFileSet = true;
282 return ret;
283}
284
285status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
286{
287 LOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length);
288 if(mMediaRecorder == NULL) {
289 LOGE("media recorder is not initialized yet");
290 return INVALID_OPERATION;
291 }
292 if (mIsOutputFileSet) {
293 LOGE("output file has already been set");
294 return INVALID_OPERATION;
295 }
296 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
297 LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
298 return INVALID_OPERATION;
299 }
300
James Dongbafa7ea2011-02-22 12:34:02 -0800301 // It appears that if an invalid file descriptor is passed through
302 // binder calls, the server-side of the inter-process function call
303 // is skipped. As a result, the check at the server-side to catch
304 // the invalid file descritpor never gets invoked. This is to workaround
305 // this issue by checking the file descriptor first before passing
306 // it through binder call.
307 if (fd < 0) {
308 LOGE("Invalid file descriptor: %d", fd);
309 return BAD_VALUE;
310 }
311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
313 if (OK != ret) {
314 LOGV("setOutputFile failed: %d", ret);
315 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800316 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 }
318 mIsOutputFileSet = true;
319 return ret;
320}
321
Nipun Kwatrab33a5ae2010-08-26 17:20:53 -0700322status_t MediaRecorder::setOutputFileAuxiliary(int fd)
323{
324 LOGV("setOutputFileAuxiliary(%d)", fd);
325 if(mMediaRecorder == NULL) {
326 LOGE("media recorder is not initialized yet");
327 return INVALID_OPERATION;
328 }
329 if (mIsAuxiliaryOutputFileSet) {
330 LOGE("output file has already been set");
331 return INVALID_OPERATION;
332 }
333 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
334 LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
335 return INVALID_OPERATION;
336 }
337
338 status_t ret = mMediaRecorder->setOutputFileAuxiliary(fd);
339 if (OK != ret) {
340 LOGV("setOutputFileAuxiliary failed: %d", ret);
341 mCurrentState = MEDIA_RECORDER_ERROR;
342 return ret;
343 }
344 mIsAuxiliaryOutputFileSet = true;
345 return ret;
346}
347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348status_t MediaRecorder::setVideoSize(int width, int height)
349{
350 LOGV("setVideoSize(%d, %d)", width, height);
351 if(mMediaRecorder == NULL) {
352 LOGE("media recorder is not initialized yet");
353 return INVALID_OPERATION;
354 }
355 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
356 LOGE("setVideoSize called in an invalid state: %d", mCurrentState);
357 return INVALID_OPERATION;
358 }
359 if (!mIsVideoSourceSet) {
360 LOGE("try to set video size without setting video source first");
361 return INVALID_OPERATION;
362 }
363
364 status_t ret = mMediaRecorder->setVideoSize(width, height);
365 if (OK != ret) {
366 LOGE("setVideoSize failed: %d", ret);
367 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800368 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 }
370 return ret;
371}
372
373status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
374{
375 LOGV("setVideoFrameRate(%d)", frames_per_second);
376 if(mMediaRecorder == NULL) {
377 LOGE("media recorder is not initialized yet");
378 return INVALID_OPERATION;
379 }
380 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
381 LOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState);
382 return INVALID_OPERATION;
383 }
384 if (!mIsVideoSourceSet) {
385 LOGE("try to set video frame rate without setting video source first");
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700386 return INVALID_OPERATION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 }
388
389 status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second);
390 if (OK != ret) {
391 LOGE("setVideoFrameRate failed: %d", ret);
392 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800393 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 }
395 return ret;
396}
397
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700398status_t MediaRecorder::setParameters(const String8& params) {
399 LOGV("setParameters(%s)", params.string());
400 if(mMediaRecorder == NULL) {
401 LOGE("media recorder is not initialized yet");
402 return INVALID_OPERATION;
403 }
404
James Dong61701ce2010-02-25 18:41:46 -0800405 bool isInvalidState = (mCurrentState &
406 (MEDIA_RECORDER_PREPARED |
407 MEDIA_RECORDER_RECORDING |
408 MEDIA_RECORDER_ERROR));
409 if (isInvalidState) {
410 LOGE("setParameters is called in an invalid state: %d", mCurrentState);
411 return INVALID_OPERATION;
412 }
413
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700414 status_t ret = mMediaRecorder->setParameters(params);
415 if (OK != ret) {
416 LOGE("setParameters(%s) failed: %d", params.string(), ret);
The Android Open Source Project10592532009-03-18 17:39:46 -0700417 // Do not change our current state to MEDIA_RECORDER_ERROR, failures
418 // of the only currently supported parameters, "max-duration" and
419 // "max-filesize" are _not_ fatal.
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700420 }
421
422 return ret;
423}
424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425status_t MediaRecorder::prepare()
426{
427 LOGV("prepare");
428 if(mMediaRecorder == NULL) {
429 LOGE("media recorder is not initialized yet");
430 return INVALID_OPERATION;
431 }
432 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
433 LOGE("prepare called in an invalid state: %d", mCurrentState);
434 return INVALID_OPERATION;
435 }
436 if (mIsAudioSourceSet != mIsAudioEncoderSet) {
437 if (mIsAudioSourceSet) {
438 LOGE("audio source is set, but audio encoder is not set");
439 } else { // must not happen, since setAudioEncoder checks this already
440 LOGE("audio encoder is set, but audio source is not set");
441 }
442 return INVALID_OPERATION;
443 }
444
445 if (mIsVideoSourceSet != mIsVideoEncoderSet) {
446 if (mIsVideoSourceSet) {
447 LOGE("video source is set, but video encoder is not set");
448 } else { // must not happen, since setVideoEncoder checks this already
449 LOGE("video encoder is set, but video source is not set");
450 }
451 return INVALID_OPERATION;
452 }
453
454 status_t ret = mMediaRecorder->prepare();
455 if (OK != ret) {
456 LOGE("prepare failed: %d", ret);
457 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800458 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 }
460 mCurrentState = MEDIA_RECORDER_PREPARED;
461 return ret;
462}
463
464status_t MediaRecorder::getMaxAmplitude(int* max)
465{
466 LOGV("getMaxAmplitude");
467 if(mMediaRecorder == NULL) {
468 LOGE("media recorder is not initialized yet");
469 return INVALID_OPERATION;
470 }
471 if (mCurrentState & MEDIA_RECORDER_ERROR) {
472 LOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState);
473 return INVALID_OPERATION;
474 }
475
476 status_t ret = mMediaRecorder->getMaxAmplitude(max);
477 if (OK != ret) {
478 LOGE("getMaxAmplitude failed: %d", ret);
479 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800480 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 }
482 return ret;
483}
484
485status_t MediaRecorder::start()
486{
487 LOGV("start");
488 if (mMediaRecorder == NULL) {
489 LOGE("media recorder is not initialized yet");
490 return INVALID_OPERATION;
491 }
492 if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
493 LOGE("start called in an invalid state: %d", mCurrentState);
494 return INVALID_OPERATION;
495 }
496
497 status_t ret = mMediaRecorder->start();
498 if (OK != ret) {
499 LOGE("start failed: %d", ret);
500 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800501 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 }
503 mCurrentState = MEDIA_RECORDER_RECORDING;
504 return ret;
505}
506
507status_t MediaRecorder::stop()
508{
509 LOGV("stop");
510 if (mMediaRecorder == NULL) {
511 LOGE("media recorder is not initialized yet");
512 return INVALID_OPERATION;
513 }
514 if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
515 LOGE("stop called in an invalid state: %d", mCurrentState);
516 return INVALID_OPERATION;
517 }
518
519 status_t ret = mMediaRecorder->stop();
520 if (OK != ret) {
521 LOGE("stop failed: %d", ret);
522 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800523 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 }
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700525
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700526 // FIXME:
527 // stop and reset are semantically different.
528 // We treat them the same for now, and will change this in the future.
529 doCleanUp();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 mCurrentState = MEDIA_RECORDER_IDLE;
531 return ret;
532}
533
534// Reset should be OK in any state
535status_t MediaRecorder::reset()
536{
537 LOGV("reset");
538 if (mMediaRecorder == NULL) {
539 LOGE("media recorder is not initialized yet");
540 return INVALID_OPERATION;
541 }
Jianhong Jiang2bcda902009-06-08 08:50:42 -0700542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 doCleanUp();
544 status_t ret = UNKNOWN_ERROR;
545 switch(mCurrentState) {
546 case MEDIA_RECORDER_IDLE:
547 ret = OK;
548 break;
549
550 case MEDIA_RECORDER_RECORDING:
551 case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
552 case MEDIA_RECORDER_PREPARED:
553 case MEDIA_RECORDER_ERROR: {
554 ret = doReset();
555 if (OK != ret) {
556 return ret; // No need to continue
557 }
558 } // Intentional fall through
559 case MEDIA_RECORDER_INITIALIZED:
560 ret = close();
561 break;
562
563 default: {
564 LOGE("Unexpected non-existing state: %d", mCurrentState);
565 break;
566 }
567 }
568 return ret;
569}
570
571status_t MediaRecorder::close()
572{
573 LOGV("close");
574 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
575 LOGE("close called in an invalid state: %d", mCurrentState);
576 return INVALID_OPERATION;
577 }
578 status_t ret = mMediaRecorder->close();
579 if (OK != ret) {
580 LOGE("close failed: %d", ret);
581 mCurrentState = MEDIA_RECORDER_ERROR;
582 return UNKNOWN_ERROR;
583 } else {
584 mCurrentState = MEDIA_RECORDER_IDLE;
585 }
586 return ret;
587}
588
589status_t MediaRecorder::doReset()
590{
591 LOGV("doReset");
592 status_t ret = mMediaRecorder->reset();
593 if (OK != ret) {
594 LOGE("doReset failed: %d", ret);
595 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800596 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 } else {
598 mCurrentState = MEDIA_RECORDER_INITIALIZED;
599 }
600 return ret;
601}
602
603void MediaRecorder::doCleanUp()
604{
605 LOGV("doCleanUp");
606 mIsAudioSourceSet = false;
607 mIsVideoSourceSet = false;
608 mIsAudioEncoderSet = false;
609 mIsVideoEncoderSet = false;
610 mIsOutputFileSet = false;
Nipun Kwatrab33a5ae2010-08-26 17:20:53 -0700611 mIsAuxiliaryOutputFileSet = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612}
613
614// Release should be OK in any state
615status_t MediaRecorder::release()
616{
617 LOGV("release");
618 if (mMediaRecorder != NULL) {
619 return mMediaRecorder->release();
620 }
621 return INVALID_OPERATION;
622}
623
624MediaRecorder::MediaRecorder()
625{
626 LOGV("constructor");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627
James Dong34bbc222010-01-15 18:13:58 -0800628 const sp<IMediaPlayerService>& service(getMediaPlayerService());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 if (service != NULL) {
630 mMediaRecorder = service->createMediaRecorder(getpid());
631 }
632 if (mMediaRecorder != NULL) {
633 mCurrentState = MEDIA_RECORDER_IDLE;
634 }
635 doCleanUp();
636}
637
638status_t MediaRecorder::initCheck()
639{
640 return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
641}
642
643MediaRecorder::~MediaRecorder()
644{
645 LOGV("destructor");
646 if (mMediaRecorder != NULL) {
647 mMediaRecorder.clear();
648 }
649}
650
651status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
652{
653 LOGV("setListener");
654 Mutex::Autolock _l(mLock);
655 mListener = listener;
656
657 return NO_ERROR;
658}
659
660void MediaRecorder::notify(int msg, int ext1, int ext2)
661{
662 LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
663
664 sp<MediaRecorderListener> listener;
665 mLock.lock();
666 listener = mListener;
667 mLock.unlock();
668
669 if (listener != NULL) {
670 Mutex::Autolock _l(mNotifyLock);
671 LOGV("callback application");
672 listener->notify(msg, ext1, ext2);
673 LOGV("back from callback");
674 }
675}
676
James Dong34bbc222010-01-15 18:13:58 -0800677void MediaRecorder::died()
678{
679 LOGV("died");
680 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