Home | History | Annotate | Download | only in libaah_rtp
      1 /*
      2  * Copyright (C) 2011 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 #ifndef __AAH_RX_PLAYER_H__
     18 #define __AAH_RX_PLAYER_H__
     19 
     20 #include <common_time/cc_helper.h>
     21 #include <media/MediaPlayerInterface.h>
     22 #include <media/stagefright/foundation/ADebug.h>
     23 #include <media/stagefright/MediaBuffer.h>
     24 #include <media/stagefright/MediaSource.h>
     25 #include <media/stagefright/MetaData.h>
     26 #include <media/stagefright/OMXClient.h>
     27 #include <netinet/in.h>
     28 #include <utils/KeyedVector.h>
     29 #include <utils/LinearTransform.h>
     30 #include <utils/threads.h>
     31 
     32 #include "aah_decoder_pump.h"
     33 #include "pipe_event.h"
     34 
     35 namespace android {
     36 
     37 class AAH_RXPlayer : public MediaPlayerInterface {
     38   public:
     39     AAH_RXPlayer();
     40 
     41     virtual status_t    initCheck();
     42     virtual status_t    setDataSource(const char *url,
     43                                       const KeyedVector<String8, String8>*
     44                                       headers);
     45     virtual status_t    setDataSource(int fd, int64_t offset, int64_t length);
     46     virtual status_t    setVideoSurface(const sp<Surface>& surface);
     47     virtual status_t    setVideoSurfaceTexture(const sp<ISurfaceTexture>&
     48                                                surfaceTexture);
     49     virtual status_t    prepare();
     50     virtual status_t    prepareAsync();
     51     virtual status_t    start();
     52     virtual status_t    stop();
     53     virtual status_t    pause();
     54     virtual bool        isPlaying();
     55     virtual status_t    seekTo(int msec);
     56     virtual status_t    getCurrentPosition(int *msec);
     57     virtual status_t    getDuration(int *msec);
     58     virtual status_t    reset();
     59     virtual status_t    setLooping(int loop);
     60     virtual player_type playerType();
     61     virtual status_t    setParameter(int key, const Parcel &request);
     62     virtual status_t    getParameter(int key, Parcel *reply);
     63     virtual status_t    invoke(const Parcel& request, Parcel *reply);
     64 
     65   protected:
     66     virtual ~AAH_RXPlayer();
     67 
     68   private:
     69     class ThreadWrapper : public Thread {
     70       public:
     71         friend class AAH_RXPlayer;
     72         explicit ThreadWrapper(AAH_RXPlayer& player)
     73             : Thread(false /* canCallJava */ )
     74             , player_(player) { }
     75 
     76         virtual bool threadLoop() { return player_.threadLoop(); }
     77 
     78       private:
     79         AAH_RXPlayer& player_;
     80 
     81         DISALLOW_EVIL_CONSTRUCTORS(ThreadWrapper);
     82     };
     83 
     84 #pragma pack(push, 1)
     85     // PacketBuffers are structures used by the RX ring buffer.  The ring buffer
     86     // is a ring of pointers to PacketBuffer structures which act as variable
     87     // length byte arrays and hold the contents of received UDP packets.  Rather
     88     // than make this a structure which hold a length and a pointer to another
     89     // allocated structure (which would require two allocations), this struct
     90     // uses a structure overlay pattern where allocation for the byte array
     91     // consists of allocating (arrayLen + sizeof(ssize_t)) bytes of data from
     92     // whatever pool/heap the packet buffer pulls from, and then overlaying the
     93     // packed PacketBuffer structure on top of the allocation.  The one-byte
     94     // array at the end of the structure serves as an offset to the the data
     95     // portion of the allocation; packet buffers are never allocated on the
     96     // stack or using the new operator.  Instead, the static allocate-byte-array
     97     // and destroy methods handle the allocate and overlay pattern.  They also
     98     // allow for a potential future optimization where instead of just
     99     // allocating blocks from the process global heap and overlaying, the
    100     // allocator is replaced with a different implementation (private heap,
    101     // free-list, circular buffer, etc) which reduces potential heap
    102     // fragmentation issues which might arise from the frequent allocation and
    103     // destruction of the received UDP traffic.
    104     struct PacketBuffer {
    105         ssize_t length_;
    106         uint8_t data_[1];
    107 
    108         // TODO : consider changing this to be some form of ring buffer or free
    109         // pool system instead of just using the heap in order to avoid heap
    110         // fragmentation.
    111         static PacketBuffer* allocate(ssize_t length);
    112         static void destroy(PacketBuffer* pb);
    113 
    114       private:
    115         // Force people to use allocate/destroy instead of new/delete.
    116         PacketBuffer() { }
    117         ~PacketBuffer() { }
    118     };
    119 
    120     struct RetransRequest {
    121         uint32_t magic_;
    122         uint32_t mcast_ip_;
    123         uint16_t mcast_port_;
    124         uint16_t start_seq_;
    125         uint16_t end_seq_;
    126     };
    127 #pragma pack(pop)
    128 
    129     enum GapStatus {
    130         kGS_NoGap = 0,
    131         kGS_NormalGap,
    132         kGS_FastStartGap,
    133     };
    134 
    135     struct SeqNoGap {
    136         uint16_t start_seq_;
    137         uint16_t end_seq_;
    138     };
    139 
    140     class RXRingBuffer {
    141       public:
    142         explicit RXRingBuffer(uint32_t capacity);
    143         ~RXRingBuffer();
    144 
    145         bool initCheck() const { return (ring_ != NULL); }
    146         void reset();
    147 
    148         // Push a packet buffer with a given sequence number into the ring
    149         // buffer.  pushBuffer will always consume the buffer pushed to it,
    150         // either destroying it because it was a duplicate or overflow, or
    151         // holding on to it in the ring.  Callers should not hold any references
    152         // to PacketBuffers after they have been pushed to the ring.  Returns
    153         // false in the case of a serious error (such as ring overflow).
    154         // Callers should consider resetting the pipeline entirely in the event
    155         // of a serious error.
    156         bool pushBuffer(PacketBuffer* buf, uint16_t seq);
    157 
    158         // Fetch the next buffer in the RTP sequence.  Returns NULL if there is
    159         // no buffer to fetch.  If a non-NULL PacketBuffer is returned,
    160         // is_discon will be set to indicate whether or not this PacketBuffer is
    161         // discontiuous with any previously returned packet buffers.  Packet
    162         // buffers returned by fetchBuffer are the caller's responsibility; they
    163         // must be certain to destroy the buffers when they are done.
    164         PacketBuffer* fetchBuffer(bool* is_discon);
    165 
    166         // Returns true and fills out the gap structure if the read pointer of
    167         // the ring buffer is currently pointing to a gap which would stall a
    168         // fetchBuffer operation.  Returns false if the read pointer is not
    169         // pointing to a gap in the sequence currently.
    170         GapStatus fetchCurrentGap(SeqNoGap* gap);
    171 
    172         // Causes the read pointer to skip over any portion of a gap indicated
    173         // by nak.  If nak is NULL, any gap currently blocking the read pointer
    174         // will be completely skipped.  If any portion of a gap is skipped, the
    175         // next successful read from fetch buffer will indicate a discontinuity.
    176         void processNAK(const SeqNoGap* nak = NULL);
    177 
    178         // Compute the number of milliseconds until the inactivity timer for
    179         // this RTP stream.  Returns -1 if there is no active timeout, or 0 if
    180         // the system has already timed out.
    181         int computeInactivityTimeout();
    182 
    183       private:
    184         Mutex          lock_;
    185         PacketBuffer** ring_;
    186         uint32_t       capacity_;
    187         uint32_t       rd_;
    188         uint32_t       wr_;
    189 
    190         uint16_t       rd_seq_;
    191         bool           rd_seq_known_;
    192         bool           waiting_for_fast_start_;
    193         bool           fetched_first_packet_;
    194 
    195         uint64_t       rtp_activity_timeout_;
    196         bool           rtp_activity_timeout_valid_;
    197 
    198         DISALLOW_EVIL_CONSTRUCTORS(RXRingBuffer);
    199     };
    200 
    201     class Substream : public virtual RefBase {
    202       public:
    203         Substream(uint32_t ssrc, OMXClient& omx);
    204 
    205         void cleanupBufferInProgress();
    206         void shutdown();
    207         void processPayloadStart(uint8_t* buf,
    208                                  uint32_t amt,
    209                                  int32_t ts_lower);
    210         void processPayloadCont (uint8_t* buf,
    211                                  uint32_t amt);
    212         void processTSTransform(const LinearTransform& trans);
    213 
    214         bool     isAboutToUnderflow();
    215         uint32_t getSSRC()      const { return ssrc_; }
    216         uint16_t getProgramID() const { return (ssrc_ >> 5) & 0x1F; }
    217         status_t getStatus() const { return status_; }
    218 
    219       protected:
    220         virtual ~Substream();
    221 
    222       private:
    223         void                cleanupDecoder();
    224         bool                shouldAbort(const char* log_tag);
    225         void                processCompletedBuffer();
    226         bool                setupSubstreamMeta();
    227         bool                setupMP3SubstreamMeta();
    228         bool                setupAACSubstreamMeta();
    229         bool                setupSubstreamType(uint8_t substream_type,
    230                                                uint8_t codec_type);
    231 
    232         uint32_t            ssrc_;
    233         bool                waiting_for_rap_;
    234         status_t            status_;
    235 
    236         bool                substream_details_known_;
    237         uint8_t             substream_type_;
    238         uint8_t             codec_type_;
    239         const char*         codec_mime_type_;
    240         sp<MetaData>        substream_meta_;
    241 
    242         MediaBuffer*        buffer_in_progress_;
    243         uint32_t            expected_buffer_size_;
    244         uint32_t            buffer_filled_;
    245 
    246         Vector<uint8_t>     aux_data_in_progress_;
    247         uint32_t            aux_data_expected_size_;
    248 
    249         sp<AAH_DecoderPump> decoder_;
    250 
    251         static int64_t      kAboutToUnderflowThreshold;
    252 
    253         DISALLOW_EVIL_CONSTRUCTORS(Substream);
    254     };
    255 
    256     typedef DefaultKeyedVector< uint32_t, sp<Substream> > SubstreamVec;
    257 
    258     status_t            startWorkThread();
    259     void                stopWorkThread();
    260     virtual bool        threadLoop();
    261     bool                setupSocket();
    262     void                cleanupSocket();
    263     void                resetPipeline();
    264     void                reset_l();
    265     bool                processRX(PacketBuffer* pb);
    266     void                processRingBuffer();
    267     void                processCommandPacket(PacketBuffer* pb);
    268     bool                processGaps();
    269     int                 computeNextGapRetransmitTimeout();
    270     void                fetchAudioFlinger();
    271 
    272     PipeEvent           wakeup_work_thread_evt_;
    273     sp<ThreadWrapper>   thread_wrapper_;
    274     Mutex               api_lock_;
    275     bool                is_playing_;
    276     bool                data_source_set_;
    277 
    278     struct sockaddr_in  listen_addr_;
    279     int                 sock_fd_;
    280     bool                multicast_joined_;
    281 
    282     struct sockaddr_in  transmitter_addr_;
    283     bool                transmitter_known_;
    284 
    285     uint32_t            current_epoch_;
    286     bool                current_epoch_known_;
    287 
    288     SeqNoGap            current_gap_;
    289     GapStatus           current_gap_status_;
    290     uint64_t            next_retrans_req_time_;
    291 
    292     RXRingBuffer        ring_buffer_;
    293     SubstreamVec        substreams_;
    294     OMXClient           omx_;
    295     CCHelper            cc_helper_;
    296 
    297     // Connection to audio flinger used to hack a path to setMasterVolume.
    298     sp<IAudioFlinger>   audio_flinger_;
    299 
    300     static const uint32_t kRTPRingBufferSize;
    301     static const uint32_t kRetransRequestMagic;
    302     static const uint32_t kFastStartRequestMagic;
    303     static const uint32_t kRetransNAKMagic;
    304     static const uint32_t kGapRerequestTimeoutUSec;
    305     static const uint32_t kFastStartTimeoutUSec;
    306     static const uint32_t kRTPActivityTimeoutUSec;
    307 
    308     static const uint32_t INVOKE_GET_MASTER_VOLUME = 3;
    309     static const uint32_t INVOKE_SET_MASTER_VOLUME = 4;
    310 
    311     static uint64_t monotonicUSecNow();
    312 
    313     DISALLOW_EVIL_CONSTRUCTORS(AAH_RXPlayer);
    314 };
    315 
    316 }  // namespace android
    317 
    318 #endif  // __AAH_RX_PLAYER_H__
    319