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