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