Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: webkit/renderer/media/android/media_source_delegate.cc

Issue 14247018: Implement WebRTC in Chrome for TV (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: build fix Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/renderer/media/android/media_source_delegate.h" 5 #include "webkit/renderer/media/android/media_source_delegate.h"
6 6
7 #include "base/message_loop_proxy.h" 7 #include "base/message_loop_proxy.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "media/base/android/demuxer_stream_player_params.h" 9 #include "media/base/android/demuxer_stream_player_params.h"
10 #include "media/base/bind_to_loop.h" 10 #include "media/base/bind_to_loop.h"
11 #include "media/base/demuxer_stream.h" 11 #include "media/base/demuxer_stream.h"
12 #include "media/base/media_log.h" 12 #include "media/base/media_log.h"
13 #include "media/filters/chunk_demuxer.h" 13 #include "media/filters/chunk_demuxer.h"
14 #include "third_party/WebKit/public/platform/WebString.h" 14 #include "third_party/WebKit/public/platform/WebString.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSource.h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSource.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h"
17 #include "webkit/renderer/media/android/webmediaplayer_proxy_android.h" 17 #include "webkit/renderer/media/android/webmediaplayer_proxy_android.h"
18 #include "webkit/renderer/media/crypto/key_systems.h" 18 #include "webkit/renderer/media/crypto/key_systems.h"
19 #include "webkit/renderer/media/webmediaplayer_util.h" 19 #include "webkit/renderer/media/webmediaplayer_util.h"
20 #include "webkit/renderer/media/webmediasourceclient_impl.h" 20 #include "webkit/renderer/media/webmediasourceclient_impl.h"
21 21
22 using media::DemuxerStream; 22 using media::DemuxerStream;
23 using media::MediaPlayerHostMsg_DemuxerReady_Params; 23 using media::MediaPlayerHostMsg_DemuxerReady_Params;
24 using media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params; 24 using media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params;
25 using WebKit::WebMediaPlayer; 25 using WebKit::WebMediaPlayer;
26 using WebKit::WebString; 26 using WebKit::WebString;
27 27
28 namespace { 28 namespace {
29 29
30 // The size of the access unit to transfer in an IPC. 30 // The size of the access unit to transfer in an IPC in case of MediaSource.
31 // 16: approximately 250ms of content in 60 fps movies. 31 // 16: approximately 250ms of content in 60 fps movies.
32 const size_t kAccessUnitSize = 16; 32 const size_t kAccessUnitSizeForMediaSource = 16;
33 33
34 const uint8 kVorbisPadding[] = { 0xff, 0xff, 0xff, 0xff }; 34 const uint8 kVorbisPadding[] = { 0xff, 0xff, 0xff, 0xff };
35 35
36 } // namespace 36 } // namespace
37 37
38 namespace webkit_media { 38 namespace webkit_media {
39 39
40 #define BIND_TO_RENDER_LOOP(function) \ 40 #define BIND_TO_RENDER_LOOP(function) \
41 media::BindToLoop(base::MessageLoopProxy::current(), \ 41 media::BindToLoop(base::MessageLoopProxy::current(), \
42 base::Bind(function, weak_this_.GetWeakPtr())) 42 base::Bind(function, weak_this_.GetWeakPtr()))
(...skipping 16 matching lines...) Expand all
59 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); 59 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error));
60 } 60 }
61 61
62 MediaSourceDelegate::MediaSourceDelegate(WebMediaPlayerProxyAndroid* proxy, 62 MediaSourceDelegate::MediaSourceDelegate(WebMediaPlayerProxyAndroid* proxy,
63 int player_id, 63 int player_id,
64 media::MediaLog* media_log) 64 media::MediaLog* media_log)
65 : weak_this_(this), 65 : weak_this_(this),
66 proxy_(proxy), 66 proxy_(proxy),
67 player_id_(player_id), 67 player_id_(player_id),
68 media_log_(media_log), 68 media_log_(media_log),
69 demuxer_(NULL),
69 audio_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params), 70 audio_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params),
70 video_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params), 71 video_params_(new MediaPlayerHostMsg_ReadFromDemuxerAck_Params),
71 seeking_(false) { 72 seeking_(false),
73 access_unit_size_(0) {
72 } 74 }
73 75
74 MediaSourceDelegate::~MediaSourceDelegate() { 76 MediaSourceDelegate::~MediaSourceDelegate() {
75 DVLOG(1) << "MediaSourceDelegate::~MediaSourceDelegate() : " << player_id_; 77 DVLOG(1) << "MediaSourceDelegate::~MediaSourceDelegate() : " << player_id_;
76 DCHECK(!chunk_demuxer_); 78 DCHECK(!chunk_demuxer_);
79 DCHECK(!demuxer_);
77 } 80 }
78 81
79 void MediaSourceDelegate::Destroy() { 82 void MediaSourceDelegate::Destroy() {
80 DVLOG(1) << "MediaSourceDelegate::Destroy() : " << player_id_; 83 DVLOG(1) << "MediaSourceDelegate::Destroy() : " << player_id_;
81 if (!chunk_demuxer_) { 84 if (!demuxer_) {
82 delete this; 85 delete this;
83 return; 86 return;
84 } 87 }
85 88
86 update_network_state_cb_.Reset(); 89 update_network_state_cb_.Reset();
87 media_source_.reset(); 90 media_source_.reset();
88 proxy_ = NULL; 91 proxy_ = NULL;
89 92
90 chunk_demuxer_->Stop( 93 demuxer_ = NULL;
91 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerStopDone)); 94 if (chunk_demuxer_)
95 chunk_demuxer_->Stop(
96 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerStopDone));
92 } 97 }
93 98
94 void MediaSourceDelegate::Initialize( 99 void MediaSourceDelegate::InitializeMediaSource(
95 WebKit::WebMediaSource* media_source, 100 WebKit::WebMediaSource* media_source,
96 const media::NeedKeyCB& need_key_cb, 101 const media::NeedKeyCB& need_key_cb,
97 const UpdateNetworkStateCB& update_network_state_cb) { 102 const UpdateNetworkStateCB& update_network_state_cb) {
98 DCHECK(media_source); 103 DCHECK(media_source);
99 media_source_.reset(media_source); 104 media_source_.reset(media_source);
100 need_key_cb_ = need_key_cb; 105 need_key_cb_ = need_key_cb;
101 update_network_state_cb_ = update_network_state_cb; 106 update_network_state_cb_ = update_network_state_cb;
102 107
103 chunk_demuxer_.reset(new media::ChunkDemuxer( 108 chunk_demuxer_.reset(new media::ChunkDemuxer(
104 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened), 109 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened),
105 BIND_TO_RENDER_LOOP_2(&MediaSourceDelegate::OnNeedKey, "", ""), 110 BIND_TO_RENDER_LOOP_2(&MediaSourceDelegate::OnNeedKey, "", ""),
106 base::Bind(&MediaSourceDelegate::OnAddTextTrack, 111 base::Bind(&MediaSourceDelegate::OnAddTextTrack,
107 base::Unretained(this)), 112 base::Unretained(this)),
108 base::Bind(&LogMediaSourceError, media_log_))); 113 base::Bind(&LogMediaSourceError, media_log_)));
109 chunk_demuxer_->Initialize(this, 114 chunk_demuxer_->Initialize(this,
110 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone)); 115 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
116 demuxer_ = chunk_demuxer_.get();
117 access_unit_size_ = kAccessUnitSizeForMediaSource;
111 } 118 }
112 119
120 #if defined(GOOGLE_TV)
121 void MediaSourceDelegate::InitializeMediaStream(
122 media::Demuxer* demuxer,
123 const UpdateNetworkStateCB& update_network_state_cb) {
124 DCHECK(demuxer);
125 demuxer_ = demuxer;
126 update_network_state_cb_ = update_network_state_cb;
127
128 demuxer_->Initialize(this,
129 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone));
130 // When playing Media Stream, don't wait to accumulate multiple packets per
131 // IPC communication.
132 access_unit_size_ = 1;
133 }
134 #endif
135
113 const WebKit::WebTimeRanges& MediaSourceDelegate::Buffered() { 136 const WebKit::WebTimeRanges& MediaSourceDelegate::Buffered() {
114 buffered_web_time_ranges_ = 137 buffered_web_time_ranges_ =
115 ConvertToWebTimeRanges(buffered_time_ranges_); 138 ConvertToWebTimeRanges(buffered_time_ranges_);
116 return buffered_web_time_ranges_; 139 return buffered_web_time_ranges_;
117 } 140 }
118 141
119 size_t MediaSourceDelegate::DecodedFrameCount() const { 142 size_t MediaSourceDelegate::DecodedFrameCount() const {
120 return statistics_.video_frames_decoded; 143 return statistics_.video_frames_decoded;
121 } 144 }
122 145
123 size_t MediaSourceDelegate::DroppedFrameCount() const { 146 size_t MediaSourceDelegate::DroppedFrameCount() const {
124 return statistics_.video_frames_dropped; 147 return statistics_.video_frames_dropped;
125 } 148 }
126 149
127 size_t MediaSourceDelegate::AudioDecodedByteCount() const { 150 size_t MediaSourceDelegate::AudioDecodedByteCount() const {
128 return statistics_.audio_bytes_decoded; 151 return statistics_.audio_bytes_decoded;
129 } 152 }
130 153
131 size_t MediaSourceDelegate::VideoDecodedByteCount() const { 154 size_t MediaSourceDelegate::VideoDecodedByteCount() const {
132 return statistics_.video_bytes_decoded; 155 return statistics_.video_bytes_decoded;
133 } 156 }
134 157
135 void MediaSourceDelegate::Seek(base::TimeDelta time) { 158 void MediaSourceDelegate::Seek(base::TimeDelta time) {
136 DVLOG(1) << "MediaSourceDelegate::Seek(" << time.InSecondsF() << ") : " 159 DVLOG(1) << "MediaSourceDelegate::Seek(" << time.InSecondsF() << ") : "
137 << player_id_; 160 << player_id_;
138 seeking_ = true; 161 seeking_ = true;
139 DCHECK(chunk_demuxer_); 162 DCHECK(demuxer_);
140 if (!chunk_demuxer_) 163 if (chunk_demuxer_)
141 return; 164 chunk_demuxer_->StartWaitingForSeek();
142 chunk_demuxer_->StartWaitingForSeek(); 165 demuxer_->Seek(time,
143 chunk_demuxer_->Seek(time,
144 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError)); 166 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerError));
145 } 167 }
146 168
147 void MediaSourceDelegate::CancelPendingSeek() { 169 void MediaSourceDelegate::CancelPendingSeek() {
148 if (chunk_demuxer_) 170 if (chunk_demuxer_)
149 chunk_demuxer_->CancelPendingSeek(); 171 chunk_demuxer_->CancelPendingSeek();
150 } 172 }
151 173
152 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) { 174 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) {
153 NOTIMPLEMENTED(); 175 NOTIMPLEMENTED();
(...skipping 14 matching lines...) Expand all
168 190
169 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type, 191 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type,
170 bool seek_done) { 192 bool seek_done) {
171 DVLOG(1) << "MediaSourceDelegate::OnReadFromDemuxer(" << type 193 DVLOG(1) << "MediaSourceDelegate::OnReadFromDemuxer(" << type
172 << ", " << seek_done << ") : " << player_id_; 194 << ", " << seek_done << ") : " << player_id_;
173 if (seeking_ && !seek_done) 195 if (seeking_ && !seek_done)
174 return; // Drop the request during seeking. 196 return; // Drop the request during seeking.
175 seeking_ = false; 197 seeking_ = false;
176 198
177 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); 199 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO);
200 // The access unit size should have been initialized properly at this stage.
201 DCHECK_GT(access_unit_size_, 0u);
178 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params = 202 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params =
179 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get(); 203 type == DemuxerStream::AUDIO ? audio_params_.get() : video_params_.get();
180 params->type = type; 204 params->type = type;
181 params->access_units.resize(kAccessUnitSize); 205 params->access_units.resize(access_unit_size_);
182 DemuxerStream* stream = chunk_demuxer_->GetStream(type); 206 DemuxerStream* stream = demuxer_->GetStream(type);
183 DCHECK(stream != NULL); 207 DCHECK(stream != NULL);
184 ReadFromDemuxerStream(stream, params, 0); 208 ReadFromDemuxerStream(stream, params, 0);
185 } 209 }
186 210
187 void MediaSourceDelegate::ReadFromDemuxerStream( 211 void MediaSourceDelegate::ReadFromDemuxerStream(
188 DemuxerStream* stream, 212 DemuxerStream* stream,
189 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, 213 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params,
190 size_t index) { 214 size_t index) {
191 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady, 215 stream->Read(BIND_TO_RENDER_LOOP_3(&MediaSourceDelegate::OnBufferReady,
192 stream, params, index)); 216 stream, params, index));
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 } 328 }
305 329
306 void MediaSourceDelegate::OnDemuxerStopDone() { 330 void MediaSourceDelegate::OnDemuxerStopDone() {
307 DVLOG(1) << "MediaSourceDelegate::OnDemuxerStopDone() : " << player_id_; 331 DVLOG(1) << "MediaSourceDelegate::OnDemuxerStopDone() : " << player_id_;
308 chunk_demuxer_.reset(); 332 chunk_demuxer_.reset();
309 delete this; 333 delete this;
310 } 334 }
311 335
312 void MediaSourceDelegate::NotifyDemuxerReady(const std::string& key_system) { 336 void MediaSourceDelegate::NotifyDemuxerReady(const std::string& key_system) {
313 MediaPlayerHostMsg_DemuxerReady_Params params; 337 MediaPlayerHostMsg_DemuxerReady_Params params;
314 DemuxerStream* audio_stream = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); 338 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
315 if (audio_stream) { 339 if (audio_stream) {
316 const media::AudioDecoderConfig& config = 340 const media::AudioDecoderConfig& config =
317 audio_stream->audio_decoder_config(); 341 audio_stream->audio_decoder_config();
318 params.audio_codec = config.codec(); 342 params.audio_codec = config.codec();
319 params.audio_channels = 343 params.audio_channels =
320 media::ChannelLayoutToChannelCount(config.channel_layout()); 344 media::ChannelLayoutToChannelCount(config.channel_layout());
321 params.audio_sampling_rate = config.samples_per_second(); 345 params.audio_sampling_rate = config.samples_per_second();
322 params.is_audio_encrypted = config.is_encrypted(); 346 params.is_audio_encrypted = config.is_encrypted();
323 params.audio_extra_data = std::vector<uint8>( 347 params.audio_extra_data = std::vector<uint8>(
324 config.extra_data(), config.extra_data() + config.extra_data_size()); 348 config.extra_data(), config.extra_data() + config.extra_data_size());
325 } 349 }
326 DemuxerStream* video_stream = chunk_demuxer_->GetStream(DemuxerStream::VIDEO); 350 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
327 if (video_stream) { 351 if (video_stream) {
328 const media::VideoDecoderConfig& config = 352 const media::VideoDecoderConfig& config =
329 video_stream->video_decoder_config(); 353 video_stream->video_decoder_config();
330 params.video_codec = config.codec(); 354 params.video_codec = config.codec();
331 params.video_size = config.natural_size(); 355 params.video_size = config.natural_size();
332 params.is_video_encrypted = config.is_encrypted(); 356 params.is_video_encrypted = config.is_encrypted();
333 params.video_extra_data = std::vector<uint8>( 357 params.video_extra_data = std::vector<uint8>(
334 config.extra_data(), config.extra_data() + config.extra_data_size()); 358 config.extra_data(), config.extra_data() + config.extra_data_size());
335 } 359 }
336 double duration_ms = chunk_demuxer_->GetDuration() * 1000; 360 params.duration_ms = GetDurationMs();
337 DCHECK(duration_ms >= 0);
338 if (duration_ms > std::numeric_limits<int>::max())
339 duration_ms = std::numeric_limits<int>::max();
340 params.duration_ms = duration_ms;
341 params.key_system = key_system; 361 params.key_system = key_system;
342 362
343 bool ready_to_send = (!params.is_audio_encrypted && 363 bool ready_to_send = (!params.is_audio_encrypted &&
344 !params.is_video_encrypted) || !key_system.empty(); 364 !params.is_video_encrypted) || !key_system.empty();
345 if (proxy_ && ready_to_send) 365 if (proxy_ && ready_to_send)
346 proxy_->DemuxerReady(player_id_, params); 366 proxy_->DemuxerReady(player_id_, params);
347 } 367 }
348 368
369 int MediaSourceDelegate::GetDurationMs() {
370 if (!chunk_demuxer_)
371 return -1;
372
373 double duration_ms = chunk_demuxer_->GetDuration() * 1000;
374 if (duration_ms > std::numeric_limits<int>::max()) {
375 LOG(WARNING) << "Duration from ChunkDemuxer is too large; probably "
376 "something has gone wrong.";
377 return std::numeric_limits<int>::max();
378 }
379 return duration_ms;
380 }
381
349 void MediaSourceDelegate::OnDemuxerOpened() { 382 void MediaSourceDelegate::OnDemuxerOpened() {
350 if (!media_source_) 383 if (!media_source_)
351 return; 384 return;
352 385
353 media_source_->open(new WebMediaSourceClientImpl( 386 media_source_->open(new WebMediaSourceClientImpl(
354 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_))); 387 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_)));
355 } 388 }
356 389
357 void MediaSourceDelegate::OnNeedKey(const std::string& key_system, 390 void MediaSourceDelegate::OnNeedKey(const std::string& key_system,
358 const std::string& session_id, 391 const std::string& session_id,
359 const std::string& type, 392 const std::string& type,
360 scoped_ptr<uint8[]> init_data, 393 scoped_ptr<uint8[]> init_data,
361 int init_data_size) { 394 int init_data_size) {
362 if (need_key_cb_.is_null()) 395 if (need_key_cb_.is_null())
363 return; 396 return;
364 397
365 need_key_cb_.Run( 398 need_key_cb_.Run(
366 key_system, session_id, type, init_data.Pass(), init_data_size); 399 key_system, session_id, type, init_data.Pass(), init_data_size);
367 } 400 }
368 401
369 scoped_ptr<media::TextTrack> MediaSourceDelegate::OnAddTextTrack( 402 scoped_ptr<media::TextTrack> MediaSourceDelegate::OnAddTextTrack(
370 media::TextKind kind, 403 media::TextKind kind,
371 const std::string& label, 404 const std::string& label,
372 const std::string& language) { 405 const std::string& language) {
373 return scoped_ptr<media::TextTrack>(); 406 return scoped_ptr<media::TextTrack>();
374 } 407 }
375 408
376 } // namespace webkit_media 409 } // namespace webkit_media
OLDNEW
« no previous file with comments | « webkit/renderer/media/android/media_source_delegate.h ('k') | webkit/renderer/media/android/webmediaplayer_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698