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

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