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