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