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