mediarecorder.cpp revision c048cae0367db6fbb4fe1127be5011910713d4ad
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 <utils/IServiceManager.h>
24#include <utils/String8.h>
25#include <media/IMediaPlayerService.h>
26#include <media/IMediaRecorder.h>
27
28namespace android {
29
30status_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
51status_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
76status_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
106status_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
139status_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
172status_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_RAW_AMR) {
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
198status_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
228status_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
258status_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
284status_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
310status_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
335status_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
360status_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        mCurrentState = MEDIA_RECORDER_ERROR;
371        return ret;
372    }
373
374    return ret;
375}
376
377status_t MediaRecorder::prepare()
378{
379    LOGV("prepare");
380    if(mMediaRecorder == NULL) {
381        LOGE("media recorder is not initialized yet");
382        return INVALID_OPERATION;
383    }
384    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
385        LOGE("prepare called in an invalid state: %d", mCurrentState);
386        return INVALID_OPERATION;
387    }
388    if (mIsAudioSourceSet != mIsAudioEncoderSet) {
389        if (mIsAudioSourceSet) {
390            LOGE("audio source is set, but audio encoder is not set");
391        } else {  // must not happen, since setAudioEncoder checks this already
392            LOGE("audio encoder is set, but audio source is not set");
393        }
394        return INVALID_OPERATION;
395    }
396
397    if (mIsVideoSourceSet != mIsVideoEncoderSet) {
398        if (mIsVideoSourceSet) {
399            LOGE("video source is set, but video encoder is not set");
400        } else {  // must not happen, since setVideoEncoder checks this already
401            LOGE("video encoder is set, but video source is not set");
402        }
403        return INVALID_OPERATION;
404    }
405
406    status_t ret = mMediaRecorder->prepare();
407    if (OK != ret) {
408        LOGE("prepare failed: %d", ret);
409        mCurrentState = MEDIA_RECORDER_ERROR;
410        return ret;
411    }
412    mCurrentState = MEDIA_RECORDER_PREPARED;
413    return ret;
414}
415
416status_t MediaRecorder::getMaxAmplitude(int* max)
417{
418    LOGV("getMaxAmplitude");
419    if(mMediaRecorder == NULL) {
420        LOGE("media recorder is not initialized yet");
421        return INVALID_OPERATION;
422    }
423    if (mCurrentState & MEDIA_RECORDER_ERROR) {
424        LOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState);
425        return INVALID_OPERATION;
426    }
427
428    status_t ret = mMediaRecorder->getMaxAmplitude(max);
429    if (OK != ret) {
430        LOGE("getMaxAmplitude failed: %d", ret);
431        mCurrentState = MEDIA_RECORDER_ERROR;
432        return ret;
433    }
434    return ret;
435}
436
437status_t MediaRecorder::start()
438{
439    LOGV("start");
440    if (mMediaRecorder == NULL) {
441        LOGE("media recorder is not initialized yet");
442        return INVALID_OPERATION;
443    }
444    if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
445        LOGE("start called in an invalid state: %d", mCurrentState);
446        return INVALID_OPERATION;
447    }
448
449    status_t ret = mMediaRecorder->start();
450    if (OK != ret) {
451        LOGE("start failed: %d", ret);
452        mCurrentState = MEDIA_RECORDER_ERROR;
453        return ret;
454    }
455    mCurrentState = MEDIA_RECORDER_RECORDING;
456    return ret;
457}
458
459status_t MediaRecorder::stop()
460{
461    LOGV("stop");
462    if (mMediaRecorder == NULL) {
463        LOGE("media recorder is not initialized yet");
464        return INVALID_OPERATION;
465    }
466    if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
467        LOGE("stop called in an invalid state: %d", mCurrentState);
468        return INVALID_OPERATION;
469    }
470
471    status_t ret = mMediaRecorder->stop();
472    if (OK != ret) {
473        LOGE("stop failed: %d", ret);
474        mCurrentState = MEDIA_RECORDER_ERROR;
475        return ret;
476    }
477
478    // FIXME:
479    // stop and reset are semantically different.
480    // We treat them the same for now, and will change this in the future.
481    doCleanUp();
482    mCurrentState = MEDIA_RECORDER_IDLE;
483    return ret;
484}
485
486// Reset should be OK in any state
487status_t MediaRecorder::reset()
488{
489    LOGV("reset");
490    if (mMediaRecorder == NULL) {
491        LOGE("media recorder is not initialized yet");
492        return INVALID_OPERATION;
493    }
494
495    doCleanUp();
496    status_t ret = UNKNOWN_ERROR;
497    switch(mCurrentState) {
498        case MEDIA_RECORDER_IDLE:
499            ret = OK;
500            break;
501
502        case MEDIA_RECORDER_RECORDING:
503        case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
504        case MEDIA_RECORDER_PREPARED:
505        case MEDIA_RECORDER_ERROR: {
506            ret = doReset();
507            if (OK != ret) {
508               return ret;  // No need to continue
509            }
510        }  // Intentional fall through
511        case MEDIA_RECORDER_INITIALIZED:
512            ret = close();
513            break;
514
515        default: {
516            LOGE("Unexpected non-existing state: %d", mCurrentState);
517            break;
518        }
519    }
520    return ret;
521}
522
523status_t MediaRecorder::close()
524{
525    LOGV("close");
526    if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
527        LOGE("close called in an invalid state: %d", mCurrentState);
528        return INVALID_OPERATION;
529    }
530    status_t ret = mMediaRecorder->close();
531    if (OK != ret) {
532        LOGE("close failed: %d", ret);
533        mCurrentState = MEDIA_RECORDER_ERROR;
534        return UNKNOWN_ERROR;
535    } else {
536        mCurrentState = MEDIA_RECORDER_IDLE;
537    }
538    return ret;
539}
540
541status_t MediaRecorder::doReset()
542{
543    LOGV("doReset");
544    status_t ret = mMediaRecorder->reset();
545    if (OK != ret) {
546        LOGE("doReset failed: %d", ret);
547        mCurrentState = MEDIA_RECORDER_ERROR;
548        return ret;
549    } else {
550        mCurrentState = MEDIA_RECORDER_INITIALIZED;
551    }
552    return ret;
553}
554
555void MediaRecorder::doCleanUp()
556{
557    LOGV("doCleanUp");
558    mIsAudioSourceSet  = false;
559    mIsVideoSourceSet  = false;
560    mIsAudioEncoderSet = false;
561    mIsVideoEncoderSet = false;
562    mIsOutputFileSet   = false;
563}
564
565// Release should be OK in any state
566status_t MediaRecorder::release()
567{
568    LOGV("release");
569    if (mMediaRecorder != NULL) {
570        return mMediaRecorder->release();
571    }
572    return INVALID_OPERATION;
573}
574
575MediaRecorder::MediaRecorder()
576{
577    LOGV("constructor");
578    sp<IServiceManager> sm = defaultServiceManager();
579    sp<IBinder> binder;
580
581    do {
582        binder = sm->getService(String16("media.player"));
583        if (binder != NULL) {
584            break;
585        }
586        LOGW("MediaPlayerService not published, waiting...");
587        usleep(500000); // 0.5 s
588    } while(true);
589
590    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
591    if (service != NULL) {
592        mMediaRecorder = service->createMediaRecorder(getpid());
593    }
594    if (mMediaRecorder != NULL) {
595        mCurrentState = MEDIA_RECORDER_IDLE;
596    }
597    doCleanUp();
598}
599
600status_t MediaRecorder::initCheck()
601{
602    return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
603}
604
605MediaRecorder::~MediaRecorder()
606{
607    LOGV("destructor");
608    if (mMediaRecorder != NULL) {
609        mMediaRecorder.clear();
610    }
611}
612
613status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
614{
615    LOGV("setListener");
616    Mutex::Autolock _l(mLock);
617    mListener = listener;
618
619    return NO_ERROR;
620}
621
622void MediaRecorder::notify(int msg, int ext1, int ext2)
623{
624    LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
625
626    sp<MediaRecorderListener> listener;
627    mLock.lock();
628    listener = mListener;
629    mLock.unlock();
630
631    if (listener != NULL) {
632        Mutex::Autolock _l(mNotifyLock);
633        LOGV("callback application");
634        listener->notify(msg, ext1, ext2);
635        LOGV("back from callback");
636    }
637}
638
639}; // namespace android
640
641