1 /*
2 **
3 ** Copyright 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 "IMediaRecorder"
20
21 #include <inttypes.h>
22 #include <unistd.h>
23
24 #include <utils/Log.h>
25 #include <binder/Parcel.h>
26 #include <camera/android/hardware/ICamera.h>
27 #include <camera/ICameraRecordingProxy.h>
28 #include <media/IMediaRecorderClient.h>
29 #include <media/IMediaRecorder.h>
30 #include <gui/Surface.h>
31 #include <gui/IGraphicBufferProducer.h>
32 #include <media/stagefright/PersistentSurface.h>
33
34 namespace android {
35
36 enum {
37 RELEASE = IBinder::FIRST_CALL_TRANSACTION,
38 INIT,
39 CLOSE,
40 SET_INPUT_SURFACE,
41 QUERY_SURFACE_MEDIASOURCE,
42 RESET,
43 STOP,
44 START,
45 PREPARE,
46 GET_MAX_AMPLITUDE,
47 SET_VIDEO_SOURCE,
48 SET_AUDIO_SOURCE,
49 SET_OUTPUT_FORMAT,
50 SET_VIDEO_ENCODER,
51 SET_AUDIO_ENCODER,
52 SET_OUTPUT_FILE_FD,
53 SET_NEXT_OUTPUT_FILE_FD,
54 SET_VIDEO_SIZE,
55 SET_VIDEO_FRAMERATE,
56 SET_PARAMETERS,
57 SET_PREVIEW_SURFACE,
58 SET_CAMERA,
59 SET_LISTENER,
60 SET_CLIENT_NAME,
61 PAUSE,
62 RESUME,
63 GET_METRICS,
64
65 };
66
67 class BpMediaRecorder: public BpInterface<IMediaRecorder>
68 {
69 public:
BpMediaRecorder(const sp<IBinder> & impl)70 explicit BpMediaRecorder(const sp<IBinder>& impl)
71 : BpInterface<IMediaRecorder>(impl)
72 {
73 }
74
setCamera(const sp<hardware::ICamera> & camera,const sp<ICameraRecordingProxy> & proxy)75 status_t setCamera(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
76 {
77 ALOGV("setCamera(%p,%p)", camera.get(), proxy.get());
78 Parcel data, reply;
79 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
80 data.writeStrongBinder(IInterface::asBinder(camera));
81 data.writeStrongBinder(IInterface::asBinder(proxy));
82 remote()->transact(SET_CAMERA, data, &reply);
83 return reply.readInt32();
84 }
85
setInputSurface(const sp<PersistentSurface> & surface)86 status_t setInputSurface(const sp<PersistentSurface>& surface)
87 {
88 ALOGV("setInputSurface(%p)", surface.get());
89 Parcel data, reply;
90 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
91 surface->writeToParcel(&data);
92 remote()->transact(SET_INPUT_SURFACE, data, &reply);
93 return reply.readInt32();
94 }
95
querySurfaceMediaSource()96 sp<IGraphicBufferProducer> querySurfaceMediaSource()
97 {
98 ALOGV("Query SurfaceMediaSource");
99 Parcel data, reply;
100 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
101 remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply);
102 int returnedNull = reply.readInt32();
103 if (returnedNull) {
104 return NULL;
105 }
106 return interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
107 }
108
setPreviewSurface(const sp<IGraphicBufferProducer> & surface)109 status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface)
110 {
111 ALOGV("setPreviewSurface(%p)", surface.get());
112 Parcel data, reply;
113 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
114 data.writeStrongBinder(IInterface::asBinder(surface));
115 remote()->transact(SET_PREVIEW_SURFACE, data, &reply);
116 return reply.readInt32();
117 }
118
init()119 status_t init()
120 {
121 ALOGV("init");
122 Parcel data, reply;
123 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
124 remote()->transact(INIT, data, &reply);
125 return reply.readInt32();
126 }
127
setVideoSource(int vs)128 status_t setVideoSource(int vs)
129 {
130 ALOGV("setVideoSource(%d)", vs);
131 Parcel data, reply;
132 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
133 data.writeInt32(vs);
134 remote()->transact(SET_VIDEO_SOURCE, data, &reply);
135 return reply.readInt32();
136 }
137
setAudioSource(int as)138 status_t setAudioSource(int as)
139 {
140 ALOGV("setAudioSource(%d)", as);
141 Parcel data, reply;
142 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
143 data.writeInt32(as);
144 remote()->transact(SET_AUDIO_SOURCE, data, &reply);
145 return reply.readInt32();
146 }
147
setOutputFormat(int of)148 status_t setOutputFormat(int of)
149 {
150 ALOGV("setOutputFormat(%d)", of);
151 Parcel data, reply;
152 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
153 data.writeInt32(of);
154 remote()->transact(SET_OUTPUT_FORMAT, data, &reply);
155 return reply.readInt32();
156 }
157
setVideoEncoder(int ve)158 status_t setVideoEncoder(int ve)
159 {
160 ALOGV("setVideoEncoder(%d)", ve);
161 Parcel data, reply;
162 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
163 data.writeInt32(ve);
164 remote()->transact(SET_VIDEO_ENCODER, data, &reply);
165 return reply.readInt32();
166 }
167
setAudioEncoder(int ae)168 status_t setAudioEncoder(int ae)
169 {
170 ALOGV("setAudioEncoder(%d)", ae);
171 Parcel data, reply;
172 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
173 data.writeInt32(ae);
174 remote()->transact(SET_AUDIO_ENCODER, data, &reply);
175 return reply.readInt32();
176 }
177
setOutputFile(int fd)178 status_t setOutputFile(int fd) {
179 ALOGV("setOutputFile(%d)", fd);
180 Parcel data, reply;
181 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
182 data.writeFileDescriptor(fd);
183 remote()->transact(SET_OUTPUT_FILE_FD, data, &reply);
184 return reply.readInt32();
185 }
186
setNextOutputFile(int fd)187 status_t setNextOutputFile(int fd) {
188 ALOGV("setNextOutputFile(%d)", fd);
189 Parcel data, reply;
190 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
191 data.writeFileDescriptor(fd);
192 remote()->transact(SET_NEXT_OUTPUT_FILE_FD, data, &reply);
193 return reply.readInt32();
194 }
195
setVideoSize(int width,int height)196 status_t setVideoSize(int width, int height)
197 {
198 ALOGV("setVideoSize(%dx%d)", width, height);
199 Parcel data, reply;
200 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
201 data.writeInt32(width);
202 data.writeInt32(height);
203 remote()->transact(SET_VIDEO_SIZE, data, &reply);
204 return reply.readInt32();
205 }
206
setVideoFrameRate(int frames_per_second)207 status_t setVideoFrameRate(int frames_per_second)
208 {
209 ALOGV("setVideoFrameRate(%d)", frames_per_second);
210 Parcel data, reply;
211 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
212 data.writeInt32(frames_per_second);
213 remote()->transact(SET_VIDEO_FRAMERATE, data, &reply);
214 return reply.readInt32();
215 }
216
setParameters(const String8 & params)217 status_t setParameters(const String8& params)
218 {
219 ALOGV("setParameter(%s)", params.string());
220 Parcel data, reply;
221 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
222 data.writeString8(params);
223 remote()->transact(SET_PARAMETERS, data, &reply);
224 return reply.readInt32();
225 }
226
setListener(const sp<IMediaRecorderClient> & listener)227 status_t setListener(const sp<IMediaRecorderClient>& listener)
228 {
229 ALOGV("setListener(%p)", listener.get());
230 Parcel data, reply;
231 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
232 data.writeStrongBinder(IInterface::asBinder(listener));
233 remote()->transact(SET_LISTENER, data, &reply);
234 return reply.readInt32();
235 }
236
setClientName(const String16 & clientName)237 status_t setClientName(const String16& clientName)
238 {
239 ALOGV("setClientName(%s)", String8(clientName).string());
240 Parcel data, reply;
241 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
242 data.writeString16(clientName);
243 remote()->transact(SET_CLIENT_NAME, data, &reply);
244 return reply.readInt32();
245 }
246
prepare()247 status_t prepare()
248 {
249 ALOGV("prepare");
250 Parcel data, reply;
251 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
252 remote()->transact(PREPARE, data, &reply);
253 return reply.readInt32();
254 }
255
getMaxAmplitude(int * max)256 status_t getMaxAmplitude(int* max)
257 {
258 ALOGV("getMaxAmplitude");
259 Parcel data, reply;
260 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
261 remote()->transact(GET_MAX_AMPLITUDE, data, &reply);
262 *max = reply.readInt32();
263 return reply.readInt32();
264 }
265
getMetrics(Parcel * reply)266 status_t getMetrics(Parcel* reply)
267 {
268 ALOGV("getMetrics");
269 Parcel data;
270 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
271 status_t ret = remote()->transact(GET_METRICS, data, reply);
272 if (ret == NO_ERROR) {
273 return OK;
274 }
275 return UNKNOWN_ERROR;
276 }
277
start()278 status_t start()
279 {
280 ALOGV("start");
281 Parcel data, reply;
282 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
283 remote()->transact(START, data, &reply);
284 return reply.readInt32();
285 }
286
stop()287 status_t stop()
288 {
289 ALOGV("stop");
290 Parcel data, reply;
291 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
292 remote()->transact(STOP, data, &reply);
293 return reply.readInt32();
294 }
295
reset()296 status_t reset()
297 {
298 ALOGV("reset");
299 Parcel data, reply;
300 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
301 remote()->transact(RESET, data, &reply);
302 return reply.readInt32();
303 }
304
pause()305 status_t pause()
306 {
307 ALOGV("pause");
308 Parcel data, reply;
309 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
310 remote()->transact(PAUSE, data, &reply);
311 return reply.readInt32();
312 }
313
resume()314 status_t resume()
315 {
316 ALOGV("resume");
317 Parcel data, reply;
318 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
319 remote()->transact(RESUME, data, &reply);
320 return reply.readInt32();
321 }
322
close()323 status_t close()
324 {
325 ALOGV("close");
326 Parcel data, reply;
327 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
328 remote()->transact(CLOSE, data, &reply);
329 return reply.readInt32();
330 }
331
release()332 status_t release()
333 {
334 ALOGV("release");
335 Parcel data, reply;
336 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
337 remote()->transact(RELEASE, data, &reply);
338 return reply.readInt32();
339 }
340 };
341
342 IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder");
343
344 // ----------------------------------------------------------------------
345
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)346 status_t BnMediaRecorder::onTransact(
347 uint32_t code, const Parcel& data, Parcel* reply,
348 uint32_t flags)
349 {
350 switch (code) {
351 case RELEASE: {
352 ALOGV("RELEASE");
353 CHECK_INTERFACE(IMediaRecorder, data, reply);
354 reply->writeInt32(release());
355 return NO_ERROR;
356 } break;
357 case INIT: {
358 ALOGV("INIT");
359 CHECK_INTERFACE(IMediaRecorder, data, reply);
360 reply->writeInt32(init());
361 return NO_ERROR;
362 } break;
363 case CLOSE: {
364 ALOGV("CLOSE");
365 CHECK_INTERFACE(IMediaRecorder, data, reply);
366 reply->writeInt32(close());
367 return NO_ERROR;
368 } break;
369 case RESET: {
370 ALOGV("RESET");
371 CHECK_INTERFACE(IMediaRecorder, data, reply);
372 reply->writeInt32(reset());
373 return NO_ERROR;
374 } break;
375 case STOP: {
376 ALOGV("STOP");
377 CHECK_INTERFACE(IMediaRecorder, data, reply);
378 reply->writeInt32(stop());
379 return NO_ERROR;
380 } break;
381 case START: {
382 ALOGV("START");
383 CHECK_INTERFACE(IMediaRecorder, data, reply);
384 reply->writeInt32(start());
385 return NO_ERROR;
386 } break;
387 case PAUSE: {
388 ALOGV("PAUSE");
389 CHECK_INTERFACE(IMediaRecorder, data, reply);
390 reply->writeInt32(pause());
391 return NO_ERROR;
392 } break;
393 case RESUME: {
394 ALOGV("RESUME");
395 CHECK_INTERFACE(IMediaRecorder, data, reply);
396 reply->writeInt32(resume());
397 return NO_ERROR;
398 } break;
399 case PREPARE: {
400 ALOGV("PREPARE");
401 CHECK_INTERFACE(IMediaRecorder, data, reply);
402 reply->writeInt32(prepare());
403 return NO_ERROR;
404 } break;
405 case GET_MAX_AMPLITUDE: {
406 ALOGV("GET_MAX_AMPLITUDE");
407 CHECK_INTERFACE(IMediaRecorder, data, reply);
408 int max = 0;
409 status_t ret = getMaxAmplitude(&max);
410 reply->writeInt32(max);
411 reply->writeInt32(ret);
412 return NO_ERROR;
413 } break;
414 case GET_METRICS: {
415 ALOGV("GET_METRICS");
416 status_t ret = getMetrics(reply);
417 return ret;
418 } break;
419 case SET_VIDEO_SOURCE: {
420 ALOGV("SET_VIDEO_SOURCE");
421 CHECK_INTERFACE(IMediaRecorder, data, reply);
422 int vs = data.readInt32();
423 reply->writeInt32(setVideoSource(vs));
424 return NO_ERROR;
425 } break;
426 case SET_AUDIO_SOURCE: {
427 ALOGV("SET_AUDIO_SOURCE");
428 CHECK_INTERFACE(IMediaRecorder, data, reply);
429 int as = data.readInt32();
430 reply->writeInt32(setAudioSource(as));
431 return NO_ERROR;
432 } break;
433 case SET_OUTPUT_FORMAT: {
434 ALOGV("SET_OUTPUT_FORMAT");
435 CHECK_INTERFACE(IMediaRecorder, data, reply);
436 int of = data.readInt32();
437 reply->writeInt32(setOutputFormat(of));
438 return NO_ERROR;
439 } break;
440 case SET_VIDEO_ENCODER: {
441 ALOGV("SET_VIDEO_ENCODER");
442 CHECK_INTERFACE(IMediaRecorder, data, reply);
443 int ve = data.readInt32();
444 reply->writeInt32(setVideoEncoder(ve));
445 return NO_ERROR;
446 } break;
447 case SET_AUDIO_ENCODER: {
448 ALOGV("SET_AUDIO_ENCODER");
449 CHECK_INTERFACE(IMediaRecorder, data, reply);
450 int ae = data.readInt32();
451 reply->writeInt32(setAudioEncoder(ae));
452 return NO_ERROR;
453
454 } break;
455 case SET_OUTPUT_FILE_FD: {
456 ALOGV("SET_OUTPUT_FILE_FD");
457 CHECK_INTERFACE(IMediaRecorder, data, reply);
458 int fd = dup(data.readFileDescriptor());
459 reply->writeInt32(setOutputFile(fd));
460 ::close(fd);
461 return NO_ERROR;
462 } break;
463 case SET_NEXT_OUTPUT_FILE_FD: {
464 ALOGV("SET_NEXT_OUTPUT_FILE_FD");
465 CHECK_INTERFACE(IMediaRecorder, data, reply);
466 int fd = dup(data.readFileDescriptor());
467 reply->writeInt32(setNextOutputFile(fd));
468 ::close(fd);
469 return NO_ERROR;
470 } break;
471 case SET_VIDEO_SIZE: {
472 ALOGV("SET_VIDEO_SIZE");
473 CHECK_INTERFACE(IMediaRecorder, data, reply);
474 int width = data.readInt32();
475 int height = data.readInt32();
476 reply->writeInt32(setVideoSize(width, height));
477 return NO_ERROR;
478 } break;
479 case SET_VIDEO_FRAMERATE: {
480 ALOGV("SET_VIDEO_FRAMERATE");
481 CHECK_INTERFACE(IMediaRecorder, data, reply);
482 int frames_per_second = data.readInt32();
483 reply->writeInt32(setVideoFrameRate(frames_per_second));
484 return NO_ERROR;
485 } break;
486 case SET_PARAMETERS: {
487 ALOGV("SET_PARAMETER");
488 CHECK_INTERFACE(IMediaRecorder, data, reply);
489 reply->writeInt32(setParameters(data.readString8()));
490 return NO_ERROR;
491 } break;
492 case SET_LISTENER: {
493 ALOGV("SET_LISTENER");
494 CHECK_INTERFACE(IMediaRecorder, data, reply);
495 sp<IMediaRecorderClient> listener =
496 interface_cast<IMediaRecorderClient>(data.readStrongBinder());
497 reply->writeInt32(setListener(listener));
498 return NO_ERROR;
499 } break;
500 case SET_CLIENT_NAME: {
501 ALOGV("SET_CLIENT_NAME");
502 CHECK_INTERFACE(IMediaRecorder, data, reply);
503 reply->writeInt32(setClientName(data.readString16()));
504 return NO_ERROR;
505 }
506 case SET_PREVIEW_SURFACE: {
507 ALOGV("SET_PREVIEW_SURFACE");
508 CHECK_INTERFACE(IMediaRecorder, data, reply);
509 sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(
510 data.readStrongBinder());
511 reply->writeInt32(setPreviewSurface(surface));
512 return NO_ERROR;
513 } break;
514 case SET_CAMERA: {
515 ALOGV("SET_CAMERA");
516 CHECK_INTERFACE(IMediaRecorder, data, reply);
517 sp<hardware::ICamera> camera =
518 interface_cast<hardware::ICamera>(data.readStrongBinder());
519 sp<ICameraRecordingProxy> proxy =
520 interface_cast<ICameraRecordingProxy>(data.readStrongBinder());
521 reply->writeInt32(setCamera(camera, proxy));
522 return NO_ERROR;
523 } break;
524 case SET_INPUT_SURFACE: {
525 ALOGV("SET_INPUT_SURFACE");
526 CHECK_INTERFACE(IMediaRecorder, data, reply);
527 sp<PersistentSurface> surface = new PersistentSurface();
528 surface->readFromParcel(&data);
529 reply->writeInt32(setInputSurface(surface));
530 return NO_ERROR;
531 } break;
532 case QUERY_SURFACE_MEDIASOURCE: {
533 ALOGV("QUERY_SURFACE_MEDIASOURCE");
534 CHECK_INTERFACE(IMediaRecorder, data, reply);
535 // call the mediaserver side to create
536 // a surfacemediasource
537 sp<IGraphicBufferProducer> surfaceMediaSource = querySurfaceMediaSource();
538 // The mediaserver might have failed to create a source
539 int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ;
540 reply->writeInt32(returnedNull);
541 if (!returnedNull) {
542 reply->writeStrongBinder(IInterface::asBinder(surfaceMediaSource));
543 }
544 return NO_ERROR;
545 } break;
546 default:
547 return BBinder::onTransact(code, data, reply, flags);
548 }
549 }
550
551 // ----------------------------------------------------------------------------
552
553 } // namespace android
554