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