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