blob: 6b26faf7361350259ba38dd6e4ab08691d2b18c7 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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 <ui/Surface.h>
22#include <media/mediarecorder.h>
23#include <utils/IServiceManager.h>
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -070024#include <utils/String8.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025#include <media/IMediaPlayerService.h>
26#include <media/IMediaRecorder.h>
27
28namespace android {
29
30status_t MediaRecorder::setCamera(const sp<ICamera>& camera)
31{
32 LOGV("setCamera(%p)", camera.get());
33 if(mMediaRecorder == NULL) {
34 LOGE("media recorder is not initialized yet");
35 return INVALID_OPERATION;
36 }
37 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
38 LOGE("setCamera called in an invalid state(%d)", mCurrentState);
39 return INVALID_OPERATION;
40 }
41
42 status_t ret = mMediaRecorder->setCamera(camera);
43 if (OK != ret) {
44 LOGV("setCamera failed: %d", ret);
45 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080046 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 }
48 return ret;
49}
50
51status_t MediaRecorder::setPreviewSurface(const sp<Surface>& surface)
52{
53 LOGV("setPreviewSurface(%p)", surface.get());
54 if(mMediaRecorder == NULL) {
55 LOGE("media recorder is not initialized yet");
56 return INVALID_OPERATION;
57 }
58 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
59 LOGE("setPreviewSurface called in an invalid state(%d)", mCurrentState);
60 return INVALID_OPERATION;
61 }
62 if (!mIsVideoSourceSet) {
63 LOGE("try to set preview surface without setting the video source first");
64 return INVALID_OPERATION;
65 }
66
67 status_t ret = mMediaRecorder->setPreviewSurface(surface->getISurface());
68 if (OK != ret) {
69 LOGV("setPreviewSurface failed: %d", ret);
70 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080071 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 }
73 return ret;
74}
75
76status_t MediaRecorder::init()
77{
78 LOGV("init");
79 if(mMediaRecorder == NULL) {
80 LOGE("media recorder is not initialized yet");
81 return INVALID_OPERATION;
82 }
83 if (!(mCurrentState & MEDIA_RECORDER_IDLE)) {
84 LOGE("init called in an invalid state(%d)", mCurrentState);
85 return INVALID_OPERATION;
86 }
87
88 status_t ret = mMediaRecorder->init();
89 if (OK != ret) {
90 LOGV("init failed: %d", ret);
91 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080092 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 }
94
95 ret = mMediaRecorder->setListener(this);
96 if (OK != ret) {
97 LOGV("setListener failed: %d", ret);
98 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -080099 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 }
101
102 mCurrentState = MEDIA_RECORDER_INITIALIZED;
103 return ret;
104}
105
106status_t MediaRecorder::setVideoSource(int vs)
107{
108 LOGV("setVideoSource(%d)", vs);
109 if(mMediaRecorder == NULL) {
110 LOGE("media recorder is not initialized yet");
111 return INVALID_OPERATION;
112 }
113 if (mIsVideoSourceSet) {
114 LOGE("video source has already been set");
115 return INVALID_OPERATION;
116 }
117 if (mCurrentState & MEDIA_RECORDER_IDLE) {
118 LOGV("Call init() since the media recorder is not initialized yet");
119 status_t ret = init();
120 if (OK != ret) {
121 return ret;
122 }
123 }
124 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
125 LOGE("setVideoSource called in an invalid state(%d)", mCurrentState);
126 return INVALID_OPERATION;
127 }
128
129 status_t ret = mMediaRecorder->setVideoSource(vs);
130 if (OK != ret) {
131 LOGV("setVideoSource failed: %d", ret);
132 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800133 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 }
135 mIsVideoSourceSet = true;
136 return ret;
137}
138
139status_t MediaRecorder::setAudioSource(int as)
140{
141 LOGV("setAudioSource(%d)", as);
142 if(mMediaRecorder == NULL) {
143 LOGE("media recorder is not initialized yet");
144 return INVALID_OPERATION;
145 }
146 if (mCurrentState & MEDIA_RECORDER_IDLE) {
147 LOGV("Call init() since the media recorder is not initialized yet");
148 status_t ret = init();
149 if (OK != ret) {
150 return ret;
151 }
152 }
153 if (mIsAudioSourceSet) {
154 LOGE("audio source has already been set");
155 return INVALID_OPERATION;
156 }
157 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
158 LOGE("setAudioSource called in an invalid state(%d)", mCurrentState);
159 return INVALID_OPERATION;
160 }
161
162 status_t ret = mMediaRecorder->setAudioSource(as);
163 if (OK != ret) {
164 LOGV("setAudioSource failed: %d", ret);
165 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800166 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 }
168 mIsAudioSourceSet = true;
169 return ret;
170}
171
172status_t MediaRecorder::setOutputFormat(int of)
173{
174 LOGV("setOutputFormat(%d)", of);
175 if(mMediaRecorder == NULL) {
176 LOGE("media recorder is not initialized yet");
177 return INVALID_OPERATION;
178 }
179 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
180 LOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
181 return INVALID_OPERATION;
182 }
183 if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_RAW_AMR) {
184 LOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of);
185 return INVALID_OPERATION;
186 }
187
188 status_t ret = mMediaRecorder->setOutputFormat(of);
189 if (OK != ret) {
190 LOGE("setOutputFormat failed: %d", ret);
191 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800192 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 }
194 mCurrentState = MEDIA_RECORDER_DATASOURCE_CONFIGURED;
195 return ret;
196}
197
198status_t MediaRecorder::setVideoEncoder(int ve)
199{
200 LOGV("setVideoEncoder(%d)", ve);
201 if(mMediaRecorder == NULL) {
202 LOGE("media recorder is not initialized yet");
203 return INVALID_OPERATION;
204 }
205 if (!mIsVideoSourceSet) {
206 LOGE("try to set the video encoder without setting the video source first");
207 return INVALID_OPERATION;
208 }
209 if (mIsVideoEncoderSet) {
210 LOGE("video encoder has already been set");
211 return INVALID_OPERATION;
212 }
213 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
214 LOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);
215 return INVALID_OPERATION;
216 }
217
218 status_t ret = mMediaRecorder->setVideoEncoder(ve);
219 if (OK != ret) {
220 LOGV("setVideoEncoder failed: %d", ret);
221 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800222 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 }
224 mIsVideoEncoderSet = true;
225 return ret;
226}
227
228status_t MediaRecorder::setAudioEncoder(int ae)
229{
230 LOGV("setAudioEncoder(%d)", ae);
231 if(mMediaRecorder == NULL) {
232 LOGE("media recorder is not initialized yet");
233 return INVALID_OPERATION;
234 }
235 if (!mIsAudioSourceSet) {
236 LOGE("try to set the audio encoder without setting the audio source first");
237 return INVALID_OPERATION;
238 }
239 if (mIsAudioEncoderSet) {
240 LOGE("audio encoder has already been set");
241 return INVALID_OPERATION;
242 }
243 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
244 LOGE("setAudioEncoder called in an invalid state(%d)", mCurrentState);
245 return INVALID_OPERATION;
246 }
247
248 status_t ret = mMediaRecorder->setAudioEncoder(ae);
249 if (OK != ret) {
250 LOGV("setAudioEncoder failed: %d", ret);
251 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800252 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 }
254 mIsAudioEncoderSet = true;
255 return ret;
256}
257
258status_t MediaRecorder::setOutputFile(const char* path)
259{
260 LOGV("setOutputFile(%s)", path);
261 if(mMediaRecorder == NULL) {
262 LOGE("media recorder is not initialized yet");
263 return INVALID_OPERATION;
264 }
265 if (mIsOutputFileSet) {
266 LOGE("output file has already been set");
267 return INVALID_OPERATION;
268 }
269 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
270 LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
271 return INVALID_OPERATION;
272 }
273
274 status_t ret = mMediaRecorder->setOutputFile(path);
275 if (OK != ret) {
276 LOGV("setOutputFile failed: %d", ret);
277 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800278 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 }
280 mIsOutputFileSet = true;
281 return ret;
282}
283
284status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
285{
286 LOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length);
287 if(mMediaRecorder == NULL) {
288 LOGE("media recorder is not initialized yet");
289 return INVALID_OPERATION;
290 }
291 if (mIsOutputFileSet) {
292 LOGE("output file has already been set");
293 return INVALID_OPERATION;
294 }
295 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
296 LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
297 return INVALID_OPERATION;
298 }
299
300 status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
301 if (OK != ret) {
302 LOGV("setOutputFile failed: %d", ret);
303 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800304 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 }
306 mIsOutputFileSet = true;
307 return ret;
308}
309
310status_t MediaRecorder::setVideoSize(int width, int height)
311{
312 LOGV("setVideoSize(%d, %d)", width, height);
313 if(mMediaRecorder == NULL) {
314 LOGE("media recorder is not initialized yet");
315 return INVALID_OPERATION;
316 }
317 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
318 LOGE("setVideoSize called in an invalid state: %d", mCurrentState);
319 return INVALID_OPERATION;
320 }
321 if (!mIsVideoSourceSet) {
322 LOGE("try to set video size without setting video source first");
323 return INVALID_OPERATION;
324 }
325
326 status_t ret = mMediaRecorder->setVideoSize(width, height);
327 if (OK != ret) {
328 LOGE("setVideoSize failed: %d", ret);
329 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800330 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 }
332 return ret;
333}
334
335status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
336{
337 LOGV("setVideoFrameRate(%d)", frames_per_second);
338 if(mMediaRecorder == NULL) {
339 LOGE("media recorder is not initialized yet");
340 return INVALID_OPERATION;
341 }
342 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
343 LOGE("setVideoFrameRate called in an invalid state: %d", mCurrentState);
344 return INVALID_OPERATION;
345 }
346 if (!mIsVideoSourceSet) {
347 LOGE("try to set video frame rate without setting video source first");
348 return INVALID_OPERATION;
349 }
350
351 status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second);
352 if (OK != ret) {
353 LOGE("setVideoFrameRate failed: %d", ret);
354 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800355 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 }
357 return ret;
358}
359
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700360status_t MediaRecorder::setParameters(const String8& params) {
361 LOGV("setParameters(%s)", params.string());
362 if(mMediaRecorder == NULL) {
363 LOGE("media recorder is not initialized yet");
364 return INVALID_OPERATION;
365 }
366
367 status_t ret = mMediaRecorder->setParameters(params);
368 if (OK != ret) {
369 LOGE("setParameters(%s) failed: %d", params.string(), ret);
The Android Open Source Project10592532009-03-18 17:39:46 -0700370 // Do not change our current state to MEDIA_RECORDER_ERROR, failures
371 // of the only currently supported parameters, "max-duration" and
372 // "max-filesize" are _not_ fatal.
The Android Open Source Projectba87e3e2009-03-13 13:04:22 -0700373 }
374
375 return ret;
376}
377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378status_t MediaRecorder::prepare()
379{
380 LOGV("prepare");
381 if(mMediaRecorder == NULL) {
382 LOGE("media recorder is not initialized yet");
383 return INVALID_OPERATION;
384 }
385 if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
386 LOGE("prepare called in an invalid state: %d", mCurrentState);
387 return INVALID_OPERATION;
388 }
389 if (mIsAudioSourceSet != mIsAudioEncoderSet) {
390 if (mIsAudioSourceSet) {
391 LOGE("audio source is set, but audio encoder is not set");
392 } else { // must not happen, since setAudioEncoder checks this already
393 LOGE("audio encoder is set, but audio source is not set");
394 }
395 return INVALID_OPERATION;
396 }
397
398 if (mIsVideoSourceSet != mIsVideoEncoderSet) {
399 if (mIsVideoSourceSet) {
400 LOGE("video source is set, but video encoder is not set");
401 } else { // must not happen, since setVideoEncoder checks this already
402 LOGE("video encoder is set, but video source is not set");
403 }
404 return INVALID_OPERATION;
405 }
406
407 status_t ret = mMediaRecorder->prepare();
408 if (OK != ret) {
409 LOGE("prepare failed: %d", ret);
410 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800411 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 }
413 mCurrentState = MEDIA_RECORDER_PREPARED;
414 return ret;
415}
416
417status_t MediaRecorder::getMaxAmplitude(int* max)
418{
419 LOGV("getMaxAmplitude");
420 if(mMediaRecorder == NULL) {
421 LOGE("media recorder is not initialized yet");
422 return INVALID_OPERATION;
423 }
424 if (mCurrentState & MEDIA_RECORDER_ERROR) {
425 LOGE("getMaxAmplitude called in an invalid state: %d", mCurrentState);
426 return INVALID_OPERATION;
427 }
428
429 status_t ret = mMediaRecorder->getMaxAmplitude(max);
430 if (OK != ret) {
431 LOGE("getMaxAmplitude failed: %d", ret);
432 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800433 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 }
435 return ret;
436}
437
438status_t MediaRecorder::start()
439{
440 LOGV("start");
441 if (mMediaRecorder == NULL) {
442 LOGE("media recorder is not initialized yet");
443 return INVALID_OPERATION;
444 }
445 if (!(mCurrentState & MEDIA_RECORDER_PREPARED)) {
446 LOGE("start called in an invalid state: %d", mCurrentState);
447 return INVALID_OPERATION;
448 }
449
450 status_t ret = mMediaRecorder->start();
451 if (OK != ret) {
452 LOGE("start failed: %d", ret);
453 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800454 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 }
456 mCurrentState = MEDIA_RECORDER_RECORDING;
457 return ret;
458}
459
460status_t MediaRecorder::stop()
461{
462 LOGV("stop");
463 if (mMediaRecorder == NULL) {
464 LOGE("media recorder is not initialized yet");
465 return INVALID_OPERATION;
466 }
467 if (!(mCurrentState & MEDIA_RECORDER_RECORDING)) {
468 LOGE("stop called in an invalid state: %d", mCurrentState);
469 return INVALID_OPERATION;
470 }
471
472 status_t ret = mMediaRecorder->stop();
473 if (OK != ret) {
474 LOGE("stop failed: %d", ret);
475 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800476 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700478
479 // FIXME:
480 // stop and reset are semantically different.
481 // We treat them the same for now, and will change this in the future.
482 doCleanUp();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 mCurrentState = MEDIA_RECORDER_IDLE;
484 return ret;
485}
486
487// Reset should be OK in any state
488status_t MediaRecorder::reset()
489{
490 LOGV("reset");
491 if (mMediaRecorder == NULL) {
492 LOGE("media recorder is not initialized yet");
493 return INVALID_OPERATION;
494 }
495
496 doCleanUp();
497 status_t ret = UNKNOWN_ERROR;
498 switch(mCurrentState) {
499 case MEDIA_RECORDER_IDLE:
500 ret = OK;
501 break;
502
503 case MEDIA_RECORDER_RECORDING:
504 case MEDIA_RECORDER_DATASOURCE_CONFIGURED:
505 case MEDIA_RECORDER_PREPARED:
506 case MEDIA_RECORDER_ERROR: {
507 ret = doReset();
508 if (OK != ret) {
509 return ret; // No need to continue
510 }
511 } // Intentional fall through
512 case MEDIA_RECORDER_INITIALIZED:
513 ret = close();
514 break;
515
516 default: {
517 LOGE("Unexpected non-existing state: %d", mCurrentState);
518 break;
519 }
520 }
521 return ret;
522}
523
524status_t MediaRecorder::close()
525{
526 LOGV("close");
527 if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED)) {
528 LOGE("close called in an invalid state: %d", mCurrentState);
529 return INVALID_OPERATION;
530 }
531 status_t ret = mMediaRecorder->close();
532 if (OK != ret) {
533 LOGE("close failed: %d", ret);
534 mCurrentState = MEDIA_RECORDER_ERROR;
535 return UNKNOWN_ERROR;
536 } else {
537 mCurrentState = MEDIA_RECORDER_IDLE;
538 }
539 return ret;
540}
541
542status_t MediaRecorder::doReset()
543{
544 LOGV("doReset");
545 status_t ret = mMediaRecorder->reset();
546 if (OK != ret) {
547 LOGE("doReset failed: %d", ret);
548 mCurrentState = MEDIA_RECORDER_ERROR;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800549 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 } else {
551 mCurrentState = MEDIA_RECORDER_INITIALIZED;
552 }
553 return ret;
554}
555
556void MediaRecorder::doCleanUp()
557{
558 LOGV("doCleanUp");
559 mIsAudioSourceSet = false;
560 mIsVideoSourceSet = false;
561 mIsAudioEncoderSet = false;
562 mIsVideoEncoderSet = false;
563 mIsOutputFileSet = false;
564}
565
566// Release should be OK in any state
567status_t MediaRecorder::release()
568{
569 LOGV("release");
570 if (mMediaRecorder != NULL) {
571 return mMediaRecorder->release();
572 }
573 return INVALID_OPERATION;
574}
575
576MediaRecorder::MediaRecorder()
577{
578 LOGV("constructor");
579 sp<IServiceManager> sm = defaultServiceManager();
580 sp<IBinder> binder;
581
582 do {
583 binder = sm->getService(String16("media.player"));
584 if (binder != NULL) {
585 break;
586 }
587 LOGW("MediaPlayerService not published, waiting...");
588 usleep(500000); // 0.5 s
589 } while(true);
590
591 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
592 if (service != NULL) {
593 mMediaRecorder = service->createMediaRecorder(getpid());
594 }
595 if (mMediaRecorder != NULL) {
596 mCurrentState = MEDIA_RECORDER_IDLE;
597 }
598 doCleanUp();
599}
600
601status_t MediaRecorder::initCheck()
602{
603 return mMediaRecorder != 0 ? NO_ERROR : NO_INIT;
604}
605
606MediaRecorder::~MediaRecorder()
607{
608 LOGV("destructor");
609 if (mMediaRecorder != NULL) {
610 mMediaRecorder.clear();
611 }
612}
613
614status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
615{
616 LOGV("setListener");
617 Mutex::Autolock _l(mLock);
618 mListener = listener;
619
620 return NO_ERROR;
621}
622
623void MediaRecorder::notify(int msg, int ext1, int ext2)
624{
625 LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
626
627 sp<MediaRecorderListener> listener;
628 mLock.lock();
629 listener = mListener;
630 mLock.unlock();
631
632 if (listener != NULL) {
633 Mutex::Autolock _l(mNotifyLock);
634 LOGV("callback application");
635 listener->notify(msg, ext1, ext2);
636 LOGV("back from callback");
637 }
638}
639
640}; // namespace android
641