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