Home | History | Annotate | Download | only in stagefright
      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 // This class provides a way to split a single media source into multiple sources.
     18 // The constructor takes in the real mediaSource and createClient() can then be
     19 // used to create multiple sources served from this real mediaSource.
     20 //
     21 // Usage:
     22 // - Create MediaSourceSplitter by passing in a real mediaSource from which
     23 // multiple duplicate channels are needed.
     24 // - Create a client using createClient() and use it as any other mediaSource.
     25 //
     26 // Note that multiple clients can be created using createClient() and
     27 // started/stopped in any order. MediaSourceSplitter stops the real source only
     28 // when all clients have been stopped.
     29 //
     30 // If a new client is created/started after some existing clients have already
     31 // started, the new client will start getting its read frames from the current
     32 // time.
     33 
     34 #ifndef MEDIA_SOURCE_SPLITTER_H_
     35 
     36 #define MEDIA_SOURCE_SPLITTER_H_
     37 
     38 #include <media/stagefright/MediaSource.h>
     39 #include <utils/threads.h>
     40 #include <utils/Vector.h>
     41 #include <utils/RefBase.h>
     42 
     43 namespace android {
     44 
     45 class MediaBuffer;
     46 class MetaData;
     47 
     48 class MediaSourceSplitter : public RefBase {
     49 public:
     50     // Constructor
     51     // mediaSource: The real mediaSource. The class keeps a reference to it to
     52     // implement the various clients.
     53     MediaSourceSplitter(sp<MediaSource> mediaSource);
     54 
     55     ~MediaSourceSplitter();
     56 
     57     // Creates a new client of base type MediaSource. Multiple clients can be
     58     // created which get their data through the same real mediaSource. These
     59     // clients can then be used like any other MediaSource, all of which provide
     60     // data from the same real source.
     61     sp<MediaSource> createClient();
     62 
     63 private:
     64     // Total number of clients created through createClient().
     65     int32_t mNumberOfClients;
     66 
     67     // reference to the real MediaSource passed to the constructor.
     68     sp<MediaSource> mSource;
     69 
     70     // Stores pointer to the MediaBuffer read from the real MediaSource.
     71     // All clients use this to implement the read() call.
     72     MediaBuffer *mLastReadMediaBuffer;
     73 
     74     // Status code for read from the real MediaSource. All clients return
     75     // this for their read().
     76     status_t mLastReadStatus;
     77 
     78     // Boolean telling whether the real MediaSource has started.
     79     bool mSourceStarted;
     80 
     81     // List of booleans, one for each client, storing whether the corresponding
     82     // client's start() has been called.
     83     Vector<bool> mClientsStarted;
     84 
     85     // Stores the number of clients which are currently started.
     86     int32_t mNumberOfClientsStarted;
     87 
     88     // Since different clients call read() asynchronously, we need to keep track
     89     // of what data is currently read into the mLastReadMediaBuffer.
     90     // mCurrentReadBit stores the bit for the current read buffer. This bit
     91     // flips each time a new buffer is read from the source.
     92     // mClientsDesiredReadBit stores the bit for the next desired read buffer
     93     // for each client. This bit flips each time read() is completed for this
     94     // client.
     95     bool mCurrentReadBit;
     96     Vector<bool> mClientsDesiredReadBit;
     97 
     98     // Number of clients whose current read has been completed.
     99     int32_t mNumberOfCurrentReads;
    100 
    101     // Boolean telling whether the last read has been completed for all clients.
    102     // The variable is reset to false each time buffer is read from the real
    103     // source.
    104     bool mLastReadCompleted;
    105 
    106     // A global mutex for access to critical sections.
    107     Mutex mLock;
    108 
    109     // Condition variable for waiting on read from source to complete.
    110     Condition mReadFromSourceCondition;
    111 
    112     // Condition variable for waiting on all client's last read to complete.
    113     Condition mAllReadsCompleteCondition;
    114 
    115     // Functions used by Client to implement the MediaSource interface.
    116 
    117     // If the real source has not been started yet by any client, starts it.
    118     status_t start(int clientId, MetaData *params);
    119 
    120     // Stops the real source after all clients have called stop().
    121     status_t stop(int clientId);
    122 
    123     // returns the real source's getFormat().
    124     sp<MetaData> getFormat(int clientId);
    125 
    126     // If the client's desired buffer has already been read into
    127     // mLastReadMediaBuffer, points the buffer to that. Otherwise if it is the
    128     // master client, reads the buffer from source or else waits for the master
    129     // client to read the buffer and uses that.
    130     status_t read(int clientId,
    131             MediaBuffer **buffer, const MediaSource::ReadOptions *options = NULL);
    132 
    133     // Not implemented right now.
    134     status_t pause(int clientId);
    135 
    136     // Function which reads a buffer from the real source into
    137     // mLastReadMediaBuffer
    138     void readFromSource_lock(const MediaSource::ReadOptions *options);
    139 
    140     // Waits until read from the real source has been completed.
    141     // _lock means that the function should be called when the thread has already
    142     // obtained the lock for the mutex mLock.
    143     void waitForReadFromSource_lock(int32_t clientId);
    144 
    145     // Waits until all clients have read the current buffer in
    146     // mLastReadCompleted.
    147     void waitForAllClientsLastRead_lock(int32_t clientId);
    148 
    149     // Each client calls this after it completes its read(). Once all clients
    150     // have called this for the current buffer, the function calls
    151     // mAllReadsCompleteCondition.broadcast() to signal the waiting clients.
    152     void signalReadComplete_lock(bool readAborted);
    153 
    154     // Make these constructors private.
    155     MediaSourceSplitter();
    156     MediaSourceSplitter(const MediaSourceSplitter &);
    157     MediaSourceSplitter &operator=(const MediaSourceSplitter &);
    158 
    159     // This class implements the MediaSource interface. Each client stores a
    160     // reference to the parent MediaSourceSplitter and uses it to complete the
    161     // various calls.
    162     class Client : public MediaSource {
    163     public:
    164         // Constructor stores reference to the parent MediaSourceSplitter and it
    165         // client id.
    166         Client(sp<MediaSourceSplitter> splitter, int32_t clientId);
    167 
    168         // MediaSource interface
    169         virtual status_t start(MetaData *params = NULL);
    170 
    171         virtual status_t stop();
    172 
    173         virtual sp<MetaData> getFormat();
    174 
    175         virtual status_t read(
    176                 MediaBuffer **buffer, const ReadOptions *options = NULL);
    177 
    178         virtual status_t pause();
    179 
    180     private:
    181         // Refernce to the parent MediaSourceSplitter
    182         sp<MediaSourceSplitter> mSplitter;
    183 
    184         // Id of this client.
    185         int32_t mClientId;
    186     };
    187 
    188     friend class Client;
    189 };
    190 
    191 }  // namespace android
    192 
    193 #endif  // MEDIA_SOURCE_SPLITTER_H_
    194