mediarecorder.cpp revision 114819633470ebd5b346c13c2a82a0025d2d39c0
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
21#include <inttypes.h>
22
23#include <utils/Log.h>
24#include <media/mediarecorder.h>
25#include <binder/IServiceManager.h>
26#include <utils/String8.h>
27#include <media/IMediaPlayerService.h>
28#include <media/IMediaRecorder.h>
29#include <media/mediaplayer.h>  // for MEDIA_ERROR_SERVER_DIED
30#include <gui/IGraphicBufferProducer.h>
31
32namespace android {
33
34status_t MediaRecorder::setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
35{
36    ALOGV("setCamera(%p,%p)", camera.get(), proxy.get());
37    if (mMediaRecorder == NULL) {
38        ALOGE("media recorder is not initialized yet");
39        return INVALID_OPERATION;
40    }
41    if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
42        ALOGE("setCamera called in an invalid state(%d)", mCurrentState);
43        return INVALID_OPERATION;
44    }
45
46    status_t ret = mMediaRecorder->setCamera(camera, proxy);
47    if (OK != ret) {
48        ALOGV("setCamera failed: %d", ret);
49        mCurrentState = MEDIA_RECORDER_ERROR;
50        return ret;
51    }
52    return ret;
53}
54
55status_t MediaRecorder::setPreviewSurface(const sp<IGraphicBufferProducer>& surface)
56{
57    ALOGV("setPreviewSurface(%p)", surface.get());
58    if (mMediaRecorder == NULL) {
59        ALOGE("media recorder is not initialized yet");
60        return INVALID_OPERATION;
61    }
62    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
63        ALOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState);
64        return INVALID_OPERATION;
65    }
66    if (!mIsVideoSourceSet) {
67        ALOGE("try to set preview surface without setting the video source first");
68        return INVALID_OPERATION;
69    }
70
71    status_t ret = mMediaRecorder->setPreviewSurface(surface);
72    if (OK != ret) {
73        ALOGV("setPreviewSurface failed: %d", ret);
74        mCurrentState = MEDIA_RECORDER_ERROR;
75        return ret;
76    }
77    return ret;
78}
79
80status_t MediaRecorder::init()
81{
82    ALOGV("init");
83    if (mMediaRecorder == NULL) {
84        ALOGE("media recorder is not initialized yet");
85        return INVALID_OPERATION;
86    }
87    if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
88        ALOGE("init called in an invalid state(%d)", mCurrentState);
89        return INVALID_OPERATION;
90    }
91
92    status_t ret = mMediaRecorder->init();
93    if (OK != ret) {
94        ALOGV("init failed: %d", ret);
95        mCurrentState = MEDIA_RECORDER_ERROR;
96        return ret;
97    }
98
99    ret = mMediaRecorder->setListener(this);
100    if (OK != ret) {
101        ALOGV("setListener failed: %d", ret);
102        mCurrentState = MEDIA_RECORDER_ERROR;
103        return ret;
104    }
105
106    mCurrentState = MEDIA_RECORDER_INITIALIZED;
107    return ret;
108}
109
110status_t MediaRecorder::setVideoSource(int vs)
111{
112    ALOGV("setVideoSource(%d)", vs);
113    if (mMediaRecorder == NULL) {
114        ALOGE("media recorder is not initialized yet");
115        return INVALID_OPERATION;
116    }
117    if (mIsVideoSourceSet) {
118        ALOGE("video source has already been set");
119        return INVALID_OPERATION;
120    }
121    if (mCurrentState & MEDIA_RECORDER_IDLE) {
122        ALOGV("Call init() since the media recorder is not initialized yet");
123        status_t ret = init();
124        if (OK != ret) {
125            return ret;
126        }
127    }
128    if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
129        ALOGE("setVideoSource called in an invalid state(%d)", mCurrentState);
130        return INVALID_OPERATION;
131    }
132
133    // following call is made over the Binder Interface
134    status_t ret = mMediaRecorder->setVideoSource(vs);
135
136    if (OK != ret) {
137        ALOGV("setVideoSource failed: %d", ret);
138        mCurrentState = MEDIA_RECORDER_ERROR;
139        return ret;
140    }
141    mIsVideoSourceSet = true;
142    return ret;
143}
144
145status_t MediaRecorder::setAudioSource(int as)
146{
147    ALOGV("setAudioSource(%d)", as);
148    if (mMediaRecorder == NULL) {
149        ALOGE("media recorder is not initialized yet");
150        return INVALID_OPERATION;
151    }
152    if (mCurrentState & MEDIA_RECORDER_IDLE) {
153        ALOGV("Call init() since the media recorder is not initialized yet");
154        status_t ret = init();
155        if (OK != ret) {
156            return ret;
157        }
158    }
159    if (mIsAudioSourceSet) {
160        ALOGE("audio source has already been set");
161        return INVALID_OPERATION;
162    }
163    if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
164        ALOGE("setAudioSource called in an invalid state(%d)", mCurrentState);
165        return INVALID_OPERATION;
166    }
167
168    status_t ret = mMediaRecorder->setAudioSource(as);
169    if (OK != ret) {
170        ALOGV("setAudioSource failed: %d", ret);
171        mCurrentState = MEDIA_RECORDER_ERROR;
172        return ret;
173    }
174    mIsAudioSourceSet = true;
175    return ret;
176}
177
178status_t MediaRecorder::setOutputFormat(int of)
179{
180    ALOGV("setOutputFormat(%d)", of);
181    if (mMediaRecorder == NULL) {
182        ALOGE("media recorder is not initialized yet");
183        return INVALID_OPERATION;
184    }
185    if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
186        ALOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
187        return INVALID_OPERATION;
188    }
189    if (mIsVideoSourceSet
190            && of >= OUTPUT_FORMAT_AUDIO_ONLY_START //first non-video output format
191            && of < OUTPUT_FORMAT_AUDIO_ONLY_END) {
192        ALOGE("output format (%d) is meant for audio recording only"
193              " and incompatible with video recording", of);
194        return INVALID_OPERATION;
195    }
196
197    status_t ret = mMediaRecorder->setOutputFormat(of);
198    if (OK != ret) {
199        ALOGE("setOutputFormat failed: %d", ret);
200        mCurrentState = MEDIA_RECORDER_ERROR;
201        return ret;
202    }
203    mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED;
204    return ret;
205}
206
207status_t MediaRecorder::setVideoEncoder(int ve)
208{
209    ALOGV("setVideoEncoder(%d)", ve);
210    if (mMediaRecorder == NULL) {
211        ALOGE("media recorder is not initialized yet");
212        return INVALID_OPERATION;
213    }
214    if (!mIsVideoSourceSet) {
215        ALOGE("try to set the video encoder without setting the video source first");
216        return INVALID_OPERATION;
217    }
218    if (mIsVideoEncoderSet) {
219        ALOGE("video encoder has already been set");
220        return INVALID_OPERATION;
221    }
222    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
223        ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);
224        return INVALID_OPERATION;
225    }
226
227    status_t ret = mMediaRecorder->setVideoEncoder(ve);
228    if (OK != ret) {
229        ALOGV("setVideoEncoder failed: %d", ret);
230        mCurrentState = MEDIA_RECORDER_ERROR;
231        return ret;
232    }
233    mIsVideoEncoderSet = true;
234    return ret;
235}
236
237status_t MediaRecorder::setAudioEncoder(int ae)
238{
239    ALOGV("setAudioEncoder(%d)", ae);
240    if (mMediaRecorder == NULL) {
241        ALOGE("media recorder is not initialized yet");
242        return INVALID_OPERATION;
243    }
244    if (!mIsAudioSourceSet) {
245        ALOGE("try to set the audio encoder without setting the audio source first");
246        return INVALID_OPERATION;
247    }
248    if (mIsAudioEncoderSet) {
249        ALOGE("audio encoder has already been set");
250        return INVALID_OPERATION;
251    }
252    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
253        ALOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState);
254        return INVALID_OPERATION;
255    }
256
257    status_t ret = mMediaRecorder->setAudioEncoder(ae);
258    if (OK != ret) {
259        ALOGV("setAudioEncoder failed: %d", ret);
260        mCurrentState = MEDIA_RECORDER_ERROR;
261        return ret;
262    }
263    mIsAudioEncoderSet = true;
264    return ret;
265}
266
267status_t MediaRecorder::setOutputFile(const char* path)
268{
269    ALOGV("setOutputFile(%s)", path);
270    if (mMediaRecorder == NULL) {
271        ALOGE("media recorder is not initialized yet");
272        return INVALID_OPERATION;
273    }
274    if (mIsOutputFileSet) {
275        ALOGE("output file has already been set");
276        return INVALID_OPERATION;
277    }
278    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
279        ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
280        return INVALID_OPERATION;
281    }
282
283    status_t ret = mMediaRecorder->setOutputFile(path);
284    if (OK != ret) {
285        ALOGV("setOutputFile failed: %d", ret);
286        mCurrentState = MEDIA_RECORDER_ERROR;
287        return ret;
288    }
289    mIsOutputFileSet = true;
290    return ret;
291}
292
293status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
294{
295    ALOGV("setOutputFile(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
296    if (mMediaRecorder == NULL) {
297        ALOGE("media recorder is not initialized yet");
298        return INVALID_OPERATION;
299    }
300    if (mIsOutputFileSet) {
301        ALOGE("output file has already been set");
302        return INVALID_OPERATION;
303    }
304    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
305        ALOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
306        return INVALID_OPERATION;
307    }
308
309    // It appears that if an invalid file descriptor is passed through
310    // binder calls, the server-side of the inter-process function call
311    // is skipped. As a result, the check at the server-side to catch
312    // the invalid file descritpor never gets invoked. This is to workaround
313    // this issue by checking the file descriptor first before passing
314    // it through binder call.
315    if (fd < 0) {
316        ALOGE("Invalid file descriptor: %d", fd);
317        return BAD_VALUE;
318    }
319
320    status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
321    if (OK != ret) {
322        ALOGV("setOutputFile failed: %d", ret);
323        mCurrentState = MEDIA_RECORDER_ERROR;
324        return ret;
325    }
326    mIsOutputFileSet = true;
327    return ret;
328}
329
330status_t MediaRecorder::setVideoSize(int width, int height)
331{
332    ALOGV("setVideoSize(%d, %d)", width, height);
333    if (mMediaRecorder == NULL) {
334        ALOGE("media recorder is not initialized yet");
335        return INVALID_OPERATION;
336    }
337    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
338        ALOGE("setVideoSize called in an invalid state: %d", mCurrentState);
339        return INVALID_OPERATION;
340    }
341    if (!mIsVideoSourceSet) {
342        ALOGE("Cannot set video size without setting video source first");
343        return INVALID_OPERATION;
344    }
345
346    status_t ret = mMediaRecorder->setVideoSize(width, height);
347    if (OK != ret) {
348        ALOGE("setVideoSize failed: %d", ret);
349        mCurrentState = MEDIA_RECORDER_ERROR;
350        return ret;
351    }
352
353    return ret;
354}
355
356// Query a SurfaceMediaSurface through the Mediaserver, over the
357// binder interface. This is used by the Filter Framework (MediaEncoder)
358// to get an <IGraphicBufferProducer> object to hook up to ANativeWindow.
359sp<IGraphicBufferProducer> MediaRecorder::
360        querySurfaceMediaSourceFromMediaServer()
361{
362    Mutex::Autolock _l(mLock);
363    mSurfaceMediaSource =
364            mMediaRecorder->querySurfaceMediaSource();
365    if (mSurfaceMediaSource == NULL) {
366        ALOGE("SurfaceMediaSource could not be initialized!");
367    }
368    return mSurfaceMediaSource;
369}
370
371
372
373status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
374{
375    ALOGV("setVideoFrameRate(%d)", frames_per_second);
376    if (mMediaRecorder == NULL) {
377        ALOGE("media recorder is not initialized yet");
378        return INVALID_OPERATION;
379    }
380    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
381        ALOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState);
382        return INVALID_OPERATION;
383    }
384    if (!mIsVideoSourceSet) {
385        ALOGE("Cannot 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        ALOGE("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    ALOGV("setParameters(%s)", params.string());
400    if (mMediaRecorder == NULL) {
401        ALOGE("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        ALOGE("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        ALOGE("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    ALOGV("prepare");
428    if (mMediaRecorder == NULL) {
429        ALOGE("media recorder is not initialized yet");
430        return INVALID_OPERATION;
431    }
432    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
433        ALOGE("prepare called in an invalid state: %d", mCurrentState);
434        return INVALID_OPERATION;
435    }
436    if (mIsAudioSourceSet != mIsAudioEncoderSet) {
437        if (mIsAudioSourceSet) {
438            ALOGE("audio source is set, but audio encoder is not set");
439        } else {  // must not happen, since setAudioEncoder checks this already
440            ALOGE("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            ALOGE("video source is set, but video encoder is not set");
448        } else {  // must not happen, since setVideoEncoder checks this already
449            ALOGE("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        ALOGE("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    ALOGV("getMaxAmplitude");
467    if (mMediaRecorder == NULL) {
468        ALOGE("media recorder is not initialized yet");
469        return INVALID_OPERATION;
470    }
471    if (mCurrentState & MEDIA_RECORDER_ERROR) {
472        ALOGE("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        ALOGE("getMaxAmplitude failed: %d", ret);
479        mCurrentState = MEDIA_RECORDER_ERROR;
480        return ret;
481    }
482    return ret;
483}
484
485status_t MediaRecorder::start()
486{
487    ALOGV("start");
488    if (mMediaRecorder == NULL) {
489        ALOGE("media recorder is not initialized yet");
490        return INVALID_OPERATION;
491    }
492    if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
493        ALOGE("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        ALOGE("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    ALOGV("stop");
510    if (mMediaRecorder == NULL) {
511        ALOGE("media recorder is not initialized yet");
512        return INVALID_OPERATION;
513    }
514    if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
515        ALOGE("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        ALOGE("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    ALOGV("reset");
538    if (mMediaRecorder == NULL) {
539        ALOGE("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            ALOGE("Unexpected non-existing state: %d", mCurrentState);
565            break;
566        }
567    }
568    return ret;
569}
570
571status_t MediaRecorder::close()
572{
573    ALOGV("close");
574    if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
575        ALOGE("close called in an invalid state: %d", mCurrentState);
576        return INVALID_OPERATION;
577    }
578    status_t ret = mMediaRecorder->close();
579    if (OK != ret) {
580        ALOGE("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    ALOGV("doReset");
592    status_t ret = mMediaRecorder->reset();
593    if (OK != ret) {
594        ALOGE("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    ALOGV("doCleanUp");
606    mIsAudioSourceSet  = false;
607    mIsVideoSourceSet  = false;
608    mIsAudioEncoderSet = false;
609    mIsVideoEncoderSet = false;
610    mIsOutputFileSet   = false;
611}
612
613// Release should be OK in any state
614status_t MediaRecorder::release()
615{
616    ALOGV("release");
617    if (mMediaRecorder != NULL) {
618        return mMediaRecorder->release();
619    }
620    return INVALID_OPERATION;
621}
622
623MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL)
624{
625    ALOGV("constructor");
626
627    const sp<IMediaPlayerService>& service(getMediaPlayerService());
628    if (service != NULL) {
629        mMediaRecorder = service->createMediaRecorder();
630    }
631    if (mMediaRecorder != NULL) {
632        mCurrentState = MEDIA_RECORDER_IDLE;
633    }
634
635
636    doCleanUp();
637}
638
639status_t MediaRecorder::initCheck()
640{
641    return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
642}
643
644MediaRecorder::~MediaRecorder()
645{
646    ALOGV("destructor");
647    if (mMediaRecorder != NULL) {
648        mMediaRecorder.clear();
649    }
650
651    if (mSurfaceMediaSource != NULL) {
652        mSurfaceMediaSource.clear();
653    }
654}
655
656status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
657{
658    ALOGV("setListener");
659    Mutex::Autolock _l(mLock);
660    mListener = listener;
661
662    return NO_ERROR;
663}
664
665status_t MediaRecorder::setClientName(const String16& clientName)
666{
667    ALOGV("setClientName");
668    if (mMediaRecorder == NULL) {
669        ALOGE("media recorder is not initialized yet");
670        return INVALID_OPERATION;
671    }
672    bool isInvalidState = (mCurrentState &
673                           (MEDIA_RECORDER_PREPARED |
674                            MEDIA_RECORDER_RECORDING |
675                            MEDIA_RECORDER_ERROR));
676    if (isInvalidState) {
677        ALOGE("setClientName is called in an invalid state: %d", mCurrentState);
678        return INVALID_OPERATION;
679    }
680
681    mMediaRecorder->setClientName(clientName);
682
683    return NO_ERROR;
684}
685
686void MediaRecorder::notify(int msg, int ext1, int ext2)
687{
688    ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
689
690    sp<MediaRecorderListener> listener;
691    mLock.lock();
692    listener = mListener;
693    mLock.unlock();
694
695    if (listener != NULL) {
696        Mutex::Autolock _l(mNotifyLock);
697        ALOGV("callback application");
698        listener->notify(msg, ext1, ext2);
699        ALOGV("back from callback");
700    }
701}
702
703void MediaRecorder::died()
704{
705    ALOGV("died");
706    notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
707}
708
709}; // namespace android
710