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