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