Added documentation to web_view.js/web_view_experimental.js regarding the webview...
[chromium-blink-merge.git] / chrome / renderer / media / cast_rtp_stream.cc
blob9115e7a431bc83bfc4bf54ad1b81e2663e069b85
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.
5 #include "chrome/renderer/media/cast_rtp_stream.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/weak_ptr.h"
10 #include "chrome/renderer/media/cast_session.h"
11 #include "chrome/renderer/media/cast_udp_transport.h"
12 #include "content/public/renderer/media_stream_audio_sink.h"
13 #include "content/public/renderer/media_stream_video_sink.h"
14 #include "media/base/audio_bus.h"
15 #include "media/cast/cast_config.h"
16 #include "media/cast/cast_defines.h"
17 #include "media/cast/cast_sender.h"
18 #include "media/cast/transport/cast_transport_config.h"
19 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
21 using media::cast::AudioSenderConfig;
22 using media::cast::VideoSenderConfig;
24 namespace {
25 const char kCodecNameOpus[] = "OPUS";
26 const char kCodecNameVp8[] = "VP8";
28 CastRtpPayloadParams DefaultOpusPayload() {
29 CastRtpPayloadParams payload;
30 payload.ssrc = 1;
31 payload.feedback_ssrc = 1;
32 payload.payload_type = 127;
33 payload.codec_name = kCodecNameOpus;
34 payload.clock_rate = 48000;
35 payload.channels = 2;
36 payload.min_bitrate = payload.max_bitrate =
37 media::cast::kDefaultAudioEncoderBitrate;
38 return payload;
41 CastRtpPayloadParams DefaultVp8Payload() {
42 CastRtpPayloadParams payload;
43 payload.ssrc = 11;
44 payload.feedback_ssrc = 12;
45 payload.payload_type = 96;
46 payload.codec_name = kCodecNameVp8;
47 payload.clock_rate = 90000;
48 payload.width = 1280;
49 payload.height = 720;
50 payload.min_bitrate = 50 * 1000;
51 payload.max_bitrate = 2000 * 1000;
52 return payload;
55 std::vector<CastRtpParams> SupportedAudioParams() {
56 // TODO(hclam): Fill in more codecs here.
57 std::vector<CastRtpParams> supported_params;
58 supported_params.push_back(CastRtpParams(DefaultOpusPayload()));
59 return supported_params;
62 std::vector<CastRtpParams> SupportedVideoParams() {
63 // TODO(hclam): Fill in H264 here.
64 std::vector<CastRtpParams> supported_params;
65 supported_params.push_back(CastRtpParams(DefaultVp8Payload()));
66 return supported_params;
69 bool ToAudioSenderConfig(const CastRtpParams& params,
70 AudioSenderConfig* config) {
71 config->sender_ssrc = params.payload.ssrc;
72 config->incoming_feedback_ssrc = params.payload.feedback_ssrc;
73 config->rtp_payload_type = params.payload.payload_type;
74 config->use_external_encoder = false;
75 config->frequency = params.payload.clock_rate;
76 config->channels = params.payload.channels;
77 config->bitrate = params.payload.max_bitrate;
78 config->codec = media::cast::transport::kPcm16;
79 if (params.payload.codec_name == kCodecNameOpus)
80 config->codec = media::cast::transport::kOpus;
81 else
82 return false;
83 return true;
86 bool ToVideoSenderConfig(const CastRtpParams& params,
87 VideoSenderConfig* config) {
88 config->sender_ssrc = params.payload.ssrc;
89 config->incoming_feedback_ssrc = params.payload.feedback_ssrc;
90 config->rtp_payload_type = params.payload.payload_type;
91 config->use_external_encoder = false;
92 config->width = params.payload.width;
93 config->height = params.payload.height;
94 config->min_bitrate = config->start_bitrate = params.payload.min_bitrate;
95 config->max_bitrate = params.payload.max_bitrate;
96 if (params.payload.codec_name == kCodecNameVp8)
97 config->codec = media::cast::transport::kVp8;
98 else
99 return false;
100 return true;
103 void DeleteAudioBus(scoped_ptr<media::AudioBus> audio_bus) {
104 // Do nothing as |audio_bus| will be deleted.
107 } // namespace
109 // This class receives MediaStreamTrack events and video frames from a
110 // MediaStreamTrack. Video frames are submitted to media::cast::FrameInput.
112 // Threading: Video frames are received on the render thread.
113 class CastVideoSink : public base::SupportsWeakPtr<CastVideoSink>,
114 public content::MediaStreamVideoSink {
115 public:
116 explicit CastVideoSink(const blink::WebMediaStreamTrack& track)
117 : track_(track), sink_added_(false) {
120 virtual ~CastVideoSink() {
121 if (sink_added_)
122 RemoveFromVideoTrack(this, track_);
125 // content::MediaStreamVideoSink implementation.
126 virtual void OnVideoFrame(
127 const scoped_refptr<media::VideoFrame>& frame) OVERRIDE {
128 // TODO(hclam): Pass in the accurate capture time to have good
129 // audio/video sync.
130 frame_input_->InsertRawVideoFrame(frame,
131 base::TimeTicks::Now());
134 // Attach this sink to MediaStreamTrack. This method call must
135 // be made on the render thread. Incoming data can then be
136 // passed to media::cast::FrameInput on any thread.
137 void AddToTrack(
138 const scoped_refptr<media::cast::FrameInput>& frame_input) {
139 DCHECK(!sink_added_);
140 frame_input_ = frame_input;
141 AddToVideoTrack(this, track_);
142 sink_added_ = true;
145 private:
146 blink::WebMediaStreamTrack track_;
147 scoped_refptr<media::cast::FrameInput> frame_input_;
148 bool sink_added_;
150 DISALLOW_COPY_AND_ASSIGN(CastVideoSink);
153 // Receives audio data from a MediaStreamTrack. Data is submitted to
154 // media::cast::FrameInput.
156 // Threading: Audio frames are received on the real-time audio thread.
157 class CastAudioSink : public base::SupportsWeakPtr<CastAudioSink>,
158 public content::MediaStreamAudioSink {
159 public:
160 explicit CastAudioSink(const blink::WebMediaStreamTrack& track)
161 : track_(track), sink_added_(false) {
164 virtual ~CastAudioSink() {
165 if (sink_added_)
166 RemoveFromAudioTrack(this, track_);
169 // content::MediaStreamAudioSink implementation.
170 virtual void OnData(const int16* audio_data,
171 int sample_rate,
172 int number_of_channels,
173 int number_of_frames) OVERRIDE {
174 scoped_ptr<media::AudioBus> audio_bus(
175 media::AudioBus::Create(number_of_channels,
176 number_of_frames));
177 audio_bus->FromInterleaved(audio_data, number_of_frames, 2);
179 // TODO(hclam): Pass in the accurate capture time to have good
180 // audio/video sync.
181 media::AudioBus* audio_bus_ptr = audio_bus.get();
182 frame_input_->InsertAudio(
183 audio_bus_ptr,
184 base::TimeTicks::Now(),
185 base::Bind(&DeleteAudioBus, base::Passed(&audio_bus)));
188 virtual void OnSetFormat(
189 const media::AudioParameters& params) OVERRIDE{
190 NOTIMPLEMENTED();
193 // See CastVideoSink for details.
194 void AddToTrack(
195 const scoped_refptr<media::cast::FrameInput>& frame_input) {
196 DCHECK(!sink_added_);
197 frame_input_ = frame_input;
198 AddToAudioTrack(this, track_);
199 sink_added_ = true;
202 private:
203 blink::WebMediaStreamTrack track_;
204 scoped_refptr<media::cast::FrameInput> frame_input_;
205 bool sink_added_;
207 DISALLOW_COPY_AND_ASSIGN(CastAudioSink);
210 CastRtpParams::CastRtpParams(const CastRtpPayloadParams& payload_params)
211 : payload(payload_params) {
214 CastCodecSpecificParams::CastCodecSpecificParams() {
217 CastCodecSpecificParams::~CastCodecSpecificParams() {
220 CastRtpPayloadParams::CastRtpPayloadParams()
221 : payload_type(0),
222 ssrc(0),
223 feedback_ssrc(0),
224 clock_rate(0),
225 max_bitrate(0),
226 min_bitrate(0),
227 channels(0),
228 width(0),
229 height(0) {
232 CastRtpPayloadParams::~CastRtpPayloadParams() {
235 CastRtpParams::CastRtpParams() {
238 CastRtpParams::~CastRtpParams() {
241 CastRtpStream::CastRtpStream(
242 const blink::WebMediaStreamTrack& track,
243 const scoped_refptr<CastSession>& session)
244 : track_(track),
245 cast_session_(session) {
248 CastRtpStream::~CastRtpStream() {
251 std::vector<CastRtpParams> CastRtpStream::GetSupportedParams() {
252 if (IsAudio())
253 return SupportedAudioParams();
254 else
255 return SupportedVideoParams();
258 CastRtpParams CastRtpStream::GetParams() {
259 return params_;
262 void CastRtpStream::Start(const CastRtpParams& params) {
263 if (IsAudio()) {
264 AudioSenderConfig config;
265 if (!ToAudioSenderConfig(params, &config)) {
266 DVLOG(1) << "Invalid parameters for audio.";
268 audio_sink_.reset(new CastAudioSink(track_));
269 cast_session_->StartAudio(
270 config,
271 base::Bind(&CastAudioSink::AddToTrack,
272 audio_sink_->AsWeakPtr()));
273 } else {
274 VideoSenderConfig config;
275 if (!ToVideoSenderConfig(params, &config)) {
276 DVLOG(1) << "Invalid parameters for video.";
278 video_sink_.reset(new CastVideoSink(track_));
279 cast_session_->StartVideo(
280 config,
281 base::Bind(&CastVideoSink::AddToTrack,
282 video_sink_->AsWeakPtr()));
286 void CastRtpStream::Stop() {
287 audio_sink_.reset();
288 video_sink_.reset();
291 bool CastRtpStream::IsAudio() const {
292 return track_.source().type() == blink::WebMediaStreamSource::TypeAudio;