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

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

Issue 22875030: Run |demuxer_| related tasks in the media thread in GTV. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed Aaron's comments. Created 7 years, 4 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 | Annotate | Revision Log
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 "content/renderer/media/android/media_source_delegate.h" 5 #include "content/renderer/media/android/media_source_delegate.h"
6 6
7 #include "base/message_loop/message_loop_proxy.h" 7 #include "base/message_loop/message_loop_proxy.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "content/renderer/media/android/webmediaplayer_proxy_android.h" 9 #include "content/renderer/media/android/webmediaplayer_proxy_android.h"
10 #include "content/renderer/media/webmediaplayer_util.h" 10 #include "content/renderer/media/webmediaplayer_util.h"
(...skipping 19 matching lines...) Expand all
30 // The size of the access unit to transfer in an IPC in case of MediaSource. 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 kAccessUnitSizeForMediaSource = 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 content { 38 namespace content {
39 39
40 // TODO(xhwang): BIND_TO_RENDER_LOOP* force posts callback! Since everything
41 // works on the same thread in this class, not all force posts are necessary.
42
43 #define BIND_TO_RENDER_LOOP(function) \ 40 #define BIND_TO_RENDER_LOOP(function) \
44 media::BindToLoop(base::MessageLoopProxy::current(), \ 41 media::BindToLoop(main_loop_, \
45 base::Bind(function, weak_this_.GetWeakPtr())) 42 base::Bind(function, main_weak_this_.GetWeakPtr()))
46 43
47 #define BIND_TO_RENDER_LOOP_1(function, arg1) \ 44 #define BIND_TO_RENDER_LOOP_1(function, arg1) \
48 media::BindToLoop(base::MessageLoopProxy::current(), \ 45 media::BindToLoop(main_loop_, \
49 base::Bind(function, weak_this_.GetWeakPtr(), arg1)) 46 base::Bind(function, main_weak_this_.GetWeakPtr(), arg1))
50 47
51 #define BIND_TO_RENDER_LOOP_2(function, arg1, arg2) \ 48 #if defined(GOOGLE_TV)
52 media::BindToLoop(base::MessageLoopProxy::current(), \ 49 #define DCHECK_BELONG_TO_MEDIA_LOOP() \
53 base::Bind(function, weak_this_.GetWeakPtr(), arg1, arg2)) 50 DCHECK(media_loop_->BelongsToCurrentThread())
54 51 #else
55 #define BIND_TO_RENDER_LOOP_3(function, arg1, arg2, arg3) \ 52 #define DCHECK_BELONG_TO_MEDIA_LOOP() \
56 media::BindToLoop(base::MessageLoopProxy::current(), \ 53 DCHECK(main_loop_->BelongsToCurrentThread())
57 base::Bind(function, \ 54 #endif
58 weak_this_.GetWeakPtr(), arg1, arg2, arg3))
59 55
60 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, 56 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log,
61 const std::string& error) { 57 const std::string& error) {
62 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); 58 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error));
63 } 59 }
64 60
65 MediaSourceDelegate::MediaSourceDelegate(WebMediaPlayerProxyAndroid* proxy, 61 MediaSourceDelegate::MediaSourceDelegate(
66 int player_id, 62 WebMediaPlayerProxyAndroid* proxy,
67 media::MediaLog* media_log) 63 int player_id,
68 : weak_this_(this), 64 const scoped_refptr<base::MessageLoopProxy>& media_loop,
65 media::MediaLog* media_log)
66 : main_weak_this_(this),
67 media_weak_this_(this),
68 main_loop_(base::MessageLoopProxy::current()),
69 #if defined(GOOGLE_TV)
70 media_loop_(media_loop),
71 send_read_from_demuxer_ack_cb_(
72 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendReadFromDemuxerAck)),
73 send_seek_request_ack_cb_(
74 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendSeekRequestAck)),
75 send_demuxer_ready_cb_(
76 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::SendDemuxerReady)),
77 #endif
69 proxy_(proxy), 78 proxy_(proxy),
70 player_id_(player_id), 79 player_id_(player_id),
71 media_log_(media_log), 80 media_log_(media_log),
72 demuxer_(NULL), 81 demuxer_(NULL),
73 is_demuxer_ready_(false), 82 is_demuxer_ready_(false),
74 audio_stream_(NULL), 83 audio_stream_(NULL),
75 video_stream_(NULL), 84 video_stream_(NULL),
76 seeking_(false), 85 seeking_(false),
77 last_seek_request_id_(0), 86 last_seek_request_id_(0),
78 key_added_(false), 87 key_added_(false),
79 access_unit_size_(0) { 88 access_unit_size_(0) {
80 } 89 }
81 90
82 MediaSourceDelegate::~MediaSourceDelegate() { 91 MediaSourceDelegate::~MediaSourceDelegate() {
92 DCHECK(main_loop_->BelongsToCurrentThread());
83 DVLOG(1) << "~MediaSourceDelegate() : " << player_id_; 93 DVLOG(1) << "~MediaSourceDelegate() : " << player_id_;
84 DCHECK(!chunk_demuxer_); 94 DCHECK(!chunk_demuxer_);
85 DCHECK(!demuxer_); 95 DCHECK(!demuxer_);
86 DCHECK(!audio_decrypting_demuxer_stream_); 96 DCHECK(!audio_decrypting_demuxer_stream_);
87 DCHECK(!video_decrypting_demuxer_stream_); 97 DCHECK(!video_decrypting_demuxer_stream_);
88 DCHECK(!audio_stream_); 98 DCHECK(!audio_stream_);
89 DCHECK(!video_stream_); 99 DCHECK(!video_stream_);
90 } 100 }
91 101
92 void MediaSourceDelegate::Destroy() { 102 void MediaSourceDelegate::Destroy() {
103 DCHECK(main_loop_->BelongsToCurrentThread());
93 DVLOG(1) << "Destroy() : " << player_id_; 104 DVLOG(1) << "Destroy() : " << player_id_;
94 if (!demuxer_) { 105 if (!demuxer_) {
95 delete this; 106 delete this;
96 return; 107 return;
97 } 108 }
98 109
99 duration_change_cb_.Reset(); 110 duration_change_cb_.Reset();
100 update_network_state_cb_.Reset(); 111 update_network_state_cb_.Reset();
101 media_source_opened_cb_.Reset(); 112 media_source_opened_cb_.Reset();
102 proxy_ = NULL; 113 proxy_ = NULL;
103 114
104 demuxer_ = NULL; 115 main_weak_this_.InvalidateWeakPtrs();
116 DCHECK(!main_weak_this_.HasWeakPtrs());
117
118 if (chunk_demuxer_)
119 chunk_demuxer_->Shutdown();
120 #if defined(GOOGLE_TV)
121 // |this| will be transfered to the callback StopDemuxer() and
122 // OnDemuxerStopDone(). they own |this| and OnDemuxerStopDone() will delete
123 // it when called. Hence using base::Unretained(this) is safe here.
124 media_loop_->PostTask(FROM_HERE,
125 base::Bind(&MediaSourceDelegate::StopDemuxer,
126 base::Unretained(this)));
127 #else
128 StopDemuxer();
129 #endif
130 }
131
132 void MediaSourceDelegate::StopDemuxer() {
133 DCHECK_BELONG_TO_MEDIA_LOOP();
134 DCHECK(demuxer_);
135
105 audio_stream_ = NULL; 136 audio_stream_ = NULL;
106 video_stream_ = NULL; 137 video_stream_ = NULL;
107 // TODO(xhwang): Figure out if we need to Reset the DDSs after Seeking or 138 // TODO(xhwang): Figure out if we need to Reset the DDSs after Seeking or
108 // before destroying them. 139 // before destroying them.
109 audio_decrypting_demuxer_stream_.reset(); 140 audio_decrypting_demuxer_stream_.reset();
110 video_decrypting_demuxer_stream_.reset(); 141 video_decrypting_demuxer_stream_.reset();
111 142
112 weak_this_.InvalidateWeakPtrs(); 143 media_weak_this_.InvalidateWeakPtrs();
113 DCHECK(!weak_this_.HasWeakPtrs()); 144 DCHECK(!media_weak_this_.HasWeakPtrs());
114 145
115 if (chunk_demuxer_) { 146 // The callback OnDemuxerStopDone() owns |this| and will delete it when
116 // The callback OnDemuxerStopDone() owns |this| and will delete it when 147 // called. Hence using base::Unretained(this) is safe here.
117 // called. Hence using base::Unretained(this) is safe here. 148 demuxer_->Stop(media::BindToLoop(main_loop_,
118 chunk_demuxer_->Stop(base::Bind(&MediaSourceDelegate::OnDemuxerStopDone, 149 base::Bind(&MediaSourceDelegate::OnDemuxerStopDone,
119 base::Unretained(this))); 150 base::Unretained(this))));
120 }
121 } 151 }
122 152
123 void MediaSourceDelegate::InitializeMediaSource( 153 void MediaSourceDelegate::InitializeMediaSource(
124 const MediaSourceOpenedCB& media_source_opened_cb, 154 const MediaSourceOpenedCB& media_source_opened_cb,
125 const media::NeedKeyCB& need_key_cb, 155 const media::NeedKeyCB& need_key_cb,
126 const media::SetDecryptorReadyCB& set_decryptor_ready_cb, 156 const media::SetDecryptorReadyCB& set_decryptor_ready_cb,
127 const UpdateNetworkStateCB& update_network_state_cb, 157 const UpdateNetworkStateCB& update_network_state_cb,
128 const DurationChangeCB& duration_change_cb) { 158 const DurationChangeCB& duration_change_cb) {
159 DCHECK(main_loop_->BelongsToCurrentThread());
129 DCHECK(!media_source_opened_cb.is_null()); 160 DCHECK(!media_source_opened_cb.is_null());
130 media_source_opened_cb_ = media_source_opened_cb; 161 media_source_opened_cb_ = media_source_opened_cb;
131 need_key_cb_ = need_key_cb; 162 need_key_cb_ = need_key_cb;
132 set_decryptor_ready_cb_ = set_decryptor_ready_cb; 163 set_decryptor_ready_cb_ = set_decryptor_ready_cb;
133 update_network_state_cb_ = update_network_state_cb; 164 update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb);
134 duration_change_cb_ = duration_change_cb; 165 duration_change_cb_ = media::BindToCurrentLoop(duration_change_cb);
135 access_unit_size_ = kAccessUnitSizeForMediaSource; 166 access_unit_size_ = kAccessUnitSizeForMediaSource;
136 167
137 chunk_demuxer_.reset(new media::ChunkDemuxer( 168 chunk_demuxer_.reset(new media::ChunkDemuxer(
138 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened), 169 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerOpened),
139 BIND_TO_RENDER_LOOP_1(&MediaSourceDelegate::OnNeedKey, ""), 170 BIND_TO_RENDER_LOOP_1(&MediaSourceDelegate::OnNeedKey, ""),
140 // WeakPtrs can only bind to methods without return values. 171 // WeakPtrs can only bind to methods without return values.
141 base::Bind(&MediaSourceDelegate::OnAddTextTrack, base::Unretained(this)), 172 base::Bind(&MediaSourceDelegate::OnAddTextTrack, base::Unretained(this)),
142 base::Bind(&LogMediaSourceError, media_log_))); 173 base::Bind(&LogMediaSourceError, media_log_)));
143 demuxer_ = chunk_demuxer_.get(); 174 demuxer_ = chunk_demuxer_.get();
144 175
145 chunk_demuxer_->Initialize(this, 176 #if defined(GOOGLE_TV)
146 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone)); 177 // |this| will be retained until StopDemuxer() is posted, so Unretained() is
178 // safe here.
179 media_loop_->PostTask(FROM_HERE,
180 base::Bind(&MediaSourceDelegate::InitializeDemuxer,
181 base::Unretained(this)));
182 #else
183 InitializeDemuxer();
184 #endif
185 }
186
187 void MediaSourceDelegate::InitializeDemuxer() {
188 DCHECK_BELONG_TO_MEDIA_LOOP();
189 demuxer_->Initialize(this, base::Bind(&MediaSourceDelegate::OnDemuxerInitDone,
190 media_weak_this_.GetWeakPtr()));
147 } 191 }
148 192
149 #if defined(GOOGLE_TV) 193 #if defined(GOOGLE_TV)
150 void MediaSourceDelegate::InitializeMediaStream( 194 void MediaSourceDelegate::InitializeMediaStream(
151 media::Demuxer* demuxer, 195 media::Demuxer* demuxer,
152 const UpdateNetworkStateCB& update_network_state_cb) { 196 const UpdateNetworkStateCB& update_network_state_cb) {
197 DCHECK(main_loop_->BelongsToCurrentThread());
153 DCHECK(demuxer); 198 DCHECK(demuxer);
154 demuxer_ = demuxer; 199 demuxer_ = demuxer;
155 update_network_state_cb_ = update_network_state_cb; 200 update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb);
156 // When playing Media Stream, don't wait to accumulate multiple packets per 201 // When playing Media Stream, don't wait to accumulate multiple packets per
157 // IPC communication. 202 // IPC communication.
158 access_unit_size_ = 1; 203 access_unit_size_ = 1;
159 204
160 demuxer_->Initialize(this, 205 // |this| will be retained until StopDemuxer() is posted, so Unretained() is
161 BIND_TO_RENDER_LOOP(&MediaSourceDelegate::OnDemuxerInitDone)); 206 // safe here.
207 media_loop_->PostTask(FROM_HERE,
208 base::Bind(&MediaSourceDelegate::InitializeDemuxer,
209 base::Unretained(this)));
162 } 210 }
163 #endif 211 #endif
164 212
165 const WebKit::WebTimeRanges& MediaSourceDelegate::Buffered() { 213 const WebKit::WebTimeRanges& MediaSourceDelegate::Buffered() {
166 buffered_web_time_ranges_ = 214 buffered_web_time_ranges_ =
167 ConvertToWebTimeRanges(buffered_time_ranges_); 215 ConvertToWebTimeRanges(buffered_time_ranges_);
168 return buffered_web_time_ranges_; 216 return buffered_web_time_ranges_;
169 } 217 }
170 218
171 size_t MediaSourceDelegate::DecodedFrameCount() const { 219 size_t MediaSourceDelegate::DecodedFrameCount() const {
172 return statistics_.video_frames_decoded; 220 return statistics_.video_frames_decoded;
173 } 221 }
174 222
175 size_t MediaSourceDelegate::DroppedFrameCount() const { 223 size_t MediaSourceDelegate::DroppedFrameCount() const {
176 return statistics_.video_frames_dropped; 224 return statistics_.video_frames_dropped;
177 } 225 }
178 226
179 size_t MediaSourceDelegate::AudioDecodedByteCount() const { 227 size_t MediaSourceDelegate::AudioDecodedByteCount() const {
180 return statistics_.audio_bytes_decoded; 228 return statistics_.audio_bytes_decoded;
181 } 229 }
182 230
183 size_t MediaSourceDelegate::VideoDecodedByteCount() const { 231 size_t MediaSourceDelegate::VideoDecodedByteCount() const {
184 return statistics_.video_bytes_decoded; 232 return statistics_.video_bytes_decoded;
185 } 233 }
186 234
187 void MediaSourceDelegate::Seek(base::TimeDelta time, unsigned seek_request_id) { 235 void MediaSourceDelegate::Seek(base::TimeDelta time, unsigned seek_request_id) {
236 DCHECK(main_loop_->BelongsToCurrentThread());
188 DVLOG(1) << "Seek(" << time.InSecondsF() << ") : " << player_id_; 237 DVLOG(1) << "Seek(" << time.InSecondsF() << ") : " << player_id_;
189 238
190 last_seek_time_ = time; 239 last_seek_time_ = time;
191 last_seek_request_id_ = seek_request_id; 240 last_seek_request_id_ = seek_request_id;
192 241
193 if (chunk_demuxer_) { 242 if (chunk_demuxer_) {
194 if (seeking_) { 243 if (IsSeeking()) {
195 chunk_demuxer_->CancelPendingSeek(time); 244 chunk_demuxer_->CancelPendingSeek(time);
196 return; 245 return;
197 } 246 }
198 247
199 chunk_demuxer_->StartWaitingForSeek(time); 248 chunk_demuxer_->StartWaitingForSeek(time);
200 } 249 }
201 250
202 seeking_ = true; 251 SetSeeking(true);
203 demuxer_->Seek(time, 252 #if defined(GOOGLE_TV)
204 BIND_TO_RENDER_LOOP_1(&MediaSourceDelegate::OnDemuxerSeekDone, 253 media_loop_->PostTask(FROM_HERE,
205 seek_request_id)); 254 base::Bind(&MediaSourceDelegate::SeekInternal,
255 base::Unretained(this),
256 time, seek_request_id));
257 #else
258 SeekInternal(time, seek_request_id);
259 #endif
260 }
261
262 void MediaSourceDelegate::SeekInternal(base::TimeDelta time,
263 unsigned request_id) {
264 DCHECK_BELONG_TO_MEDIA_LOOP();
265 demuxer_->Seek(time, base::Bind(&MediaSourceDelegate::OnDemuxerSeekDone,
266 media_weak_this_.GetWeakPtr(), request_id));
206 } 267 }
207 268
208 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) { 269 void MediaSourceDelegate::SetTotalBytes(int64 total_bytes) {
209 NOTIMPLEMENTED(); 270 NOTIMPLEMENTED();
210 } 271 }
211 272
212 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) { 273 void MediaSourceDelegate::AddBufferedByteRange(int64 start, int64 end) {
213 NOTIMPLEMENTED(); 274 NOTIMPLEMENTED();
214 } 275 }
215 276
216 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, 277 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start,
217 base::TimeDelta end) { 278 base::TimeDelta end) {
218 buffered_time_ranges_.Add(start, end); 279 buffered_time_ranges_.Add(start, end);
219 } 280 }
220 281
221 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { 282 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) {
222 DVLOG(1) << "SetDuration(" << duration.InSecondsF() << ") : " << player_id_; 283 DVLOG(1) << "SetDuration(" << duration.InSecondsF() << ") : " << player_id_;
223 // Notify our owner (e.g. WebMediaPlayerAndroid) that 284 // Notify our owner (e.g. WebMediaPlayerAndroid) that duration has changed.
224 // duration has changed. 285 // |duration_change_cb_| is bound to the main thread.
225 if (!duration_change_cb_.is_null()) 286 if (!duration_change_cb_.is_null())
226 duration_change_cb_.Run(duration); 287 duration_change_cb_.Run(duration);
227 } 288 }
228 289
229 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) { 290 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) {
291 DCHECK(main_loop_->BelongsToCurrentThread());
292 #if defined(GOOGLE_TV)
293 media_loop_->PostTask(
294 FROM_HERE,
295 base::Bind(&MediaSourceDelegate::OnReadFromDemuxerInternal,
296 base::Unretained(this), type));
297 #else
298 OnReadFromDemuxerInternal(type);
299 #endif
300 }
301
302 void MediaSourceDelegate::OnReadFromDemuxerInternal(
303 media::DemuxerStream::Type type) {
304 DCHECK_BELONG_TO_MEDIA_LOOP();
230 DVLOG(1) << "OnReadFromDemuxer(" << type << ") : " << player_id_; 305 DVLOG(1) << "OnReadFromDemuxer(" << type << ") : " << player_id_;
231 if (seeking_) 306 if (IsSeeking())
232 return; // Drop the request during seeking. 307 return; // Drop the request during seeking.
233 308
234 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); 309 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO);
235 // The access unit size should have been initialized properly at this stage. 310 // The access unit size should have been initialized properly at this stage.
236 DCHECK_GT(access_unit_size_, 0u); 311 DCHECK_GT(access_unit_size_, 0u);
237 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params = 312 scoped_ptr<MediaPlayerHostMsg_ReadFromDemuxerAck_Params> params(
238 type == DemuxerStream::AUDIO ? &audio_params_ : &video_params_; 313 new MediaPlayerHostMsg_ReadFromDemuxerAck_Params());
239 params->type = type; 314 params->type = type;
240 params->access_units.resize(access_unit_size_); 315 params->access_units.resize(access_unit_size_);
241 ReadFromDemuxerStream(type, params, 0); 316 ReadFromDemuxerStream(type, params.Pass(), 0);
242 } 317 }
243 318
244 void MediaSourceDelegate::ReadFromDemuxerStream( 319 void MediaSourceDelegate::ReadFromDemuxerStream(
245 media::DemuxerStream::Type type, 320 media::DemuxerStream::Type type,
246 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, 321 scoped_ptr<MediaPlayerHostMsg_ReadFromDemuxerAck_Params> params,
247 size_t index) { 322 size_t index) {
248 DCHECK(!seeking_); 323 DCHECK_BELONG_TO_MEDIA_LOOP();
249 // DemuxerStream::Read() always returns the read callback asynchronously. 324 // DemuxerStream::Read() always returns the read callback asynchronously.
250 DemuxerStream* stream = 325 DemuxerStream* stream =
251 (type == DemuxerStream::AUDIO) ? audio_stream_ : video_stream_; 326 (type == DemuxerStream::AUDIO) ? audio_stream_ : video_stream_;
252 stream->Read(base::Bind(&MediaSourceDelegate::OnBufferReady, 327 stream->Read(base::Bind(
253 weak_this_.GetWeakPtr(), type, params, index)); 328 &MediaSourceDelegate::OnBufferReady,
329 media_weak_this_.GetWeakPtr(), type, base::Passed(&params), index));
254 } 330 }
255 331
256 void MediaSourceDelegate::OnBufferReady( 332 void MediaSourceDelegate::OnBufferReady(
257 media::DemuxerStream::Type type, 333 media::DemuxerStream::Type type,
258 MediaPlayerHostMsg_ReadFromDemuxerAck_Params* params, 334 scoped_ptr<MediaPlayerHostMsg_ReadFromDemuxerAck_Params> params,
259 size_t index, 335 size_t index,
260 DemuxerStream::Status status, 336 DemuxerStream::Status status,
261 const scoped_refptr<media::DecoderBuffer>& buffer) { 337 const scoped_refptr<media::DecoderBuffer>& buffer) {
338 DCHECK_BELONG_TO_MEDIA_LOOP();
262 DVLOG(1) << "OnBufferReady(" << index << ", " << status << ", " 339 DVLOG(1) << "OnBufferReady(" << index << ", " << status << ", "
263 << ((!buffer || buffer->end_of_stream()) ? 340 << ((!buffer || buffer->end_of_stream()) ?
264 -1 : buffer->timestamp().InMilliseconds()) 341 -1 : buffer->timestamp().InMilliseconds())
265 << ") : " << player_id_; 342 << ") : " << player_id_;
266 DCHECK(demuxer_); 343 DCHECK(demuxer_);
267 344
268 // No new OnReadFromDemuxer() will be called during seeking. So this callback 345 // No new OnReadFromDemuxer() will be called during seeking. So this callback
269 // must be from previous OnReadFromDemuxer() call and should be ignored. 346 // must be from previous OnReadFromDemuxer() call and should be ignored.
270 if (seeking_) { 347 if (IsSeeking()) {
271 DVLOG(1) << "OnBufferReady(): Ignore previous read during seeking."; 348 DVLOG(1) << "OnBufferReady(): Ignore previous read during seeking.";
272 params->access_units.clear();
273 return; 349 return;
274 } 350 }
275 351
276 bool is_audio = (type == DemuxerStream::AUDIO); 352 bool is_audio = (type == DemuxerStream::AUDIO);
277 if (status != DemuxerStream::kAborted && 353 if (status != DemuxerStream::kAborted &&
278 index >= params->access_units.size()) { 354 index >= params->access_units.size()) {
279 LOG(ERROR) << "The internal state inconsistency onBufferReady: " 355 LOG(ERROR) << "The internal state inconsistency onBufferReady: "
280 << (is_audio ? "Audio" : "Video") << ", index " << index 356 << (is_audio ? "Audio" : "Video") << ", index " << index
281 <<", size " << params->access_units.size() 357 <<", size " << params->access_units.size()
282 << ", status " << static_cast<int>(status); 358 << ", status " << static_cast<int>(status);
283 NOTREACHED(); 359 NOTREACHED();
284 return; 360 return;
285 } 361 }
286 362
287 switch (status) { 363 switch (status) {
288 case DemuxerStream::kAborted: 364 case DemuxerStream::kAborted:
289 // Because the abort was caused by the seek, don't respond ack. 365 // Because the abort was caused by the seek, don't respond ack.
290 DVLOG(1) << "OnBufferReady() : Aborted"; 366 DVLOG(1) << "OnBufferReady() : Aborted";
291 params->access_units.clear();
292 return; 367 return;
293 368
294 case DemuxerStream::kConfigChanged: 369 case DemuxerStream::kConfigChanged:
295 // In case of kConfigChanged, need to read decoder_config once 370 // In case of kConfigChanged, need to read decoder_config once
296 // for the next reads. 371 // for the next reads.
297 // TODO(kjyoun): Investigate if we need to use this new config. See 372 // TODO(kjyoun): Investigate if we need to use this new config. See
298 // http://crbug.com/255783 373 // http://crbug.com/255783
299 if (is_audio) { 374 if (is_audio) {
300 audio_stream_->audio_decoder_config(); 375 audio_stream_->audio_decoder_config();
301 } else { 376 } else {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 params->access_units[index].key_id = std::vector<char>( 416 params->access_units[index].key_id = std::vector<char>(
342 buffer->decrypt_config()->key_id().begin(), 417 buffer->decrypt_config()->key_id().begin(),
343 buffer->decrypt_config()->key_id().end()); 418 buffer->decrypt_config()->key_id().end());
344 params->access_units[index].iv = std::vector<char>( 419 params->access_units[index].iv = std::vector<char>(
345 buffer->decrypt_config()->iv().begin(), 420 buffer->decrypt_config()->iv().begin(),
346 buffer->decrypt_config()->iv().end()); 421 buffer->decrypt_config()->iv().end());
347 params->access_units[index].subsamples = 422 params->access_units[index].subsamples =
348 buffer->decrypt_config()->subsamples(); 423 buffer->decrypt_config()->subsamples();
349 } 424 }
350 if (++index < params->access_units.size()) { 425 if (++index < params->access_units.size()) {
351 ReadFromDemuxerStream(type, params, index); 426 ReadFromDemuxerStream(type, params.Pass(), index);
352 return; 427 return;
353 } 428 }
354 break; 429 break;
355 430
356 default: 431 default:
357 NOTREACHED(); 432 NOTREACHED();
358 } 433 }
359 434
360 if (proxy_) 435 #if defined(GOOGLE_TV)
436 send_read_from_demuxer_ack_cb_.Run(params.Pass());
437 #else
438 SendReadFromDemuxerAck(params.Pass());
439 #endif
440 }
441
442 void MediaSourceDelegate::SendReadFromDemuxerAck(
443 scoped_ptr<MediaPlayerHostMsg_ReadFromDemuxerAck_Params> params) {
444 DCHECK(main_loop_->BelongsToCurrentThread());
445 if (!IsSeeking() && proxy_)
361 proxy_->ReadFromDemuxerAck(player_id_, *params); 446 proxy_->ReadFromDemuxerAck(player_id_, *params);
362
363 params->access_units.clear();
364 } 447 }
365 448
366 void MediaSourceDelegate::OnDemuxerError(media::PipelineStatus status) { 449 void MediaSourceDelegate::OnDemuxerError(media::PipelineStatus status) {
367 DVLOG(1) << "OnDemuxerError(" << status << ") : " << player_id_; 450 DVLOG(1) << "OnDemuxerError(" << status << ") : " << player_id_;
451 // |update_network_state_cb_| is bound to the main thread.
368 if (status != media::PIPELINE_OK && !update_network_state_cb_.is_null()) 452 if (status != media::PIPELINE_OK && !update_network_state_cb_.is_null())
369 update_network_state_cb_.Run(PipelineErrorToNetworkState(status)); 453 update_network_state_cb_.Run(PipelineErrorToNetworkState(status));
370 } 454 }
371 455
372 void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { 456 void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) {
457 DCHECK_BELONG_TO_MEDIA_LOOP();
373 DVLOG(1) << "OnDemuxerInitDone(" << status << ") : " << player_id_; 458 DVLOG(1) << "OnDemuxerInitDone(" << status << ") : " << player_id_;
374 DCHECK(demuxer_); 459 DCHECK(demuxer_);
375 460
376 if (status != media::PIPELINE_OK) { 461 if (status != media::PIPELINE_OK) {
377 OnDemuxerError(status); 462 OnDemuxerError(status);
378 return; 463 return;
379 } 464 }
380 465
381 audio_stream_ = demuxer_->GetStream(DemuxerStream::AUDIO); 466 audio_stream_ = demuxer_->GetStream(DemuxerStream::AUDIO);
382 video_stream_ = demuxer_->GetStream(DemuxerStream::VIDEO); 467 video_stream_ = demuxer_->GetStream(DemuxerStream::VIDEO);
(...skipping 12 matching lines...) Expand all
395 return; 480 return;
396 } 481 }
397 482
398 // Notify demuxer ready when both streams are not encrypted. 483 // Notify demuxer ready when both streams are not encrypted.
399 is_demuxer_ready_ = true; 484 is_demuxer_ready_ = true;
400 if (CanNotifyDemuxerReady()) 485 if (CanNotifyDemuxerReady())
401 NotifyDemuxerReady(); 486 NotifyDemuxerReady();
402 } 487 }
403 488
404 void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { 489 void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() {
490 DCHECK_BELONG_TO_MEDIA_LOOP();
405 DVLOG(1) << "InitAudioDecryptingDemuxerStream() : " << player_id_; 491 DVLOG(1) << "InitAudioDecryptingDemuxerStream() : " << player_id_;
406 DCHECK(!set_decryptor_ready_cb_.is_null()); 492 DCHECK(!set_decryptor_ready_cb_.is_null());
407 493
408 audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( 494 audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream(
409 base::MessageLoopProxy::current(), set_decryptor_ready_cb_)); 495 base::MessageLoopProxy::current(), set_decryptor_ready_cb_));
410 audio_decrypting_demuxer_stream_->Initialize( 496 audio_decrypting_demuxer_stream_->Initialize(
411 audio_stream_, 497 audio_stream_,
412 BIND_TO_RENDER_LOOP( 498 base::Bind(&MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone,
413 &MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone)); 499 media_weak_this_.GetWeakPtr()));
414 } 500 }
415 501
416 void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { 502 void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() {
503 DCHECK_BELONG_TO_MEDIA_LOOP();
417 DVLOG(1) << "InitVideoDecryptingDemuxerStream() : " << player_id_; 504 DVLOG(1) << "InitVideoDecryptingDemuxerStream() : " << player_id_;
418 DCHECK(!set_decryptor_ready_cb_.is_null()); 505 DCHECK(!set_decryptor_ready_cb_.is_null());
419 506
420 video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( 507 video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream(
421 base::MessageLoopProxy::current(), set_decryptor_ready_cb_)); 508 base::MessageLoopProxy::current(), set_decryptor_ready_cb_));
422 video_decrypting_demuxer_stream_->Initialize( 509 video_decrypting_demuxer_stream_->Initialize(
423 video_stream_, 510 video_stream_,
424 BIND_TO_RENDER_LOOP( 511 base::Bind(&MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone,
425 &MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone)); 512 media_weak_this_.GetWeakPtr()));
426 } 513 }
427 514
428 void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( 515 void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone(
429 media::PipelineStatus status) { 516 media::PipelineStatus status) {
517 DCHECK_BELONG_TO_MEDIA_LOOP();
430 DVLOG(1) << "OnAudioDecryptingDemuxerStreamInitDone(" << status 518 DVLOG(1) << "OnAudioDecryptingDemuxerStreamInitDone(" << status
431 << ") : " << player_id_; 519 << ") : " << player_id_;
432 DCHECK(demuxer_); 520 DCHECK(demuxer_);
433 521
434 if (status != media::PIPELINE_OK) 522 if (status != media::PIPELINE_OK)
435 audio_decrypting_demuxer_stream_.reset(); 523 audio_decrypting_demuxer_stream_.reset();
436 else 524 else
437 audio_stream_ = audio_decrypting_demuxer_stream_.get(); 525 audio_stream_ = audio_decrypting_demuxer_stream_.get();
438 526
439 if (video_stream_ && video_stream_->video_decoder_config().is_encrypted()) { 527 if (video_stream_ && video_stream_->video_decoder_config().is_encrypted()) {
440 InitVideoDecryptingDemuxerStream(); 528 InitVideoDecryptingDemuxerStream();
441 return; 529 return;
442 } 530 }
443 531
444 // Try to notify demuxer ready when audio DDS initialization finished and 532 // Try to notify demuxer ready when audio DDS initialization finished and
445 // video is not encrypted. 533 // video is not encrypted.
446 is_demuxer_ready_ = true; 534 is_demuxer_ready_ = true;
447 if (CanNotifyDemuxerReady()) 535 if (CanNotifyDemuxerReady())
448 NotifyDemuxerReady(); 536 NotifyDemuxerReady();
449 } 537 }
450 538
451 void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( 539 void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone(
452 media::PipelineStatus status) { 540 media::PipelineStatus status) {
541 DCHECK_BELONG_TO_MEDIA_LOOP();
453 DVLOG(1) << "OnVideoDecryptingDemuxerStreamInitDone(" << status 542 DVLOG(1) << "OnVideoDecryptingDemuxerStreamInitDone(" << status
454 << ") : " << player_id_; 543 << ") : " << player_id_;
455 DCHECK(demuxer_); 544 DCHECK(demuxer_);
456 545
457 if (status != media::PIPELINE_OK) 546 if (status != media::PIPELINE_OK)
458 video_decrypting_demuxer_stream_.reset(); 547 video_decrypting_demuxer_stream_.reset();
459 else 548 else
460 video_stream_ = video_decrypting_demuxer_stream_.get(); 549 video_stream_ = video_decrypting_demuxer_stream_.get();
461 550
462 // Try to notify demuxer ready when video DDS initialization finished. 551 // Try to notify demuxer ready when video DDS initialization finished.
463 is_demuxer_ready_ = true; 552 is_demuxer_ready_ = true;
464 if (CanNotifyDemuxerReady()) 553 if (CanNotifyDemuxerReady())
465 NotifyDemuxerReady(); 554 NotifyDemuxerReady();
466 } 555 }
467 556
468 void MediaSourceDelegate::OnDemuxerSeekDone(unsigned seek_request_id, 557 void MediaSourceDelegate::OnDemuxerSeekDone(unsigned seek_request_id,
469 media::PipelineStatus status) { 558 media::PipelineStatus status) {
559 DCHECK_BELONG_TO_MEDIA_LOOP();
470 DVLOG(1) << "OnDemuxerSeekDone(" << status << ") : " << player_id_; 560 DVLOG(1) << "OnDemuxerSeekDone(" << status << ") : " << player_id_;
471 DCHECK(seeking_); 561 DCHECK(IsSeeking());
472 562
473 if (status != media::PIPELINE_OK) { 563 if (status != media::PIPELINE_OK) {
474 OnDemuxerError(status); 564 OnDemuxerError(status);
475 return; 565 return;
476 } 566 }
477 567
478 // Newer seek has been issued. Resume the last seek request. 568 // Newer seek has been issued. Resume the last seek request.
479 if (seek_request_id != last_seek_request_id_) { 569 if (seek_request_id != last_seek_request_id_) {
480 if (chunk_demuxer_) 570 if (chunk_demuxer_)
481 chunk_demuxer_->StartWaitingForSeek(last_seek_time_); 571 chunk_demuxer_->StartWaitingForSeek(last_seek_time_);
482 demuxer_->Seek( 572 SeekInternal(last_seek_time_, last_seek_request_id_);
483 last_seek_time_,
484 BIND_TO_RENDER_LOOP_1(&MediaSourceDelegate::OnDemuxerSeekDone,
485 last_seek_request_id_));
486 return; 573 return;
487 } 574 }
488 575
489 ResetAudioDecryptingDemuxerStream(); 576 ResetAudioDecryptingDemuxerStream();
490 } 577 }
491 578
492 void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { 579 void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() {
580 DCHECK_BELONG_TO_MEDIA_LOOP();
493 DVLOG(1) << "ResetAudioDecryptingDemuxerStream() : " << player_id_; 581 DVLOG(1) << "ResetAudioDecryptingDemuxerStream() : " << player_id_;
494 if (audio_decrypting_demuxer_stream_) { 582 if (audio_decrypting_demuxer_stream_) {
495 audio_decrypting_demuxer_stream_->Reset( 583 audio_decrypting_demuxer_stream_->Reset(
496 base::Bind(&MediaSourceDelegate::ResetVideoDecryptingDemuxerStream, 584 base::Bind(&MediaSourceDelegate::ResetVideoDecryptingDemuxerStream,
497 weak_this_.GetWeakPtr())); 585 media_weak_this_.GetWeakPtr()));
498 } else { 586 } else {
499 ResetVideoDecryptingDemuxerStream(); 587 ResetVideoDecryptingDemuxerStream();
500 } 588 }
501 } 589 }
502 590
503 void MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() { 591 void MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() {
592 DCHECK_BELONG_TO_MEDIA_LOOP();
504 DVLOG(1) << "ResetVideoDecryptingDemuxerStream()"; 593 DVLOG(1) << "ResetVideoDecryptingDemuxerStream()";
594 #if defined(GOOGLE_TV)
595 if (video_decrypting_demuxer_stream_)
596 video_decrypting_demuxer_stream_->Reset(send_seek_request_ack_cb_);
597 else
598 send_seek_request_ack_cb_.Run();
599 #else
505 if (video_decrypting_demuxer_stream_) { 600 if (video_decrypting_demuxer_stream_) {
506 video_decrypting_demuxer_stream_->Reset( 601 video_decrypting_demuxer_stream_->Reset(
507 base::Bind(&MediaSourceDelegate::SendSeekRequestAck, 602 base::Bind(&MediaSourceDelegate::SendSeekRequestAck,
508 weak_this_.GetWeakPtr())); 603 main_weak_this_.GetWeakPtr()));
509 } else { 604 } else {
510 SendSeekRequestAck(); 605 SendSeekRequestAck();
511 } 606 }
607 #endif
512 } 608 }
513 609
514 void MediaSourceDelegate::SendSeekRequestAck() { 610 void MediaSourceDelegate::SendSeekRequestAck() {
515 DVLOG(1) << "SendSeekRequestAck() : " << player_id_; 611 DVLOG(1) << "SendSeekRequestAck() : " << player_id_;
516 seeking_ = false; 612 SetSeeking(false);
517 proxy_->SeekRequestAck(player_id_, last_seek_request_id_); 613 proxy_->SeekRequestAck(player_id_, last_seek_request_id_);
518 last_seek_request_id_ = 0; 614 last_seek_request_id_ = 0;
519 } 615 }
520 616
521 void MediaSourceDelegate::OnDemuxerStopDone() { 617 void MediaSourceDelegate::OnDemuxerStopDone() {
618 DCHECK(main_loop_->BelongsToCurrentThread());
522 DVLOG(1) << "OnDemuxerStopDone() : " << player_id_; 619 DVLOG(1) << "OnDemuxerStopDone() : " << player_id_;
523 chunk_demuxer_.reset(); 620 chunk_demuxer_.reset();
621 demuxer_ = NULL;
524 delete this; 622 delete this;
525 } 623 }
526 624
527 void MediaSourceDelegate::OnMediaConfigRequest() { 625 void MediaSourceDelegate::OnMediaConfigRequest() {
626 #if defined(GOOGLE_TV)
627 if (!media_loop_->BelongsToCurrentThread()) {
628 media_loop_->PostTask(FROM_HERE,
629 base::Bind(&MediaSourceDelegate::OnMediaConfigRequest,
630 base::Unretained(this)));
631 return;
632 }
633 #endif
528 if (CanNotifyDemuxerReady()) 634 if (CanNotifyDemuxerReady())
529 NotifyDemuxerReady(); 635 NotifyDemuxerReady();
530 } 636 }
531 637
532 void MediaSourceDelegate::NotifyKeyAdded(const std::string& key_system) { 638 void MediaSourceDelegate::NotifyKeyAdded(const std::string& key_system) {
639 #if defined(GOOGLE_TV)
640 if (!media_loop_->BelongsToCurrentThread()) {
641 media_loop_->PostTask(FROM_HERE,
642 base::Bind(&MediaSourceDelegate::NotifyKeyAdded,
643 base::Unretained(this), key_system));
644 return;
645 }
646 #endif
533 DVLOG(1) << "NotifyKeyAdded() : " << player_id_; 647 DVLOG(1) << "NotifyKeyAdded() : " << player_id_;
534 // TODO(kjyoun): Enhance logic to detect when to call NotifyDemuxerReady() 648 // TODO(kjyoun): Enhance logic to detect when to call NotifyDemuxerReady()
535 // For now, we calls it when the first key is added. See 649 // For now, we calls it when the first key is added. See
536 // http://crbug.com/255781 650 // http://crbug.com/255781
537 if (key_added_) 651 if (key_added_)
538 return; 652 return;
539 key_added_ = true; 653 key_added_ = true;
540 key_system_ = key_system; 654 key_system_ = key_system;
541 if (!CanNotifyDemuxerReady()) 655 if (!CanNotifyDemuxerReady())
542 return; 656 return;
543 if (HasEncryptedStream()) 657 if (HasEncryptedStream())
544 NotifyDemuxerReady(); 658 NotifyDemuxerReady();
545 } 659 }
546 660
547 bool MediaSourceDelegate::CanNotifyDemuxerReady() { 661 bool MediaSourceDelegate::CanNotifyDemuxerReady() {
662 DCHECK_BELONG_TO_MEDIA_LOOP();
548 // This can happen when a key is added before the demuxer is initialized. 663 // This can happen when a key is added before the demuxer is initialized.
549 // See NotifyKeyAdded(). 664 // See NotifyKeyAdded().
550 // TODO(kjyoun): Remove NotifyDemxuerReady() call from NotifyKeyAdded() so 665 // TODO(kjyoun): Remove NotifyDemxuerReady() call from NotifyKeyAdded() so
551 // that we can remove all is_demuxer_ready_/key_added_/key_system_ madness. 666 // that we can remove all is_demuxer_ready_/key_added_/key_system_ madness.
552 // See http://crbug.com/255781 667 // See http://crbug.com/255781
553 if (!is_demuxer_ready_) 668 if (!is_demuxer_ready_)
554 return false; 669 return false;
555 if (HasEncryptedStream() && !key_added_) 670 if (HasEncryptedStream() && !key_added_)
556 return false; 671 return false;
557 return true; 672 return true;
558 } 673 }
559 674
560 void MediaSourceDelegate::NotifyDemuxerReady() { 675 void MediaSourceDelegate::NotifyDemuxerReady() {
676 DCHECK_BELONG_TO_MEDIA_LOOP();
561 DVLOG(1) << "NotifyDemuxerReady() : " << player_id_; 677 DVLOG(1) << "NotifyDemuxerReady() : " << player_id_;
562 DCHECK(CanNotifyDemuxerReady()); 678 DCHECK(CanNotifyDemuxerReady());
563 679
564 MediaPlayerHostMsg_DemuxerReady_Params params; 680 scoped_ptr<MediaPlayerHostMsg_DemuxerReady_Params> params(
681 new MediaPlayerHostMsg_DemuxerReady_Params());
565 if (audio_stream_) { 682 if (audio_stream_) {
566 media::AudioDecoderConfig config = audio_stream_->audio_decoder_config(); 683 media::AudioDecoderConfig config = audio_stream_->audio_decoder_config();
567 params.audio_codec = config.codec(); 684 params->audio_codec = config.codec();
568 params.audio_channels = 685 params->audio_channels =
569 media::ChannelLayoutToChannelCount(config.channel_layout()); 686 media::ChannelLayoutToChannelCount(config.channel_layout());
570 params.audio_sampling_rate = config.samples_per_second(); 687 params->audio_sampling_rate = config.samples_per_second();
571 params.is_audio_encrypted = config.is_encrypted(); 688 params->is_audio_encrypted = config.is_encrypted();
572 params.audio_extra_data = std::vector<uint8>( 689 params->audio_extra_data = std::vector<uint8>(
573 config.extra_data(), config.extra_data() + config.extra_data_size()); 690 config.extra_data(), config.extra_data() + config.extra_data_size());
574 } 691 }
575 if (video_stream_) { 692 if (video_stream_) {
576 media::VideoDecoderConfig config = video_stream_->video_decoder_config(); 693 media::VideoDecoderConfig config = video_stream_->video_decoder_config();
577 params.video_codec = config.codec(); 694 params->video_codec = config.codec();
578 params.video_size = config.natural_size(); 695 params->video_size = config.natural_size();
579 params.is_video_encrypted = config.is_encrypted(); 696 params->is_video_encrypted = config.is_encrypted();
580 params.video_extra_data = std::vector<uint8>( 697 params->video_extra_data = std::vector<uint8>(
581 config.extra_data(), config.extra_data() + config.extra_data_size()); 698 config.extra_data(), config.extra_data() + config.extra_data_size());
582 } 699 }
583 params.duration_ms = GetDurationMs(); 700 params->duration_ms = GetDurationMs();
584 params.key_system = HasEncryptedStream() ? key_system_ : ""; 701 params->key_system = HasEncryptedStream() ? key_system_ : "";
585 702
703 #if defined(GOOGLE_TV)
704 send_demuxer_ready_cb_.Run(params.Pass());
705 #else
706 SendDemuxerReady(params.Pass());
707 #endif
708 }
709
710 void MediaSourceDelegate::SendDemuxerReady(
711 scoped_ptr<MediaPlayerHostMsg_DemuxerReady_Params> params) {
712 DCHECK(main_loop_->BelongsToCurrentThread());
586 if (proxy_) 713 if (proxy_)
587 proxy_->DemuxerReady(player_id_, params); 714 proxy_->DemuxerReady(player_id_, *params);
588 } 715 }
589 716
590 int MediaSourceDelegate::GetDurationMs() { 717 int MediaSourceDelegate::GetDurationMs() {
718 DCHECK_BELONG_TO_MEDIA_LOOP();
591 if (!chunk_demuxer_) 719 if (!chunk_demuxer_)
592 return -1; 720 return -1;
593 721
594 double duration_ms = chunk_demuxer_->GetDuration() * 1000; 722 double duration_ms = chunk_demuxer_->GetDuration() * 1000;
595 if (duration_ms > std::numeric_limits<int32>::max()) { 723 if (duration_ms > std::numeric_limits<int32>::max()) {
596 LOG(WARNING) << "Duration from ChunkDemuxer is too large; probably " 724 LOG(WARNING) << "Duration from ChunkDemuxer is too large; probably "
597 "something has gone wrong."; 725 "something has gone wrong.";
598 return std::numeric_limits<int32>::max(); 726 return std::numeric_limits<int32>::max();
599 } 727 }
600 return duration_ms; 728 return duration_ms;
601 } 729 }
602 730
603 void MediaSourceDelegate::OnDemuxerOpened() { 731 void MediaSourceDelegate::OnDemuxerOpened() {
732 DCHECK(main_loop_->BelongsToCurrentThread());
604 if (media_source_opened_cb_.is_null()) 733 if (media_source_opened_cb_.is_null())
605 return; 734 return;
606 735
607 media_source_opened_cb_.Run(new WebMediaSourceImpl( 736 media_source_opened_cb_.Run(new WebMediaSourceImpl(
608 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_))); 737 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_)));
609 } 738 }
610 739
611 void MediaSourceDelegate::OnNeedKey(const std::string& session_id, 740 void MediaSourceDelegate::OnNeedKey(const std::string& session_id,
612 const std::string& type, 741 const std::string& type,
613 scoped_ptr<uint8[]> init_data, 742 scoped_ptr<uint8[]> init_data,
614 int init_data_size) { 743 int init_data_size) {
744 DCHECK(main_loop_->BelongsToCurrentThread());
615 if (need_key_cb_.is_null()) 745 if (need_key_cb_.is_null())
616 return; 746 return;
617 747
618 need_key_cb_.Run(session_id, type, init_data.Pass(), init_data_size); 748 need_key_cb_.Run(session_id, type, init_data.Pass(), init_data_size);
619 } 749 }
620 750
621 scoped_ptr<media::TextTrack> MediaSourceDelegate::OnAddTextTrack( 751 scoped_ptr<media::TextTrack> MediaSourceDelegate::OnAddTextTrack(
622 media::TextKind kind, 752 media::TextKind kind,
623 const std::string& label, 753 const std::string& label,
624 const std::string& language) { 754 const std::string& language) {
625 return scoped_ptr<media::TextTrack>(); 755 return scoped_ptr<media::TextTrack>();
626 } 756 }
627 757
628 bool MediaSourceDelegate::HasEncryptedStream() { 758 bool MediaSourceDelegate::HasEncryptedStream() {
759 DCHECK_BELONG_TO_MEDIA_LOOP();
629 return (audio_stream_ && 760 return (audio_stream_ &&
630 audio_stream_->audio_decoder_config().is_encrypted()) || 761 audio_stream_->audio_decoder_config().is_encrypted()) ||
631 (video_stream_ && 762 (video_stream_ &&
632 video_stream_->video_decoder_config().is_encrypted()); 763 video_stream_->video_decoder_config().is_encrypted());
633 } 764 }
634 765
766 void MediaSourceDelegate::SetSeeking(bool seeking) {
767 base::AutoLock auto_lock(seeking_lock_);
768 seeking_ = seeking;
769 }
770
771 bool MediaSourceDelegate::IsSeeking() const {
772 base::AutoLock auto_lock(seeking_lock_);
773 return seeking_;
774 }
775
635 } // namespace content 776 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/android/media_source_delegate.h ('k') | content/renderer/media/android/webmediaplayer_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698