1 /*
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>
21 #include <ui/Surface.h>
22 #include <media/mediarecorder.h>
23 #include <binder/IServiceManager.h>
24 #include <utils/String8.h>
25 #include <media/IMediaPlayerService.h>
26 #include <media/IMediaRecorder.h>
27
28 namespace android {
29
setCamera(const sp<ICamera> & camera)30 status_t MediaRecorder::setCamera(const sp<ICamera>& camera)
31 {
32 LOGV("setCamera(%p)", camera.get());
33 if(mMediaRecorder == NULL) {
34 LOGE("media recorder is not initialized yet");
35 return INVALID_OPERATION;
36 }
37 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
38 LOGE("setCamera called in an invalid state(%d)", mCurrentState);
39 return INVALID_OPERATION;
40 }
41
42 status_t ret = mMediaRecorder->setCamera(camera);
43 if (OK != ret) {
44 LOGV("setCamera failed: %d", ret);
45 mCurrentState = MEDIA_RECORDER_ERROR;
46 return ret;
47 }
48 return ret;
49 }
50
setPreviewSurface(const sp<Surface> & surface)51 status_t MediaRecorder::setPreviewSurface(const sp<Surface>& surface)
52 {
53 LOGV("setPreviewSurface(%p)", surface.get());
54 if(mMediaRecorder == NULL) {
55 LOGE("media recorder is not initialized yet");
56 return INVALID_OPERATION;
57 }
58 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
59 LOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState);
60 return INVALID_OPERATION;
61 }
62 if (!mIsVideoSourceSet) {
63 LOGE("try to set preview surface without setting the video source first");
64 return INVALID_OPERATION;
65 }
66
67 status_t ret = mMediaRecorder->setPreviewSurface(surface->getISurface());
68 if (OK != ret) {
69 LOGV("setPreviewSurface failed: %d", ret);
70 mCurrentState = MEDIA_RECORDER_ERROR;
71 return ret;
72 }
73 return ret;
74 }
75
init()76 status_t MediaRecorder::init()
77 {
78 LOGV("init");
79 if(mMediaRecorder == NULL) {
80 LOGE("media recorder is not initialized yet");
81 return INVALID_OPERATION;
82 }
83 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
84 LOGE("init called in an invalid state(%d)", mCurrentState);
85 return INVALID_OPERATION;
86 }
87
88 status_t ret = mMediaRecorder->init();
89 if (OK != ret) {
90 LOGV("init failed: %d", ret);
91 mCurrentState = MEDIA_RECORDER_ERROR;
92 return ret;
93 }
94
95 ret = mMediaRecorder->setListener(this);
96 if (OK != ret) {
97 LOGV("setListener failed: %d", ret);
98 mCurrentState = MEDIA_RECORDER_ERROR;
99 return ret;
100 }
101
102 mCurrentState = MEDIA_RECORDER_INITIALIZED;
103 return ret;
104 }
105
setVideoSource(int vs)106 status_t MediaRecorder::setVideoSource(int vs)
107 {
108 LOGV("setVideoSource(%d)", vs);
109 if(mMediaRecorder == NULL) {
110 LOGE("media recorder is not initialized yet");
111 return INVALID_OPERATION;
112 }
113 if (mIsVideoSourceSet) {
114 LOGE("video source has already been set");
115 return INVALID_OPERATION;
116 }
117 if (mCurrentState & MEDIA_RECORDER_IDLE) {
118 LOGV("Call init() since the media recorder is not initialized yet");
119 status_t ret = init();
120 if (OK != ret) {
121 return ret;
122 }
123 }
124 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
125 LOGE("setVideoSource called in an invalid state(%d)", mCurrentState);
126 return INVALID_OPERATION;
127 }
128
129 status_t ret = mMediaRecorder->setVideoSource(vs);
130 if (OK != ret) {
131 LOGV("setVideoSource failed: %d", ret);
132 mCurrentState = MEDIA_RECORDER_ERROR;
133 return ret;
134 }
135 mIsVideoSourceSet = true;
136 return ret;
137 }
138
setAudioSource(int as)139 status_t MediaRecorder::setAudioSource(int as)
140 {
141 LOGV("setAudioSource(%d)", as);
142 if(mMediaRecorder == NULL) {
143 LOGE("media recorder is not initialized yet");
144 return INVALID_OPERATION;
145 }
146 if (mCurrentState & MEDIA_RECORDER_IDLE) {
147 LOGV("Call init() since the media recorder is not initialized yet");
148 status_t ret = init();
149 if (OK != ret) {
150 return ret;
151 }
152 }
153 if (mIsAudioSourceSet) {
154 LOGE("audio source has already been set");
155 return INVALID_OPERATION;
156 }
157 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
158 LOGE("setAudioSource called in an invalid state(%d)", mCurrentState);
159 return INVALID_OPERATION;
160 }
161
162 status_t ret = mMediaRecorder->setAudioSource(as);
163 if (OK != ret) {
164 LOGV("setAudioSource failed: %d", ret);
165 mCurrentState = MEDIA_RECORDER_ERROR;
166 return ret;
167 }
168 mIsAudioSourceSet = true;
169 return ret;
170 }
171
setOutputFormat(int of)172 status_t MediaRecorder::setOutputFormat(int of)
173 {
174 LOGV("setOutputFormat(%d)", of);
175 if(mMediaRecorder == NULL) {
176 LOGE("media recorder is not initialized yet");
177 return INVALID_OPERATION;
178 }
179 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
180 LOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
181 return INVALID_OPERATION;
182 }
183 if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START) { //first non-video output format
184 LOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of);
185 return INVALID_OPERATION;
186 }
187
188 status_t ret = mMediaRecorder->setOutputFormat(of);
189 if (OK != ret) {
190 LOGE("setOutputFormat failed: %d", ret);
191 mCurrentState = MEDIA_RECORDER_ERROR;
192 return ret;
193 }
194 mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED;
195 return ret;
196 }
197
setVideoEncoder(int ve)198 status_t MediaRecorder::setVideoEncoder(int ve)
199 {
200 LOGV("setVideoEncoder(%d)", ve);
201 if(mMediaRecorder == NULL) {
202 LOGE("media recorder is not initialized yet");
203 return INVALID_OPERATION;
204 }
205 if (!mIsVideoSourceSet) {
206 LOGE("try to set the video encoder without setting the video source first");
207 return INVALID_OPERATION;
208 }
209 if (mIsVideoEncoderSet) {
210 LOGE("video encoder has already been set");
211 return INVALID_OPERATION;
212 }
213 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
214 LOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);
215 return INVALID_OPERATION;
216 }
217
218 status_t ret = mMediaRecorder->setVideoEncoder(ve);
219 if (OK != ret) {
220 LOGV("setVideoEncoder failed: %d", ret);
221 mCurrentState = MEDIA_RECORDER_ERROR;
222 return ret;
223 }
224 mIsVideoEncoderSet = true;
225 return ret;
226 }
227
setAudioEncoder(int ae)228 status_t MediaRecorder::setAudioEncoder(int ae)
229 {
230 LOGV("setAudioEncoder(%d)", ae);
231 if(mMediaRecorder == NULL) {
232 LOGE("media recorder is not initialized yet");
233 return INVALID_OPERATION;
234 }
235 if (!mIsAudioSourceSet) {
236 LOGE("try to set the audio encoder without setting the audio source first");
237 return INVALID_OPERATION;
238 }
239 if (mIsAudioEncoderSet) {
240 LOGE("audio encoder has already been set");
241 return INVALID_OPERATION;
242 }
243 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
244 LOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState);
245 return INVALID_OPERATION;
246 }
247
248 status_t ret = mMediaRecorder->setAudioEncoder(ae);
249 if (OK != ret) {
250 LOGV("setAudioEncoder failed: %d", ret);
251 mCurrentState = MEDIA_RECORDER_ERROR;
252 return ret;
253 }
254 mIsAudioEncoderSet = true;
255 return ret;
256 }
257
setOutputFile(const char * path)258 status_t MediaRecorder::setOutputFile(const char* path)
259 {
260 LOGV("setOutputFile(%s)", path);
261 if(mMediaRecorder == NULL) {
262 LOGE("media recorder is not initialized yet");
263 return INVALID_OPERATION;
264 }
265 if (mIsOutputFileSet) {
266 LOGE("output file has already been set");
267 return INVALID_OPERATION;
268 }
269 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
270 LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
271 return INVALID_OPERATION;
272 }
273
274 status_t ret = mMediaRecorder->setOutputFile(path);
275 if (OK != ret) {
276 LOGV("setOutputFile failed: %d", ret);
277 mCurrentState = MEDIA_RECORDER_ERROR;
278 return ret;
279 }
280 mIsOutputFileSet = true;
281 return ret;
282 }
283
setOutputFile(int fd,int64_t offset,int64_t length)284 status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
285 {
286 LOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length);
287 if(mMediaRecorder == NULL) {
288 LOGE("media recorder is not initialized yet");
289 return INVALID_OPERATION;
290 }
291 if (mIsOutputFileSet) {
292 LOGE("output file has already been set");
293 return INVALID_OPERATION;
294 }
295 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
296 LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
297 return INVALID_OPERATION;
298 }
299
300 status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
301 if (OK != ret) {
302 LOGV("setOutputFile failed: %d", ret);
303 mCurrentState = MEDIA_RECORDER_ERROR;
304 return ret;
305 }
306 mIsOutputFileSet = true;
307 return ret;
308 }
309
setVideoSize(int width,int height)310 status_t MediaRecorder::setVideoSize(int width, int height)
311 {
312 LOGV("setVideoSize(%d, %d)", width, height);
313 if(mMediaRecorder == NULL) {
314 LOGE("media recorder is not initialized yet");
315 return INVALID_OPERATION;
316 }
317 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
318 LOGE("setVideoSize called in an invalid state: %d", mCurrentState);
319 return INVALID_OPERATION;
320 }
321 if (!mIsVideoSourceSet) {
322 LOGE("try to set video size without setting video source first");
323 return INVALID_OPERATION;
324 }
325
326 status_t ret = mMediaRecorder->setVideoSize(width, height);
327 if (OK != ret) {
328 LOGE("setVideoSize failed: %d", ret);
329 mCurrentState = MEDIA_RECORDER_ERROR;
330 return ret;
331 }
332 return ret;
333 }
334
setVideoFrameRate(int frames_per_second)335 status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
336 {
337 LOGV("setVideoFrameRate(%d)", frames_per_second);
338 if(mMediaRecorder == NULL) {
339 LOGE("media recorder is not initialized yet");
340 return INVALID_OPERATION;
341 }
342 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
343 LOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState);
344 return INVALID_OPERATION;
345 }
346 if (!mIsVideoSourceSet) {
347 LOGE("try to set video frame rate without setting video source first");
348 return INVALID_OPERATION;
349 }
350
351 status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second);
352 if (OK != ret) {
353 LOGE("setVideoFrameRate failed: %d", ret);
354 mCurrentState = MEDIA_RECORDER_ERROR;
355 return ret;
356 }
357 return ret;
358 }
359
setParameters(const String8 & params)360 status_t MediaRecorder::setParameters(const String8& params) {
361 LOGV("setParameters(%s)", params.string());
362 if(mMediaRecorder == NULL) {
363 LOGE("media recorder is not initialized yet");
364 return INVALID_OPERATION;
365 }
366
367 status_t ret = mMediaRecorder->setParameters(params);
368 if (OK != ret) {
369 LOGE("setParameters(%s) failed: %d", params.string(), ret);
370 // Do not change our current state to MEDIA_RECORDER_ERROR, failures
371 // of the only currently supported parameters, "max-duration" and
372 // "max-filesize" are _not_ fatal.
373 }
374
375 return ret;
376 }
377
prepare()378 status_t MediaRecorder::prepare()
379 {
380 LOGV("prepare");
381 if(mMediaRecorder == NULL) {
382 LOGE("media recorder is not initialized yet");
383 return INVALID_OPERATION;
384 }
385 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
386 LOGE("prepare called in an invalid state: %d", mCurrentState);
387 return INVALID_OPERATION;
388 }
389 if (mIsAudioSourceSet != mIsAudioEncoderSet) {
390 if (mIsAudioSourceSet) {
391 LOGE("audio source is set, but audio encoder is not set");
392 } else { // must not happen, since setAudioEncoder checks this already
393 LOGE("audio encoder is set, but audio source is not set");
394 }
395 return INVALID_OPERATION;
396 }
397
398 if (mIsVideoSourceSet != mIsVideoEncoderSet) {
399 if (mIsVideoSourceSet) {
400 LOGE("video source is set, but video encoder is not set");
401 } else { // must not happen, since setVideoEncoder checks this already
402 LOGE("video encoder is set, but video source is not set");
403 }
404 return INVALID_OPERATION;
405 }
406
407 status_t ret = mMediaRecorder->prepare();
408 if (OK != ret) {
409 LOGE("prepare failed: %d", ret);
410 mCurrentState = MEDIA_RECORDER_ERROR;
411 return ret;
412 }
413 mCurrentState = MEDIA_RECORDER_PREPARED;
414 return ret;
415 }
416
getMaxAmplitude(int * max)417 status_t MediaRecorder::getMaxAmplitude(int* max)
418 {
419 LOGV("getMaxAmplitude");
420 if(mMediaRecorder == NULL) {
421 LOGE("media recorder is not initialized yet");
422 return INVALID_OPERATION;
423 }
424 if (mCurrentState & MEDIA_RECORDER_ERROR) {
425 LOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState);
426 return INVALID_OPERATION;
427 }
428
429 status_t ret = mMediaRecorder->getMaxAmplitude(max);
430 if (OK != ret) {
431 LOGE("getMaxAmplitude failed: %d", ret);
432 mCurrentState = MEDIA_RECORDER_ERROR;
433 return ret;
434 }
435 return ret;
436 }
437
start()438 status_t MediaRecorder::start()
439 {
440 LOGV("start");
441 if (mMediaRecorder == NULL) {
442 LOGE("media recorder is not initialized yet");
443 return INVALID_OPERATION;
444 }
445 if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
446 LOGE("start called in an invalid state: %d", mCurrentState);
447 return INVALID_OPERATION;
448 }
449
450 status_t ret = mMediaRecorder->start();
451 if (OK != ret) {
452 LOGE("start failed: %d", ret);
453 mCurrentState = MEDIA_RECORDER_ERROR;
454 return ret;
455 }
456 mCurrentState = MEDIA_RECORDER_RECORDING;
457 return ret;
458 }
459
stop()460 status_t MediaRecorder::stop()
461 {
462 LOGV("stop");
463 if (mMediaRecorder == NULL) {
464 LOGE("media recorder is not initialized yet");
465 return INVALID_OPERATION;
466 }
467 if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
468 LOGE("stop called in an invalid state: %d", mCurrentState);
469 return INVALID_OPERATION;
470 }
471
472 status_t ret = mMediaRecorder->stop();
473 if (OK != ret) {
474 LOGE("stop failed: %d", ret);
475 mCurrentState = MEDIA_RECORDER_ERROR;
476 return ret;
477 }
478
479 // FIXME:
480 // stop and reset are semantically different.
481 // We treat them the same for now, and will change this in the future.
482 doCleanUp();
483 mCurrentState = MEDIA_RECORDER_IDLE;
484 return ret;
485 }
486
487 // Reset should be OK in any state
reset()488 status_t MediaRecorder::reset()
489 {
490 LOGV("reset");
491 if (mMediaRecorder == NULL) {
492 LOGE("media recorder is not initialized yet");
493 return INVALID_OPERATION;
494 }
495
496 doCleanUp();
497 status_t ret = UNKNOWN_ERROR;
498 switch(mCurrentState) {
499 case MEDIA_RECORDER_IDLE:
500 ret = OK;
501 break;
502
503 case MEDIA_RECORDER_RECORDING:
504 case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
505 case MEDIA_RECORDER_PREPARED:
506 case MEDIA_RECORDER_ERROR: {
507 ret = doReset();
508 if (OK != ret) {
509 return ret; // No need to continue
510 }
511 } // Intentional fall through
512 case MEDIA_RECORDER_INITIALIZED:
513 ret = close();
514 break;
515
516 default: {
517 LOGE("Unexpected non-existing state: %d", mCurrentState);
518 break;
519 }
520 }
521 return ret;
522 }
523
close()524 status_t MediaRecorder::close()
525 {
526 LOGV("close");
527 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
528 LOGE("close called in an invalid state: %d", mCurrentState);
529 return INVALID_OPERATION;
530 }
531 status_t ret = mMediaRecorder->close();
532 if (OK != ret) {
533 LOGE("close failed: %d", ret);
534 mCurrentState = MEDIA_RECORDER_ERROR;
535 return UNKNOWN_ERROR;
536 } else {
537 mCurrentState = MEDIA_RECORDER_IDLE;
538 }
539 return ret;
540 }
541
doReset()542 status_t MediaRecorder::doReset()
543 {
544 LOGV("doReset");
545 status_t ret = mMediaRecorder->reset();
546 if (OK != ret) {
547 LOGE("doReset failed: %d", ret);
548 mCurrentState = MEDIA_RECORDER_ERROR;
549 return ret;
550 } else {
551 mCurrentState = MEDIA_RECORDER_INITIALIZED;
552 }
553 return ret;
554 }
555
doCleanUp()556 void MediaRecorder::doCleanUp()
557 {
558 LOGV("doCleanUp");
559 mIsAudioSourceSet = false;
560 mIsVideoSourceSet = false;
561 mIsAudioEncoderSet = false;
562 mIsVideoEncoderSet = false;
563 mIsOutputFileSet = false;
564 }
565
566 // Release should be OK in any state
release()567 status_t MediaRecorder::release()
568 {
569 LOGV("release");
570 if (mMediaRecorder != NULL) {
571 return mMediaRecorder->release();
572 }
573 return INVALID_OPERATION;
574 }
575
MediaRecorder()576 MediaRecorder::MediaRecorder()
577 {
578 LOGV("constructor");
579 sp<IServiceManager> sm = defaultServiceManager();
580 sp<IBinder> binder;
581
582 do {
583 binder = sm->getService(String16("media.player"));
584 if (binder != NULL) {
585 break;
586 }
587 LOGW("MediaPlayerService not published, waiting...");
588 usleep(500000); // 0.5 s
589 } while(true);
590
591 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
592 if (service != NULL) {
593 mMediaRecorder = service->createMediaRecorder(getpid());
594 }
595 if (mMediaRecorder != NULL) {
596 mCurrentState = MEDIA_RECORDER_IDLE;
597 }
598 doCleanUp();
599 }
600
initCheck()601 status_t MediaRecorder::initCheck()
602 {
603 return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
604 }
605
~MediaRecorder()606 MediaRecorder::~MediaRecorder()
607 {
608 LOGV("destructor");
609 if (mMediaRecorder != NULL) {
610 mMediaRecorder.clear();
611 }
612 }
613
setListener(const sp<MediaRecorderListener> & listener)614 status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
615 {
616 LOGV("setListener");
617 Mutex::Autolock _l(mLock);
618 mListener = listener;
619
620 return NO_ERROR;
621 }
622
notify(int msg,int ext1,int ext2)623 void MediaRecorder::notify(int msg, int ext1, int ext2)
624 {
625 LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
626
627 sp<MediaRecorderListener> listener;
628 mLock.lock();
629 listener = mListener;
630 mLock.unlock();
631
632 if (listener != NULL) {
633 Mutex::Autolock _l(mNotifyLock);
634 LOGV("callback application");
635 listener->notify(msg, ext1, ext2);
636 LOGV("back from callback");
637 }
638 }
639
640 }; // namespace android
641
642