Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / media / cast / cast_receiver_impl.cc
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 callback should not be used, as the receiver is using the external
16 // transport. Implementation is required as the pacer is common to sender and
17 // receiver.
18 static void DoNothingCastTransportStatus(transport::CastTransportStatus status)
19 {
20   NOTREACHED() << "Internal transport used in CastReceiver";
21 }
22 // The video and audio receivers should only be called from the main thread.
23 // LocalFrameReciever posts tasks to the main thread, making the cast interface
24 // thread safe.
25 class LocalFrameReceiver : public FrameReceiver {
26  public:
27   LocalFrameReceiver(scoped_refptr<CastEnvironment> cast_environment,
28                      AudioReceiver* audio_receiver,
29                      VideoReceiver* video_receiver)
30       : cast_environment_(cast_environment),
31         audio_receiver_(audio_receiver),
32         video_receiver_(video_receiver) {}
33
34   virtual void GetRawVideoFrame(
35       const VideoFrameDecodedCallback& callback) OVERRIDE {
36     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
37         base::Bind(&VideoReceiver::GetRawVideoFrame,
38                    video_receiver_->AsWeakPtr(), callback));
39   }
40
41   virtual void GetEncodedVideoFrame(
42       const VideoFrameEncodedCallback& callback) OVERRIDE {
43     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
44         base::Bind(&VideoReceiver::GetEncodedVideoFrame,
45                    video_receiver_->AsWeakPtr(), callback));
46   }
47
48   virtual void GetRawAudioFrame(
49       int number_of_10ms_blocks,
50       int desired_frequency,
51       const AudioFrameDecodedCallback& callback) OVERRIDE {
52     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, base::Bind(
53         &AudioReceiver::GetRawAudioFrame, audio_receiver_->AsWeakPtr(),
54         number_of_10ms_blocks, desired_frequency, callback));
55   }
56
57   virtual void GetCodedAudioFrame(
58       const AudioFrameEncodedCallback& callback) OVERRIDE {
59     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
60         base::Bind(&AudioReceiver::GetEncodedAudioFrame,
61                    audio_receiver_->AsWeakPtr(), callback));
62   }
63
64  protected:
65   virtual ~LocalFrameReceiver() {}
66
67  private:
68   friend class base::RefCountedThreadSafe<LocalFrameReceiver>;
69
70   scoped_refptr<CastEnvironment> cast_environment_;
71   AudioReceiver* audio_receiver_;
72   VideoReceiver* video_receiver_;
73 };
74
75 // The video and audio receivers should only be called from the main thread.
76 class LocalPacketReceiver : public transport::PacketReceiver {
77  public:
78   LocalPacketReceiver(scoped_refptr<CastEnvironment> cast_environment,
79                       AudioReceiver* audio_receiver,
80                       VideoReceiver* video_receiver,
81                       uint32 ssrc_of_audio_sender,
82                       uint32 ssrc_of_video_sender)
83       : cast_environment_(cast_environment),
84         audio_receiver_(audio_receiver),
85         video_receiver_(video_receiver),
86         ssrc_of_audio_sender_(ssrc_of_audio_sender),
87         ssrc_of_video_sender_(ssrc_of_video_sender) {}
88
89   virtual void ReceivedPacket(const uint8* packet,
90                               size_t length,
91                               const base::Closure callback) OVERRIDE {
92     if (length < kMinLengthOfRtcp) {
93       // No action; just log and call the callback informing that we are done
94       // with the packet.
95       VLOG(1) << "Received a packet which is too short " << length;
96       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
97       return;
98     }
99     uint32 ssrc_of_sender;
100     if (!Rtcp::IsRtcpPacket(packet, length)) {
101       if (length < kMinLengthOfRtp) {
102         // No action; just log and call the callback informing that we are done
103         // with the packet.
104         VLOG(1) << "Received a RTP packet which is too short " << length;
105         cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
106         return;
107       }
108       ssrc_of_sender = RtpReceiver::GetSsrcOfSender(packet, length);
109     } else {
110       ssrc_of_sender = Rtcp::GetSsrcOfSender(packet, length);
111     }
112     if (ssrc_of_sender == ssrc_of_audio_sender_) {
113       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
114           base::Bind(&AudioReceiver::IncomingPacket,
115                      audio_receiver_->AsWeakPtr(), packet, length, callback));
116     } else if (ssrc_of_sender == ssrc_of_video_sender_) {
117       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
118           base::Bind(&VideoReceiver::IncomingPacket,
119                      video_receiver_->AsWeakPtr(), packet, length, callback));
120     } else {
121       // No action; just log and call the callback informing that we are done
122       // with the packet.
123       VLOG(1) << "Received a packet with a non matching sender SSRC "
124               << ssrc_of_sender;
125
126       cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
127     }
128   }
129
130  protected:
131   virtual ~LocalPacketReceiver() {}
132
133  private:
134   friend class base::RefCountedThreadSafe<LocalPacketReceiver>;
135
136   scoped_refptr<CastEnvironment> cast_environment_;
137   AudioReceiver* audio_receiver_;
138   VideoReceiver* video_receiver_;
139   const uint32 ssrc_of_audio_sender_;
140   const uint32 ssrc_of_video_sender_;
141 };
142
143 CastReceiver* CastReceiver::CreateCastReceiver(
144     scoped_refptr<CastEnvironment> cast_environment,
145     const AudioReceiverConfig& audio_config,
146     const VideoReceiverConfig& video_config,
147     transport::PacketSender* const packet_sender) {
148   return new CastReceiverImpl(cast_environment,
149                               audio_config,
150                               video_config,
151                               packet_sender);
152 }
153
154 CastReceiverImpl::CastReceiverImpl(
155     scoped_refptr<CastEnvironment> cast_environment,
156     const AudioReceiverConfig& audio_config,
157     const VideoReceiverConfig& video_config,
158     transport::PacketSender* const packet_sender)
159     : pacer_(cast_environment->Clock(), NULL, packet_sender,
160              cast_environment->GetMessageTaskRunnerForThread(
161              CastEnvironment::TRANSPORT),
162              base::Bind(&DoNothingCastTransportStatus)),
163       audio_receiver_(cast_environment, audio_config, &pacer_),
164       video_receiver_(cast_environment, video_config, &pacer_),
165       frame_receiver_(new LocalFrameReceiver(cast_environment,
166                                              &audio_receiver_,
167                                              &video_receiver_)),
168       packet_receiver_(new LocalPacketReceiver(cast_environment,
169                                                &audio_receiver_,
170                                                &video_receiver_,
171                                                audio_config.incoming_ssrc,
172                                                video_config.incoming_ssrc)) {}
173
174 CastReceiverImpl::~CastReceiverImpl() {}
175
176 scoped_refptr<transport::PacketReceiver> CastReceiverImpl::packet_receiver() {
177   return packet_receiver_;
178 }
179
180 scoped_refptr<FrameReceiver> CastReceiverImpl::frame_receiver() {
181   return frame_receiver_;
182 }
183
184 }  // namespace cast
185 }  // namespace media