• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ISurfaceTexture.h>
28 
29 namespace android {
30 
setCamera(const sp<ICamera> & camera,const sp<ICameraRecordingProxy> & proxy)31 status_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 
setPreviewSurface(const sp<Surface> & surface)52 status_t MediaRecorder::setPreviewSurface(const sp<Surface>& 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 
init()77 status_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 
setVideoSource(int vs)107 status_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 
setAudioSource(int as)142 status_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 
setOutputFormat(int of)175 status_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 
setVideoEncoder(int ve)201 status_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 
setAudioEncoder(int ae)231 status_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 
setOutputFile(const char * path)261 status_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 
setOutputFile(int fd,int64_t offset,int64_t length)287 status_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 
setVideoSize(int width,int height)324 status_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 (MeidaEncoder)
352 // to get an <ISurfaceTexture> object to hook up to ANativeWindow.
353 sp<ISurfaceTexture> MediaRecorder::
querySurfaceMediaSourceFromMediaServer()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 
setVideoFrameRate(int frames_per_second)367 status_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 
setParameters(const String8 & params)392 status_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 
prepare()419 status_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 
getMaxAmplitude(int * max)458 status_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 
start()479 status_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 
stop()501 status_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
reset()529 status_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 
close()565 status_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 
doReset()583 status_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 
doCleanUp()597 void 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
release()608 status_t MediaRecorder::release()
609 {
610     ALOGV("release");
611     if (mMediaRecorder != NULL) {
612         return mMediaRecorder->release();
613     }
614     return INVALID_OPERATION;
615 }
616 
MediaRecorder()617 MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL)
618 {
619     ALOGV("constructor");
620 
621     const sp<IMediaPlayerService>& service(getMediaPlayerService());
622     if (service != NULL) {
623         mMediaRecorder = service->createMediaRecorder(getpid());
624     }
625     if (mMediaRecorder != NULL) {
626         mCurrentState = MEDIA_RECORDER_IDLE;
627     }
628 
629 
630     doCleanUp();
631 }
632 
initCheck()633 status_t MediaRecorder::initCheck()
634 {
635     return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
636 }
637 
~MediaRecorder()638 MediaRecorder::~MediaRecorder()
639 {
640     ALOGV("destructor");
641     if (mMediaRecorder != NULL) {
642         mMediaRecorder.clear();
643     }
644 
645     if (mSurfaceMediaSource != NULL) {
646         mSurfaceMediaSource.clear();
647     }
648 }
649 
setListener(const sp<MediaRecorderListener> & listener)650 status_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 
notify(int msg,int ext1,int ext2)659 void MediaRecorder::notify(int msg, int ext1, int ext2)
660 {
661     ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
662 
663     sp<MediaRecorderListener> listener;
664     mLock.lock();
665     listener = mListener;
666     mLock.unlock();
667 
668     if (listener != NULL) {
669         Mutex::Autolock _l(mNotifyLock);
670         ALOGV("callback application");
671         listener->notify(msg, ext1, ext2);
672         ALOGV("back from callback");
673     }
674 }
675 
died()676 void MediaRecorder::died()
677 {
678     ALOGV("died");
679     notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
680 }
681 
682 }; // namespace android
683