mediarecorder.cpp revision 1179bc9b0e3d17c984e8f4ad38561c049dd102fa
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        // 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
378status_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
417status_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
438status_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
460status_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
488status_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
524status_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
542status_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
556void 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
567status_t MediaRecorder::release()
568{
569    LOGV("release");
570    if (mMediaRecorder != NULL) {
571        return mMediaRecorder->release();
572    }
573    return INVALID_OPERATION;
574}
575
576MediaRecorder::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
601status_t MediaRecorder::initCheck()
602{
603    return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
604}
605
606MediaRecorder::~MediaRecorder()
607{
608    LOGV("destructor");
609    if (mMediaRecorder != NULL) {
610        mMediaRecorder.clear();
611    }
612}
613
614status_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
623void 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