• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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