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