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