Home | History | Annotate | Download | only in libmedia
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "IStreamSource"
     19 #include <utils/Log.h>
     20 
     21 #include <media/IStreamSource.h>
     22 #include <media/stagefright/foundation/AMessage.h>
     23 
     24 #include <binder/IMemory.h>
     25 #include <binder/Parcel.h>
     26 
     27 namespace android {
     28 
     29 // static
     30 const char *const IStreamListener::kKeyResumeAtPTS = "resume-at-PTS";
     31 
     32 // static
     33 const char *const IStreamListener::kKeyDiscontinuityMask = "discontinuity-mask";
     34 
     35 // static
     36 const char *const IStreamListener::kKeyMediaTimeUs = "media-time-us";
     37 
     38 enum {
     39     // IStreamSource
     40     SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
     41     SET_BUFFERS,
     42     ON_BUFFER_AVAILABLE,
     43     FLAGS,
     44 
     45     // IStreamListener
     46     QUEUE_BUFFER,
     47     ISSUE_COMMAND,
     48 };
     49 
     50 struct BpStreamSource : public BpInterface<IStreamSource> {
     51     BpStreamSource(const sp<IBinder> &impl)
     52         : BpInterface<IStreamSource>(impl) {
     53     }
     54 
     55     virtual void setListener(const sp<IStreamListener> &listener) {
     56         Parcel data, reply;
     57         data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
     58         data.writeStrongBinder(listener->asBinder());
     59         remote()->transact(SET_LISTENER, data, &reply);
     60     }
     61 
     62     virtual void setBuffers(const Vector<sp<IMemory> > &buffers) {
     63         Parcel data, reply;
     64         data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
     65         data.writeInt32(static_cast<int32_t>(buffers.size()));
     66         for (size_t i = 0; i < buffers.size(); ++i) {
     67             data.writeStrongBinder(buffers.itemAt(i)->asBinder());
     68         }
     69         remote()->transact(SET_BUFFERS, data, &reply);
     70     }
     71 
     72     virtual void onBufferAvailable(size_t index) {
     73         Parcel data, reply;
     74         data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
     75         data.writeInt32(static_cast<int32_t>(index));
     76         remote()->transact(
     77                 ON_BUFFER_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
     78     }
     79 
     80     virtual uint32_t flags() const {
     81         Parcel data, reply;
     82         data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
     83         remote()->transact(FLAGS, data, &reply);
     84 
     85         return reply.readInt32();
     86     }
     87 };
     88 
     89 IMPLEMENT_META_INTERFACE(StreamSource, "android.hardware.IStreamSource");
     90 
     91 status_t BnStreamSource::onTransact(
     92         uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
     93     switch (code) {
     94         case SET_LISTENER:
     95         {
     96             CHECK_INTERFACE(IStreamSource, data, reply);
     97             setListener(
     98                     interface_cast<IStreamListener>(data.readStrongBinder()));
     99             break;
    100         }
    101 
    102         case SET_BUFFERS:
    103         {
    104             CHECK_INTERFACE(IStreamSource, data, reply);
    105             size_t n = static_cast<size_t>(data.readInt32());
    106             Vector<sp<IMemory> > buffers;
    107             for (size_t i = 0; i < n; ++i) {
    108                 sp<IMemory> mem =
    109                     interface_cast<IMemory>(data.readStrongBinder());
    110 
    111                 buffers.push(mem);
    112             }
    113             setBuffers(buffers);
    114             break;
    115         }
    116 
    117         case ON_BUFFER_AVAILABLE:
    118         {
    119             CHECK_INTERFACE(IStreamSource, data, reply);
    120             onBufferAvailable(static_cast<size_t>(data.readInt32()));
    121             break;
    122         }
    123 
    124         case FLAGS:
    125         {
    126             CHECK_INTERFACE(IStreamSource, data, reply);
    127             reply->writeInt32(this->flags());
    128             break;
    129         }
    130 
    131         default:
    132             return BBinder::onTransact(code, data, reply, flags);
    133     }
    134 
    135     return OK;
    136 }
    137 
    138 ////////////////////////////////////////////////////////////////////////////////
    139 
    140 struct BpStreamListener : public BpInterface<IStreamListener> {
    141     BpStreamListener(const sp<IBinder> &impl)
    142         : BpInterface<IStreamListener>(impl) {
    143     }
    144 
    145     virtual void queueBuffer(size_t index, size_t size) {
    146         Parcel data, reply;
    147         data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
    148         data.writeInt32(static_cast<int32_t>(index));
    149         data.writeInt32(static_cast<int32_t>(size));
    150 
    151         remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
    152     }
    153 
    154     virtual void issueCommand(
    155             Command cmd, bool synchronous, const sp<AMessage> &msg) {
    156         Parcel data, reply;
    157         data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
    158         data.writeInt32(static_cast<int32_t>(cmd));
    159         data.writeInt32(static_cast<int32_t>(synchronous));
    160 
    161         if (msg != NULL) {
    162             data.writeInt32(1);
    163             msg->writeToParcel(&data);
    164         } else {
    165             data.writeInt32(0);
    166         }
    167 
    168         remote()->transact(ISSUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY);
    169     }
    170 };
    171 
    172 IMPLEMENT_META_INTERFACE(StreamListener, "android.hardware.IStreamListener");
    173 
    174 status_t BnStreamListener::onTransact(
    175         uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
    176     switch (code) {
    177         case QUEUE_BUFFER:
    178         {
    179             CHECK_INTERFACE(IStreamListener, data, reply);
    180             size_t index = static_cast<size_t>(data.readInt32());
    181             size_t size = static_cast<size_t>(data.readInt32());
    182 
    183             queueBuffer(index, size);
    184             break;
    185         }
    186 
    187         case ISSUE_COMMAND:
    188         {
    189             CHECK_INTERFACE(IStreamListener, data, reply);
    190             Command cmd = static_cast<Command>(data.readInt32());
    191 
    192             bool synchronous = static_cast<bool>(data.readInt32());
    193 
    194             sp<AMessage> msg;
    195 
    196             if (data.readInt32()) {
    197                 msg = AMessage::FromParcel(data);
    198             }
    199 
    200             issueCommand(cmd, synchronous, msg);
    201             break;
    202         }
    203 
    204         default:
    205             return BBinder::onTransact(code, data, reply, flags);
    206     }
    207 
    208     return OK;
    209 }
    210 
    211 }  // namespace android
    212