mediarecorder.cpp revision 99ffda877980468a9ae31e013cd10fb3645df1b0
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
92    }
93
94    ret = mMediaRecorder->setListener(this);
95    if (OK != ret) {
96        LOGV("setListener failed: %d", ret);
97        mCurrentState = MEDIA_RECORDER_ERROR;
98        return UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
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 UNKNOWN_ERROR;
458    }
459    mCurrentState = MEDIA_RECORDER_IDLE;
460    return ret;
461}
462
463// Reset should be OK in any state
464status_t MediaRecorder::reset()
465{
466    LOGV("reset");
467    if (mMediaRecorder == NULL) {
468        LOGE("media recorder is not initialized yet");
469        return INVALID_OPERATION;
470    }
471
472    doCleanUp();
473    status_t ret = UNKNOWN_ERROR;
474    switch(mCurrentState) {
475        case MEDIA_RECORDER_IDLE:
476            ret = OK;
477            break;
478
479        case MEDIA_RECORDER_RECORDING:
480        case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
481        case MEDIA_RECORDER_PREPARED:
482        case MEDIA_RECORDER_ERROR: {
483            ret = doReset();
484            if (OK != ret) {
485               return ret;  // No need to continue
486            }
487        }  // Intentional fall through
488        case MEDIA_RECORDER_INITIALIZED:
489            ret = close();
490            break;
491
492        default: {
493            LOGE("Unexpected non-existing state: %d", mCurrentState);
494            break;
495        }
496    }
497    return ret;
498}
499
500status_t MediaRecorder::close()
501{
502    LOGV("close");
503    if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
504        LOGE("close called in an invalid state: %d", mCurrentState);
505        return INVALID_OPERATION;
506    }
507    status_t ret = mMediaRecorder->close();
508    if (OK != ret) {
509        LOGE("close failed: %d", ret);
510        mCurrentState = MEDIA_RECORDER_ERROR;
511        return UNKNOWN_ERROR;
512    } else {
513        mCurrentState = MEDIA_RECORDER_IDLE;
514    }
515    return ret;
516}
517
518status_t MediaRecorder::doReset()
519{
520    LOGV("doReset");
521    status_t ret = mMediaRecorder->reset();
522    if (OK != ret) {
523        LOGE("doReset failed: %d", ret);
524        mCurrentState = MEDIA_RECORDER_ERROR;
525        return UNKNOWN_ERROR;
526    } else {
527        mCurrentState = MEDIA_RECORDER_INITIALIZED;
528    }
529    return ret;
530}
531
532void MediaRecorder::doCleanUp()
533{
534    LOGV("doCleanUp");
535    mIsAudioSourceSet  = false;
536    mIsVideoSourceSet  = false;
537    mIsAudioEncoderSet = false;
538    mIsVideoEncoderSet = false;
539    mIsOutputFileSet   = false;
540}
541
542// Release should be OK in any state
543status_t MediaRecorder::release()
544{
545    LOGV("release");
546    if (mMediaRecorder != NULL) {
547        return mMediaRecorder->release();
548    }
549    return INVALID_OPERATION;
550}
551
552MediaRecorder::MediaRecorder()
553{
554    LOGV("constructor");
555    sp<IServiceManager> sm = defaultServiceManager();
556    sp<IBinder> binder;
557
558    do {
559        binder = sm->getService(String16("media.player"));
560        if (binder != NULL) {
561            break;
562        }
563        LOGW("MediaPlayerService not published, waiting...");
564        usleep(500000); // 0.5 s
565    } while(true);
566
567    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
568    if (service != NULL) {
569        mMediaRecorder = service->createMediaRecorder(getpid());
570    }
571    if (mMediaRecorder != NULL) {
572        mCurrentState = MEDIA_RECORDER_IDLE;
573    }
574    doCleanUp();
575}
576
577status_t MediaRecorder::initCheck()
578{
579    return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
580}
581
582MediaRecorder::~MediaRecorder()
583{
584    LOGV("destructor");
585    if (mMediaRecorder != NULL) {
586        mMediaRecorder.clear();
587    }
588}
589
590status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
591{
592    LOGV("setListener");
593    Mutex::Autolock _l(mLock);
594    mListener = listener;
595
596    return NO_ERROR;
597}
598
599void MediaRecorder::notify(int msg, int ext1, int ext2)
600{
601    LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
602
603    sp<MediaRecorderListener> listener;
604    mLock.lock();
605    listener = mListener;
606    mLock.unlock();
607
608    if (listener != NULL) {
609        Mutex::Autolock _l(mNotifyLock);
610        LOGV("callback application");
611        listener->notify(msg, ext1, ext2);
612        LOGV("back from callback");
613    }
614}
615
616}; // namespace android
617
618