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)
32{
33    LOGV("setCamera(%p)", camera.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);
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->getISurface());
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) { //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    status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
302    if (OK != ret) {
303        LOGV("setOutputFile failed: %d", ret);
304        mCurrentState = MEDIA_RECORDER_ERROR;
305        return ret;
306    }
307    mIsOutputFileSet = true;
308    return ret;
309}
310
311status_t MediaRecorder::setVideoSize(int width, int height)
312{
313    LOGV("setVideoSize(%d, %d)", width, height);
314    if(mMediaRecorder == NULL) {
315        LOGE("media recorder is not initialized yet");
316        return INVALID_OPERATION;
317    }
318    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
319        LOGE("setVideoSize called in an invalid state: %d", mCurrentState);
320        return INVALID_OPERATION;
321    }
322    if (!mIsVideoSourceSet) {
323        LOGE("try to set video size without setting video source first");
324        return INVALID_OPERATION;
325    }
326
327    status_t ret = mMediaRecorder->setVideoSize(width, height);
328    if (OK != ret) {
329        LOGE("setVideoSize failed: %d", ret);
330        mCurrentState = MEDIA_RECORDER_ERROR;
331        return ret;
332    }
333    return ret;
334}
335
336status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
337{
338    LOGV("setVideoFrameRate(%d)", frames_per_second);
339    if(mMediaRecorder == NULL) {
340        LOGE("media recorder is not initialized yet");
341        return INVALID_OPERATION;
342    }
343    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
344        LOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState);
345        return INVALID_OPERATION;
346    }
347    if (!mIsVideoSourceSet) {
348        LOGE("try to set video frame rate without setting video source first");
349        return INVALID_OPERATION;
350    }
351
352    status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second);
353    if (OK != ret) {
354        LOGE("setVideoFrameRate failed: %d", ret);
355        mCurrentState = MEDIA_RECORDER_ERROR;
356        return ret;
357    }
358    return ret;
359}
360
361status_t MediaRecorder::setParameters(const String8& params) {
362    LOGV("setParameters(%s)", params.string());
363    if(mMediaRecorder == NULL) {
364        LOGE("media recorder is not initialized yet");
365        return INVALID_OPERATION;
366    }
367
368    bool isInvalidState = (mCurrentState &
369                           (MEDIA_RECORDER_PREPARED |
370                            MEDIA_RECORDER_RECORDING |
371                            MEDIA_RECORDER_ERROR));
372    if (isInvalidState) {
373        LOGE("setParameters is called in an invalid state: %d", mCurrentState);
374        return INVALID_OPERATION;
375    }
376
377    status_t ret = mMediaRecorder->setParameters(params);
378    if (OK != ret) {
379        LOGE("setParameters(%s) failed: %d", params.string(), ret);
380        // Do not change our current state to MEDIA_RECORDER_ERROR, failures
381        // of the only currently supported parameters, "max-duration" and
382        // "max-filesize" are _not_ fatal.
383    }
384
385    return ret;
386}
387
388status_t MediaRecorder::prepare()
389{
390    LOGV("prepare");
391    if(mMediaRecorder == NULL) {
392        LOGE("media recorder is not initialized yet");
393        return INVALID_OPERATION;
394    }
395    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
396        LOGE("prepare called in an invalid state: %d", mCurrentState);
397        return INVALID_OPERATION;
398    }
399    if (mIsAudioSourceSet != mIsAudioEncoderSet) {
400        if (mIsAudioSourceSet) {
401            LOGE("audio source is set, but audio encoder is not set");
402        } else {  // must not happen, since setAudioEncoder checks this already
403            LOGE("audio encoder is set, but audio source is not set");
404        }
405        return INVALID_OPERATION;
406    }
407
408    if (mIsVideoSourceSet != mIsVideoEncoderSet) {
409        if (mIsVideoSourceSet) {
410            LOGE("video source is set, but video encoder is not set");
411        } else {  // must not happen, since setVideoEncoder checks this already
412            LOGE("video encoder is set, but video source is not set");
413        }
414        return INVALID_OPERATION;
415    }
416
417    status_t ret = mMediaRecorder->prepare();
418    if (OK != ret) {
419        LOGE("prepare failed: %d", ret);
420        mCurrentState = MEDIA_RECORDER_ERROR;
421        return ret;
422    }
423    mCurrentState = MEDIA_RECORDER_PREPARED;
424    return ret;
425}
426
427status_t MediaRecorder::getMaxAmplitude(int* max)
428{
429    LOGV("getMaxAmplitude");
430    if(mMediaRecorder == NULL) {
431        LOGE("media recorder is not initialized yet");
432        return INVALID_OPERATION;
433    }
434    if (mCurrentState & MEDIA_RECORDER_ERROR) {
435        LOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState);
436        return INVALID_OPERATION;
437    }
438
439    status_t ret = mMediaRecorder->getMaxAmplitude(max);
440    if (OK != ret) {
441        LOGE("getMaxAmplitude failed: %d", ret);
442        mCurrentState = MEDIA_RECORDER_ERROR;
443        return ret;
444    }
445    return ret;
446}
447
448status_t MediaRecorder::start()
449{
450    LOGV("start");
451    if (mMediaRecorder == NULL) {
452        LOGE("media recorder is not initialized yet");
453        return INVALID_OPERATION;
454    }
455    if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
456        LOGE("start called in an invalid state: %d", mCurrentState);
457        return INVALID_OPERATION;
458    }
459
460    status_t ret = mMediaRecorder->start();
461    if (OK != ret) {
462        LOGE("start failed: %d", ret);
463        mCurrentState = MEDIA_RECORDER_ERROR;
464        return ret;
465    }
466    mCurrentState = MEDIA_RECORDER_RECORDING;
467    return ret;
468}
469
470status_t MediaRecorder::stop()
471{
472    LOGV("stop");
473    if (mMediaRecorder == NULL) {
474        LOGE("media recorder is not initialized yet");
475        return INVALID_OPERATION;
476    }
477    if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
478        LOGE("stop called in an invalid state: %d", mCurrentState);
479        return INVALID_OPERATION;
480    }
481
482    status_t ret = mMediaRecorder->stop();
483    if (OK != ret) {
484        LOGE("stop failed: %d", ret);
485        mCurrentState = MEDIA_RECORDER_ERROR;
486        return ret;
487    }
488
489    // FIXME:
490    // stop and reset are semantically different.
491    // We treat them the same for now, and will change this in the future.
492    doCleanUp();
493    mCurrentState = MEDIA_RECORDER_IDLE;
494    return ret;
495}
496
497// Reset should be OK in any state
498status_t MediaRecorder::reset()
499{
500    LOGV("reset");
501    if (mMediaRecorder == NULL) {
502        LOGE("media recorder is not initialized yet");
503        return INVALID_OPERATION;
504    }
505
506    doCleanUp();
507    status_t ret = UNKNOWN_ERROR;
508    switch(mCurrentState) {
509        case MEDIA_RECORDER_IDLE:
510            ret = OK;
511            break;
512
513        case MEDIA_RECORDER_RECORDING:
514        case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
515        case MEDIA_RECORDER_PREPARED:
516        case MEDIA_RECORDER_ERROR: {
517            ret = doReset();
518            if (OK != ret) {
519               return ret;  // No need to continue
520            }
521        }  // Intentional fall through
522        case MEDIA_RECORDER_INITIALIZED:
523            ret = close();
524            break;
525
526        default: {
527            LOGE("Unexpected non-existing state: %d", mCurrentState);
528            break;
529        }
530    }
531    return ret;
532}
533
534status_t MediaRecorder::close()
535{
536    LOGV("close");
537    if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
538        LOGE("close called in an invalid state: %d", mCurrentState);
539        return INVALID_OPERATION;
540    }
541    status_t ret = mMediaRecorder->close();
542    if (OK != ret) {
543        LOGE("close failed: %d", ret);
544        mCurrentState = MEDIA_RECORDER_ERROR;
545        return UNKNOWN_ERROR;
546    } else {
547        mCurrentState = MEDIA_RECORDER_IDLE;
548    }
549    return ret;
550}
551
552status_t MediaRecorder::doReset()
553{
554    LOGV("doReset");
555    status_t ret = mMediaRecorder->reset();
556    if (OK != ret) {
557        LOGE("doReset failed: %d", ret);
558        mCurrentState = MEDIA_RECORDER_ERROR;
559        return ret;
560    } else {
561        mCurrentState = MEDIA_RECORDER_INITIALIZED;
562    }
563    return ret;
564}
565
566void MediaRecorder::doCleanUp()
567{
568    LOGV("doCleanUp");
569    mIsAudioSourceSet  = false;
570    mIsVideoSourceSet  = false;
571    mIsAudioEncoderSet = false;
572    mIsVideoEncoderSet = false;
573    mIsOutputFileSet   = false;
574}
575
576// Release should be OK in any state
577status_t MediaRecorder::release()
578{
579    LOGV("release");
580    if (mMediaRecorder != NULL) {
581        return mMediaRecorder->release();
582    }
583    return INVALID_OPERATION;
584}
585
586MediaRecorder::MediaRecorder()
587{
588    LOGV("constructor");
589
590    const sp<IMediaPlayerService>& service(getMediaPlayerService());
591    if (service != NULL) {
592        mMediaRecorder = service->createMediaRecorder(getpid());
593    }
594    if (mMediaRecorder != NULL) {
595        mCurrentState = MEDIA_RECORDER_IDLE;
596    }
597    doCleanUp();
598}
599
600status_t MediaRecorder::initCheck()
601{
602    return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
603}
604
605MediaRecorder::~MediaRecorder()
606{
607    LOGV("destructor");
608    if (mMediaRecorder != NULL) {
609        mMediaRecorder.clear();
610    }
611}
612
613status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
614{
615    LOGV("setListener");
616    Mutex::Autolock _l(mLock);
617    mListener = listener;
618
619    return NO_ERROR;
620}
621
622void MediaRecorder::notify(int msg, int ext1, int ext2)
623{
624    LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
625
626    sp<MediaRecorderListener> listener;
627    mLock.lock();
628    listener = mListener;
629    mLock.unlock();
630
631    if (listener != NULL) {
632        Mutex::Autolock _l(mNotifyLock);
633        LOGV("callback application");
634        listener->notify(msg, ext1, ext2);
635        LOGV("back from callback");
636    }
637}
638
639void MediaRecorder::died()
640{
641    LOGV("died");
642    notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
643}
644
645}; // namespace android
646
647