Home | History | Annotate | Download | only in libmedia
      1 /*
      2 **
      3 ** Copyright 2007, 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_TAG "IAudioTrack"
     19 //#define LOG_NDEBUG 0
     20 #include <utils/Log.h>
     21 
     22 #include <stdint.h>
     23 #include <sys/types.h>
     24 
     25 #include <binder/Parcel.h>
     26 
     27 #include <media/IAudioTrack.h>
     28 
     29 namespace android {
     30 
     31 enum {
     32     GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
     33     START,
     34     STOP,
     35     FLUSH,
     36     RESERVED, // was MUTE
     37     PAUSE,
     38     ATTACH_AUX_EFFECT,
     39     ALLOCATE_TIMED_BUFFER,
     40     QUEUE_TIMED_BUFFER,
     41     SET_MEDIA_TIME_TRANSFORM,
     42 };
     43 
     44 class BpAudioTrack : public BpInterface<IAudioTrack>
     45 {
     46 public:
     47     BpAudioTrack(const sp<IBinder>& impl)
     48         : BpInterface<IAudioTrack>(impl)
     49     {
     50     }
     51 
     52     virtual sp<IMemory> getCblk() const
     53     {
     54         Parcel data, reply;
     55         sp<IMemory> cblk;
     56         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     57         status_t status = remote()->transact(GET_CBLK, data, &reply);
     58         if (status == NO_ERROR) {
     59             cblk = interface_cast<IMemory>(reply.readStrongBinder());
     60         }
     61         return cblk;
     62     }
     63 
     64     virtual status_t start()
     65     {
     66         Parcel data, reply;
     67         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     68         status_t status = remote()->transact(START, data, &reply);
     69         if (status == NO_ERROR) {
     70             status = reply.readInt32();
     71         } else {
     72             ALOGW("start() error: %s", strerror(-status));
     73         }
     74         return status;
     75     }
     76 
     77     virtual void stop()
     78     {
     79         Parcel data, reply;
     80         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     81         remote()->transact(STOP, data, &reply);
     82     }
     83 
     84     virtual void flush()
     85     {
     86         Parcel data, reply;
     87         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     88         remote()->transact(FLUSH, data, &reply);
     89     }
     90 
     91     virtual void pause()
     92     {
     93         Parcel data, reply;
     94         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
     95         remote()->transact(PAUSE, data, &reply);
     96     }
     97 
     98     virtual status_t attachAuxEffect(int effectId)
     99     {
    100         Parcel data, reply;
    101         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
    102         data.writeInt32(effectId);
    103         status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
    104         if (status == NO_ERROR) {
    105             status = reply.readInt32();
    106         } else {
    107             ALOGW("attachAuxEffect() error: %s", strerror(-status));
    108         }
    109         return status;
    110     }
    111 
    112     virtual status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer) {
    113         Parcel data, reply;
    114         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
    115         data.writeInt32(size);
    116         status_t status = remote()->transact(ALLOCATE_TIMED_BUFFER,
    117                                              data, &reply);
    118         if (status == NO_ERROR) {
    119             status = reply.readInt32();
    120             if (status == NO_ERROR) {
    121                 *buffer = interface_cast<IMemory>(reply.readStrongBinder());
    122             }
    123         }
    124         return status;
    125     }
    126 
    127     virtual status_t queueTimedBuffer(const sp<IMemory>& buffer,
    128                                       int64_t pts) {
    129         Parcel data, reply;
    130         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
    131         data.writeStrongBinder(buffer->asBinder());
    132         data.writeInt64(pts);
    133         status_t status = remote()->transact(QUEUE_TIMED_BUFFER,
    134                                              data, &reply);
    135         if (status == NO_ERROR) {
    136             status = reply.readInt32();
    137         }
    138         return status;
    139     }
    140 
    141     virtual status_t setMediaTimeTransform(const LinearTransform& xform,
    142                                            int target) {
    143         Parcel data, reply;
    144         data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
    145         data.writeInt64(xform.a_zero);
    146         data.writeInt64(xform.b_zero);
    147         data.writeInt32(xform.a_to_b_numer);
    148         data.writeInt32(xform.a_to_b_denom);
    149         data.writeInt32(target);
    150         status_t status = remote()->transact(SET_MEDIA_TIME_TRANSFORM,
    151                                              data, &reply);
    152         if (status == NO_ERROR) {
    153             status = reply.readInt32();
    154         }
    155         return status;
    156     }
    157 };
    158 
    159 IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
    160 
    161 // ----------------------------------------------------------------------
    162 
    163 status_t BnAudioTrack::onTransact(
    164     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    165 {
    166     switch (code) {
    167         case GET_CBLK: {
    168             CHECK_INTERFACE(IAudioTrack, data, reply);
    169             reply->writeStrongBinder(getCblk()->asBinder());
    170             return NO_ERROR;
    171         } break;
    172         case START: {
    173             CHECK_INTERFACE(IAudioTrack, data, reply);
    174             reply->writeInt32(start());
    175             return NO_ERROR;
    176         } break;
    177         case STOP: {
    178             CHECK_INTERFACE(IAudioTrack, data, reply);
    179             stop();
    180             return NO_ERROR;
    181         } break;
    182         case FLUSH: {
    183             CHECK_INTERFACE(IAudioTrack, data, reply);
    184             flush();
    185             return NO_ERROR;
    186         } break;
    187         case PAUSE: {
    188             CHECK_INTERFACE(IAudioTrack, data, reply);
    189             pause();
    190             return NO_ERROR;
    191         }
    192         case ATTACH_AUX_EFFECT: {
    193             CHECK_INTERFACE(IAudioTrack, data, reply);
    194             reply->writeInt32(attachAuxEffect(data.readInt32()));
    195             return NO_ERROR;
    196         } break;
    197         case ALLOCATE_TIMED_BUFFER: {
    198             CHECK_INTERFACE(IAudioTrack, data, reply);
    199             sp<IMemory> buffer;
    200             status_t status = allocateTimedBuffer(data.readInt32(), &buffer);
    201             reply->writeInt32(status);
    202             if (status == NO_ERROR) {
    203                 reply->writeStrongBinder(buffer->asBinder());
    204             }
    205             return NO_ERROR;
    206         } break;
    207         case QUEUE_TIMED_BUFFER: {
    208             CHECK_INTERFACE(IAudioTrack, data, reply);
    209             sp<IMemory> buffer = interface_cast<IMemory>(
    210                 data.readStrongBinder());
    211             uint64_t pts = data.readInt64();
    212             reply->writeInt32(queueTimedBuffer(buffer, pts));
    213             return NO_ERROR;
    214         } break;
    215         case SET_MEDIA_TIME_TRANSFORM: {
    216             CHECK_INTERFACE(IAudioTrack, data, reply);
    217             LinearTransform xform;
    218             xform.a_zero = data.readInt64();
    219             xform.b_zero = data.readInt64();
    220             xform.a_to_b_numer = data.readInt32();
    221             xform.a_to_b_denom = data.readInt32();
    222             int target = data.readInt32();
    223             reply->writeInt32(setMediaTimeTransform(xform, target));
    224             return NO_ERROR;
    225         } break;
    226         default:
    227             return BBinder::onTransact(code, data, reply, flags);
    228     }
    229 }
    230 
    231 }; // namespace android
    232