Home | History | Annotate | Download | only in cast
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "media/cast/cast_receiver_impl.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback.h"
      9 #include "base/logging.h"
     10 #include "base/message_loop/message_loop.h"
     11 
     12 namespace media {
     13 namespace cast {
     14 
     15 // The video and audio receivers should only be called from the main thread.
     16 // LocalFrameReciever posts tasks to the main thread, making the cast interface
     17 // thread safe.
     18 class LocalFrameReceiver : public FrameReceiver {
     19  public:
     20   LocalFrameReceiver(scoped_refptr<CastEnvironment> cast_environment,
     21                      AudioReceiver* audio_receiver,
     22                      VideoReceiver* video_receiver)
     23       : cast_environment_(cast_environment),
     24         audio_receiver_(audio_receiver),
     25         video_receiver_(video_receiver) {}
     26 
     27   virtual void GetRawVideoFrame(
     28       const VideoFrameDecodedCallback& callback) OVERRIDE {
     29     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
     30         base::Bind(&VideoReceiver::GetRawVideoFrame,
     31                    video_receiver_->AsWeakPtr(), callback));
     32   }
     33 
     34   virtual void GetEncodedVideoFrame(
     35       const VideoFrameEncodedCallback& callback) OVERRIDE {
     36     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
     37         base::Bind(&VideoReceiver::GetEncodedVideoFrame,
     38                    video_receiver_->AsWeakPtr(), callback));
     39   }
     40 
     41   virtual void GetRawAudioFrame(
     42       int number_of_10ms_blocks,
     43       int desired_frequency,
     44       const AudioFrameDecodedCallback& callback) OVERRIDE {
     45     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, base::Bind(
     46         &AudioReceiver::GetRawAudioFrame, audio_receiver_->AsWeakPtr(),
     47         number_of_10ms_blocks, desired_frequency, callback));
     48   }
     49 
     50   virtual void GetCodedAudioFrame(
     51       const AudioFrameEncodedCallback& callback) OVERRIDE {
     52     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
     53         base::Bind(&AudioReceiver::GetEncodedAudioFrame,
     54                    audio_receiver_->AsWeakPtr(), callback));
     55   }
     56 
     57  protected:
     58   virtual ~LocalFrameReceiver() {}
     59 
     60  private:
     61   friend class base::RefCountedThreadSafe<LocalFrameReceiver>;
     62 
     63   scoped_refptr<CastEnvironment> cast_environment_;
     64   AudioReceiver* audio_receiver_;
     65   VideoReceiver* video_receiver_;
     66 };
     67 
     68 // The video and audio receivers should only be called from the main thread.
     69 class LocalPacketReceiver : public PacketReceiver {
     70  public:
     71   LocalPacketReceiver(scoped_refptr<CastEnvironment> cast_environment,
     72                       AudioReceiver* audio_receiver,
     73                       VideoReceiver* video_receiver,
     74                       uint32 ssrc_of_audio_sender,
     75                       uint32 ssrc_of_video_sender)
     76       : cast_environment_(cast_environment),
     77         audio_receiver_(audio_receiver),
     78         video_receiver_(video_receiver),
     79         ssrc_of_audio_sender_(ssrc_of_audio_sender),
     80         ssrc_of_video_sender_(ssrc_of_video_sender) {}
     81 
     82   virtual void ReceivedPacket(const uint8* packet,
     83                               size_t length,
     84                               const base::Closure callback) OVERRIDE {
     85     if (length < kMinLengthOfRtcp) {
     86       // No action; just log and call the callback informing that we are done
     87       // with the packet.
     88       VLOG(1) << "Received a packet which is too short " << length;
     89       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
     90       return;
     91     }
     92     uint32 ssrc_of_sender;
     93     if (!Rtcp::IsRtcpPacket(packet, length)) {
     94       if (length < kMinLengthOfRtp) {
     95         // No action; just log and call the callback informing that we are done
     96         // with the packet.
     97         VLOG(1) << "Received a RTP packet which is too short " << length;
     98         cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
     99         return;
    100       }
    101       ssrc_of_sender = RtpReceiver::GetSsrcOfSender(packet, length);
    102     } else {
    103       ssrc_of_sender = Rtcp::GetSsrcOfSender(packet, length);
    104     }
    105     if (ssrc_of_sender == ssrc_of_audio_sender_) {
    106       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
    107           base::Bind(&AudioReceiver::IncomingPacket,
    108                      audio_receiver_->AsWeakPtr(), packet, length, callback));
    109     } else if (ssrc_of_sender == ssrc_of_video_sender_) {
    110       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
    111           base::Bind(&VideoReceiver::IncomingPacket,
    112                      video_receiver_->AsWeakPtr(), packet, length, callback));
    113     } else {
    114       // No action; just log and call the callback informing that we are done
    115       // with the packet.
    116       VLOG(1) << "Received a packet with a non matching sender SSRC "
    117               << ssrc_of_sender;
    118 
    119       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
    120     }
    121   }
    122 
    123  protected:
    124   virtual ~LocalPacketReceiver() {}
    125 
    126  private:
    127   friend class base::RefCountedThreadSafe<LocalPacketReceiver>;
    128 
    129   scoped_refptr<CastEnvironment> cast_environment_;
    130   AudioReceiver* audio_receiver_;
    131   VideoReceiver* video_receiver_;
    132   const uint32 ssrc_of_audio_sender_;
    133   const uint32 ssrc_of_video_sender_;
    134 };
    135 
    136 CastReceiver* CastReceiver::CreateCastReceiver(
    137     scoped_refptr<CastEnvironment> cast_environment,
    138     const AudioReceiverConfig& audio_config,
    139     const VideoReceiverConfig& video_config,
    140     PacketSender* const packet_sender) {
    141   return new CastReceiverImpl(cast_environment,
    142                               audio_config,
    143                               video_config,
    144                               packet_sender);
    145 }
    146 
    147 CastReceiverImpl::CastReceiverImpl(
    148     scoped_refptr<CastEnvironment> cast_environment,
    149     const AudioReceiverConfig& audio_config,
    150     const VideoReceiverConfig& video_config,
    151     PacketSender* const packet_sender)
    152     : pacer_(cast_environment, packet_sender),
    153       audio_receiver_(cast_environment, audio_config, &pacer_),
    154       video_receiver_(cast_environment, video_config, &pacer_),
    155       frame_receiver_(new LocalFrameReceiver(cast_environment,
    156                                              &audio_receiver_,
    157                                              &video_receiver_)),
    158       packet_receiver_(new LocalPacketReceiver(cast_environment,
    159                                                &audio_receiver_,
    160                                                &video_receiver_,
    161                                                audio_config.incoming_ssrc,
    162                                                video_config.incoming_ssrc)) {}
    163 
    164 CastReceiverImpl::~CastReceiverImpl() {}
    165 
    166 scoped_refptr<PacketReceiver> CastReceiverImpl::packet_receiver() {
    167   return packet_receiver_;
    168 }
    169 
    170 scoped_refptr<FrameReceiver> CastReceiverImpl::frame_receiver() {
    171   return frame_receiver_;
    172 }
    173 
    174 }  // namespace cast
    175 }  // namespace media
    176