OLD | NEW |
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 <limits> | 7 #include <limits> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 namespace content { | 41 namespace content { |
42 | 42 |
43 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, | 43 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, |
44 const std::string& error) { | 44 const std::string& error) { |
45 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); | 45 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); |
46 } | 46 } |
47 | 47 |
48 MediaSourceDelegate::MediaSourceDelegate( | 48 MediaSourceDelegate::MediaSourceDelegate( |
49 RendererDemuxerAndroid* demuxer_client, | 49 RendererDemuxerAndroid* demuxer_client, |
50 int demuxer_client_id, | 50 int demuxer_client_id, |
51 const scoped_refptr<base::MessageLoopProxy>& media_loop, | 51 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
52 const scoped_refptr<media::MediaLog> media_log) | 52 const scoped_refptr<media::MediaLog> media_log) |
53 : demuxer_client_(demuxer_client), | 53 : demuxer_client_(demuxer_client), |
54 demuxer_client_id_(demuxer_client_id), | 54 demuxer_client_id_(demuxer_client_id), |
55 media_log_(media_log), | 55 media_log_(media_log), |
56 is_demuxer_ready_(false), | 56 is_demuxer_ready_(false), |
57 audio_stream_(NULL), | 57 audio_stream_(NULL), |
58 video_stream_(NULL), | 58 video_stream_(NULL), |
59 seeking_(false), | 59 seeking_(false), |
60 is_video_encrypted_(false), | 60 is_video_encrypted_(false), |
61 doing_browser_seek_(false), | 61 doing_browser_seek_(false), |
62 browser_seek_time_(media::kNoTimestamp()), | 62 browser_seek_time_(media::kNoTimestamp()), |
63 expecting_regular_seek_(false), | 63 expecting_regular_seek_(false), |
64 access_unit_size_(0), | 64 access_unit_size_(0), |
65 main_loop_(base::MessageLoopProxy::current()), | 65 main_task_runner_(base::MessageLoopProxy::current()), |
66 media_loop_(media_loop), | 66 media_task_runner_(media_task_runner), |
67 main_weak_factory_(this), | 67 main_weak_factory_(this), |
68 media_weak_factory_(this), | 68 media_weak_factory_(this), |
69 main_weak_this_(main_weak_factory_.GetWeakPtr()) { | 69 main_weak_this_(main_weak_factory_.GetWeakPtr()) { |
70 DCHECK(main_loop_->BelongsToCurrentThread()); | 70 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
71 } | 71 } |
72 | 72 |
73 MediaSourceDelegate::~MediaSourceDelegate() { | 73 MediaSourceDelegate::~MediaSourceDelegate() { |
74 DCHECK(main_loop_->BelongsToCurrentThread()); | 74 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
75 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 75 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
76 DCHECK(!chunk_demuxer_); | 76 DCHECK(!chunk_demuxer_); |
77 DCHECK(!demuxer_client_); | 77 DCHECK(!demuxer_client_); |
78 DCHECK(!audio_decrypting_demuxer_stream_); | 78 DCHECK(!audio_decrypting_demuxer_stream_); |
79 DCHECK(!video_decrypting_demuxer_stream_); | 79 DCHECK(!video_decrypting_demuxer_stream_); |
80 DCHECK(!audio_stream_); | 80 DCHECK(!audio_stream_); |
81 DCHECK(!video_stream_); | 81 DCHECK(!video_stream_); |
82 } | 82 } |
83 | 83 |
84 void MediaSourceDelegate::Destroy() { | 84 void MediaSourceDelegate::Destroy() { |
85 DCHECK(main_loop_->BelongsToCurrentThread()); | 85 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
86 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 86 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
87 | 87 |
88 if (!chunk_demuxer_) { | 88 if (!chunk_demuxer_) { |
89 DCHECK(!demuxer_client_); | 89 DCHECK(!demuxer_client_); |
90 delete this; | 90 delete this; |
91 return; | 91 return; |
92 } | 92 } |
93 | 93 |
94 duration_change_cb_.Reset(); | 94 duration_change_cb_.Reset(); |
95 update_network_state_cb_.Reset(); | 95 update_network_state_cb_.Reset(); |
96 media_source_opened_cb_.Reset(); | 96 media_source_opened_cb_.Reset(); |
97 | 97 |
98 main_weak_factory_.InvalidateWeakPtrs(); | 98 main_weak_factory_.InvalidateWeakPtrs(); |
99 DCHECK(!main_weak_factory_.HasWeakPtrs()); | 99 DCHECK(!main_weak_factory_.HasWeakPtrs()); |
100 | 100 |
101 chunk_demuxer_->Shutdown(); | 101 chunk_demuxer_->Shutdown(); |
102 | 102 |
103 // |this| will be transferred to the callback StopDemuxer() and | 103 // |this| will be transferred to the callback StopDemuxer() and |
104 // OnDemuxerStopDone(). They own |this| and OnDemuxerStopDone() will delete | 104 // OnDemuxerStopDone(). They own |this| and OnDemuxerStopDone() will delete |
105 // it when called, hence using base::Unretained(this) is safe here. | 105 // it when called, hence using base::Unretained(this) is safe here. |
106 media_loop_->PostTask(FROM_HERE, | 106 media_task_runner_->PostTask(FROM_HERE, |
107 base::Bind(&MediaSourceDelegate::StopDemuxer, | 107 base::Bind(&MediaSourceDelegate::StopDemuxer, |
108 base::Unretained(this))); | 108 base::Unretained(this))); |
109 } | 109 } |
110 | 110 |
111 bool MediaSourceDelegate::IsVideoEncrypted() { | 111 bool MediaSourceDelegate::IsVideoEncrypted() { |
112 DCHECK(main_loop_->BelongsToCurrentThread()); | 112 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
113 base::AutoLock auto_lock(is_video_encrypted_lock_); | 113 base::AutoLock auto_lock(is_video_encrypted_lock_); |
114 return is_video_encrypted_; | 114 return is_video_encrypted_; |
115 } | 115 } |
116 | 116 |
117 base::Time MediaSourceDelegate::GetTimelineOffset() const { | 117 base::Time MediaSourceDelegate::GetTimelineOffset() const { |
118 DCHECK(main_loop_->BelongsToCurrentThread()); | 118 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
119 if (!chunk_demuxer_) | 119 if (!chunk_demuxer_) |
120 return base::Time(); | 120 return base::Time(); |
121 | 121 |
122 return chunk_demuxer_->GetTimelineOffset(); | 122 return chunk_demuxer_->GetTimelineOffset(); |
123 } | 123 } |
124 | 124 |
125 void MediaSourceDelegate::StopDemuxer() { | 125 void MediaSourceDelegate::StopDemuxer() { |
126 DCHECK(media_loop_->BelongsToCurrentThread()); | 126 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
127 DCHECK(chunk_demuxer_); | 127 DCHECK(chunk_demuxer_); |
128 | 128 |
129 demuxer_client_->RemoveDelegate(demuxer_client_id_); | 129 demuxer_client_->RemoveDelegate(demuxer_client_id_); |
130 demuxer_client_ = NULL; | 130 demuxer_client_ = NULL; |
131 | 131 |
132 audio_stream_ = NULL; | 132 audio_stream_ = NULL; |
133 video_stream_ = NULL; | 133 video_stream_ = NULL; |
134 // TODO(xhwang): Figure out if we need to Reset the DDSs after Seeking or | 134 // TODO(xhwang): Figure out if we need to Reset the DDSs after Seeking or |
135 // before destroying them. | 135 // before destroying them. |
136 audio_decrypting_demuxer_stream_.reset(); | 136 audio_decrypting_demuxer_stream_.reset(); |
137 video_decrypting_demuxer_stream_.reset(); | 137 video_decrypting_demuxer_stream_.reset(); |
138 | 138 |
139 media_weak_factory_.InvalidateWeakPtrs(); | 139 media_weak_factory_.InvalidateWeakPtrs(); |
140 DCHECK(!media_weak_factory_.HasWeakPtrs()); | 140 DCHECK(!media_weak_factory_.HasWeakPtrs()); |
141 | 141 |
142 // The callback OnDemuxerStopDone() owns |this| and will delete it when | 142 // The callback OnDemuxerStopDone() owns |this| and will delete it when |
143 // called. Hence using base::Unretained(this) is safe here. | 143 // called. Hence using base::Unretained(this) is safe here. |
144 chunk_demuxer_->Stop(base::Bind(&MediaSourceDelegate::OnDemuxerStopDone, | 144 chunk_demuxer_->Stop(base::Bind(&MediaSourceDelegate::OnDemuxerStopDone, |
145 base::Unretained(this))); | 145 base::Unretained(this))); |
146 } | 146 } |
147 | 147 |
148 void MediaSourceDelegate::InitializeMediaSource( | 148 void MediaSourceDelegate::InitializeMediaSource( |
149 const MediaSourceOpenedCB& media_source_opened_cb, | 149 const MediaSourceOpenedCB& media_source_opened_cb, |
150 const media::Demuxer::NeedKeyCB& need_key_cb, | 150 const media::Demuxer::NeedKeyCB& need_key_cb, |
151 const media::SetDecryptorReadyCB& set_decryptor_ready_cb, | 151 const media::SetDecryptorReadyCB& set_decryptor_ready_cb, |
152 const UpdateNetworkStateCB& update_network_state_cb, | 152 const UpdateNetworkStateCB& update_network_state_cb, |
153 const DurationChangeCB& duration_change_cb) { | 153 const DurationChangeCB& duration_change_cb) { |
154 DCHECK(main_loop_->BelongsToCurrentThread()); | 154 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
155 DCHECK(!media_source_opened_cb.is_null()); | 155 DCHECK(!media_source_opened_cb.is_null()); |
156 media_source_opened_cb_ = media_source_opened_cb; | 156 media_source_opened_cb_ = media_source_opened_cb; |
157 need_key_cb_ = need_key_cb; | 157 need_key_cb_ = need_key_cb; |
158 set_decryptor_ready_cb_ = set_decryptor_ready_cb; | 158 set_decryptor_ready_cb_ = set_decryptor_ready_cb; |
159 update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb); | 159 update_network_state_cb_ = media::BindToCurrentLoop(update_network_state_cb); |
160 duration_change_cb_ = duration_change_cb; | 160 duration_change_cb_ = duration_change_cb; |
161 access_unit_size_ = kAccessUnitSizeForMediaSource; | 161 access_unit_size_ = kAccessUnitSizeForMediaSource; |
162 | 162 |
163 chunk_demuxer_.reset(new media::ChunkDemuxer( | 163 chunk_demuxer_.reset(new media::ChunkDemuxer( |
164 media::BindToCurrentLoop( | 164 media::BindToCurrentLoop( |
165 base::Bind(&MediaSourceDelegate::OnDemuxerOpened, main_weak_this_)), | 165 base::Bind(&MediaSourceDelegate::OnDemuxerOpened, main_weak_this_)), |
166 media::BindToCurrentLoop( | 166 media::BindToCurrentLoop( |
167 base::Bind(&MediaSourceDelegate::OnNeedKey, main_weak_this_)), | 167 base::Bind(&MediaSourceDelegate::OnNeedKey, main_weak_this_)), |
168 base::Bind(&LogMediaSourceError, media_log_), | 168 base::Bind(&LogMediaSourceError, media_log_), |
169 false)); | 169 false)); |
170 | 170 |
171 // |this| will be retained until StopDemuxer() is posted, so Unretained() is | 171 // |this| will be retained until StopDemuxer() is posted, so Unretained() is |
172 // safe here. | 172 // safe here. |
173 media_loop_->PostTask(FROM_HERE, | 173 media_task_runner_->PostTask(FROM_HERE, |
174 base::Bind(&MediaSourceDelegate::InitializeDemuxer, | 174 base::Bind(&MediaSourceDelegate::InitializeDemuxer, |
175 base::Unretained(this))); | 175 base::Unretained(this))); |
176 } | 176 } |
177 | 177 |
178 void MediaSourceDelegate::InitializeDemuxer() { | 178 void MediaSourceDelegate::InitializeDemuxer() { |
179 DCHECK(media_loop_->BelongsToCurrentThread()); | 179 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
180 demuxer_client_->AddDelegate(demuxer_client_id_, this); | 180 demuxer_client_->AddDelegate(demuxer_client_id_, this); |
181 chunk_demuxer_->Initialize(this, | 181 chunk_demuxer_->Initialize(this, |
182 base::Bind(&MediaSourceDelegate::OnDemuxerInitDone, | 182 base::Bind(&MediaSourceDelegate::OnDemuxerInitDone, |
183 media_weak_factory_.GetWeakPtr()), | 183 media_weak_factory_.GetWeakPtr()), |
184 false); | 184 false); |
185 } | 185 } |
186 | 186 |
187 blink::WebTimeRanges MediaSourceDelegate::Buffered() const { | 187 blink::WebTimeRanges MediaSourceDelegate::Buffered() const { |
188 return ConvertToWebTimeRanges(buffered_time_ranges_); | 188 return ConvertToWebTimeRanges(buffered_time_ranges_); |
189 } | 189 } |
190 | 190 |
191 size_t MediaSourceDelegate::DecodedFrameCount() const { | 191 size_t MediaSourceDelegate::DecodedFrameCount() const { |
192 return statistics_.video_frames_decoded; | 192 return statistics_.video_frames_decoded; |
193 } | 193 } |
194 | 194 |
195 size_t MediaSourceDelegate::DroppedFrameCount() const { | 195 size_t MediaSourceDelegate::DroppedFrameCount() const { |
196 return statistics_.video_frames_dropped; | 196 return statistics_.video_frames_dropped; |
197 } | 197 } |
198 | 198 |
199 size_t MediaSourceDelegate::AudioDecodedByteCount() const { | 199 size_t MediaSourceDelegate::AudioDecodedByteCount() const { |
200 return statistics_.audio_bytes_decoded; | 200 return statistics_.audio_bytes_decoded; |
201 } | 201 } |
202 | 202 |
203 size_t MediaSourceDelegate::VideoDecodedByteCount() const { | 203 size_t MediaSourceDelegate::VideoDecodedByteCount() const { |
204 return statistics_.video_bytes_decoded; | 204 return statistics_.video_bytes_decoded; |
205 } | 205 } |
206 | 206 |
207 void MediaSourceDelegate::CancelPendingSeek(const base::TimeDelta& seek_time) { | 207 void MediaSourceDelegate::CancelPendingSeek(const base::TimeDelta& seek_time) { |
208 DCHECK(main_loop_->BelongsToCurrentThread()); | 208 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
209 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ") : " | 209 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ") : " |
210 << demuxer_client_id_; | 210 << demuxer_client_id_; |
211 | 211 |
212 if (!chunk_demuxer_) | 212 if (!chunk_demuxer_) |
213 return; | 213 return; |
214 | 214 |
215 { | 215 { |
216 // Remember to trivially finish any newly arriving browser seek requests | 216 // Remember to trivially finish any newly arriving browser seek requests |
217 // that may arrive prior to the next regular seek request. | 217 // that may arrive prior to the next regular seek request. |
218 base::AutoLock auto_lock(seeking_lock_); | 218 base::AutoLock auto_lock(seeking_lock_); |
219 expecting_regular_seek_ = true; | 219 expecting_regular_seek_ = true; |
220 } | 220 } |
221 | 221 |
222 // Cancel any previously expected or in-progress regular or browser seek. | 222 // Cancel any previously expected or in-progress regular or browser seek. |
223 // It is possible that we have just finished the seek, but caller does | 223 // It is possible that we have just finished the seek, but caller does |
224 // not know this yet. It is still safe to cancel in this case because the | 224 // not know this yet. It is still safe to cancel in this case because the |
225 // caller will always call StartWaitingForSeek() when it is notified of | 225 // caller will always call StartWaitingForSeek() when it is notified of |
226 // the finished seek. | 226 // the finished seek. |
227 chunk_demuxer_->CancelPendingSeek(seek_time); | 227 chunk_demuxer_->CancelPendingSeek(seek_time); |
228 } | 228 } |
229 | 229 |
230 void MediaSourceDelegate::StartWaitingForSeek( | 230 void MediaSourceDelegate::StartWaitingForSeek( |
231 const base::TimeDelta& seek_time) { | 231 const base::TimeDelta& seek_time) { |
232 DCHECK(main_loop_->BelongsToCurrentThread()); | 232 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
233 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ") : " | 233 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ") : " |
234 << demuxer_client_id_; | 234 << demuxer_client_id_; |
235 | 235 |
236 if (!chunk_demuxer_) | 236 if (!chunk_demuxer_) |
237 return; | 237 return; |
238 | 238 |
239 bool cancel_browser_seek = false; | 239 bool cancel_browser_seek = false; |
240 { | 240 { |
241 // Remember to trivially finish any newly arriving browser seek requests | 241 // Remember to trivially finish any newly arriving browser seek requests |
242 // that may arrive prior to the next regular seek request. | 242 // that may arrive prior to the next regular seek request. |
243 base::AutoLock auto_lock(seeking_lock_); | 243 base::AutoLock auto_lock(seeking_lock_); |
244 expecting_regular_seek_ = true; | 244 expecting_regular_seek_ = true; |
245 | 245 |
246 // Remember to cancel any in-progress browser seek. | 246 // Remember to cancel any in-progress browser seek. |
247 if (seeking_) { | 247 if (seeking_) { |
248 DCHECK(doing_browser_seek_); | 248 DCHECK(doing_browser_seek_); |
249 cancel_browser_seek = true; | 249 cancel_browser_seek = true; |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 if (cancel_browser_seek) | 253 if (cancel_browser_seek) |
254 chunk_demuxer_->CancelPendingSeek(seek_time); | 254 chunk_demuxer_->CancelPendingSeek(seek_time); |
255 chunk_demuxer_->StartWaitingForSeek(seek_time); | 255 chunk_demuxer_->StartWaitingForSeek(seek_time); |
256 } | 256 } |
257 | 257 |
258 void MediaSourceDelegate::Seek( | 258 void MediaSourceDelegate::Seek( |
259 const base::TimeDelta& seek_time, bool is_browser_seek) { | 259 const base::TimeDelta& seek_time, bool is_browser_seek) { |
260 DCHECK(media_loop_->BelongsToCurrentThread()); | 260 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
261 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ", " | 261 DVLOG(1) << __FUNCTION__ << "(" << seek_time.InSecondsF() << ", " |
262 << (is_browser_seek ? "browser seek" : "regular seek") << ") : " | 262 << (is_browser_seek ? "browser seek" : "regular seek") << ") : " |
263 << demuxer_client_id_; | 263 << demuxer_client_id_; |
264 | 264 |
265 base::TimeDelta internal_seek_time = seek_time; | 265 base::TimeDelta internal_seek_time = seek_time; |
266 { | 266 { |
267 base::AutoLock auto_lock(seeking_lock_); | 267 base::AutoLock auto_lock(seeking_lock_); |
268 DCHECK(!seeking_); | 268 DCHECK(!seeking_); |
269 seeking_ = true; | 269 seeking_ = true; |
270 doing_browser_seek_ = is_browser_seek; | 270 doing_browser_seek_ = is_browser_seek; |
(...skipping 21 matching lines...) Expand all Loading... |
292 // Prepare |chunk_demuxer_| for browser seek. | 292 // Prepare |chunk_demuxer_| for browser seek. |
293 if (is_browser_seek) { | 293 if (is_browser_seek) { |
294 chunk_demuxer_->CancelPendingSeek(internal_seek_time); | 294 chunk_demuxer_->CancelPendingSeek(internal_seek_time); |
295 chunk_demuxer_->StartWaitingForSeek(internal_seek_time); | 295 chunk_demuxer_->StartWaitingForSeek(internal_seek_time); |
296 } | 296 } |
297 | 297 |
298 SeekInternal(internal_seek_time); | 298 SeekInternal(internal_seek_time); |
299 } | 299 } |
300 | 300 |
301 void MediaSourceDelegate::SeekInternal(const base::TimeDelta& seek_time) { | 301 void MediaSourceDelegate::SeekInternal(const base::TimeDelta& seek_time) { |
302 DCHECK(media_loop_->BelongsToCurrentThread()); | 302 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
303 DCHECK(IsSeeking()); | 303 DCHECK(IsSeeking()); |
304 chunk_demuxer_->Seek(seek_time, base::Bind( | 304 chunk_demuxer_->Seek(seek_time, base::Bind( |
305 &MediaSourceDelegate::OnDemuxerSeekDone, | 305 &MediaSourceDelegate::OnDemuxerSeekDone, |
306 media_weak_factory_.GetWeakPtr())); | 306 media_weak_factory_.GetWeakPtr())); |
307 } | 307 } |
308 | 308 |
309 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, | 309 void MediaSourceDelegate::AddBufferedTimeRange(base::TimeDelta start, |
310 base::TimeDelta end) { | 310 base::TimeDelta end) { |
311 buffered_time_ranges_.Add(start, end); | 311 buffered_time_ranges_.Add(start, end); |
312 } | 312 } |
313 | 313 |
314 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { | 314 void MediaSourceDelegate::SetDuration(base::TimeDelta duration) { |
315 DCHECK(main_loop_->BelongsToCurrentThread()); | 315 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
316 DVLOG(1) << __FUNCTION__ << "(" << duration.InSecondsF() << ") : " | 316 DVLOG(1) << __FUNCTION__ << "(" << duration.InSecondsF() << ") : " |
317 << demuxer_client_id_; | 317 << demuxer_client_id_; |
318 | 318 |
319 // Force duration change notification to be async to avoid reentrancy into | 319 // Force duration change notification to be async to avoid reentrancy into |
320 // ChunkDemxuer. | 320 // ChunkDemxuer. |
321 main_loop_->PostTask(FROM_HERE, base::Bind( | 321 main_task_runner_->PostTask(FROM_HERE, base::Bind( |
322 &MediaSourceDelegate::OnDurationChanged, main_weak_this_, duration)); | 322 &MediaSourceDelegate::OnDurationChanged, main_weak_this_, duration)); |
323 } | 323 } |
324 | 324 |
325 void MediaSourceDelegate::OnDurationChanged(const base::TimeDelta& duration) { | 325 void MediaSourceDelegate::OnDurationChanged(const base::TimeDelta& duration) { |
326 DCHECK(main_loop_->BelongsToCurrentThread()); | 326 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
327 if (demuxer_client_) | 327 if (demuxer_client_) |
328 demuxer_client_->DurationChanged(demuxer_client_id_, duration); | 328 demuxer_client_->DurationChanged(demuxer_client_id_, duration); |
329 if (!duration_change_cb_.is_null()) | 329 if (!duration_change_cb_.is_null()) |
330 duration_change_cb_.Run(duration); | 330 duration_change_cb_.Run(duration); |
331 } | 331 } |
332 | 332 |
333 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) { | 333 void MediaSourceDelegate::OnReadFromDemuxer(media::DemuxerStream::Type type) { |
334 DCHECK(media_loop_->BelongsToCurrentThread()); | 334 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
335 DVLOG(1) << __FUNCTION__ << "(" << type << ") : " << demuxer_client_id_; | 335 DVLOG(1) << __FUNCTION__ << "(" << type << ") : " << demuxer_client_id_; |
336 if (IsSeeking()) | 336 if (IsSeeking()) |
337 return; // Drop the request during seeking. | 337 return; // Drop the request during seeking. |
338 | 338 |
339 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); | 339 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); |
340 // The access unit size should have been initialized properly at this stage. | 340 // The access unit size should have been initialized properly at this stage. |
341 DCHECK_GT(access_unit_size_, 0u); | 341 DCHECK_GT(access_unit_size_, 0u); |
342 scoped_ptr<DemuxerData> data(new DemuxerData()); | 342 scoped_ptr<DemuxerData> data(new DemuxerData()); |
343 data->type = type; | 343 data->type = type; |
344 data->access_units.resize(access_unit_size_); | 344 data->access_units.resize(access_unit_size_); |
345 ReadFromDemuxerStream(type, data.Pass(), 0); | 345 ReadFromDemuxerStream(type, data.Pass(), 0); |
346 } | 346 } |
347 | 347 |
348 void MediaSourceDelegate::ReadFromDemuxerStream(media::DemuxerStream::Type type, | 348 void MediaSourceDelegate::ReadFromDemuxerStream(media::DemuxerStream::Type type, |
349 scoped_ptr<DemuxerData> data, | 349 scoped_ptr<DemuxerData> data, |
350 size_t index) { | 350 size_t index) { |
351 DCHECK(media_loop_->BelongsToCurrentThread()); | 351 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
352 // DemuxerStream::Read() always returns the read callback asynchronously. | 352 // DemuxerStream::Read() always returns the read callback asynchronously. |
353 DemuxerStream* stream = | 353 DemuxerStream* stream = |
354 (type == DemuxerStream::AUDIO) ? audio_stream_ : video_stream_; | 354 (type == DemuxerStream::AUDIO) ? audio_stream_ : video_stream_; |
355 stream->Read(base::Bind( | 355 stream->Read(base::Bind( |
356 &MediaSourceDelegate::OnBufferReady, | 356 &MediaSourceDelegate::OnBufferReady, |
357 media_weak_factory_.GetWeakPtr(), type, base::Passed(&data), index)); | 357 media_weak_factory_.GetWeakPtr(), type, base::Passed(&data), index)); |
358 } | 358 } |
359 | 359 |
360 void MediaSourceDelegate::OnBufferReady( | 360 void MediaSourceDelegate::OnBufferReady( |
361 media::DemuxerStream::Type type, | 361 media::DemuxerStream::Type type, |
362 scoped_ptr<DemuxerData> data, | 362 scoped_ptr<DemuxerData> data, |
363 size_t index, | 363 size_t index, |
364 DemuxerStream::Status status, | 364 DemuxerStream::Status status, |
365 const scoped_refptr<media::DecoderBuffer>& buffer) { | 365 const scoped_refptr<media::DecoderBuffer>& buffer) { |
366 DCHECK(media_loop_->BelongsToCurrentThread()); | 366 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
367 DVLOG(1) << __FUNCTION__ << "(" << index << ", " << status << ", " | 367 DVLOG(1) << __FUNCTION__ << "(" << index << ", " << status << ", " |
368 << ((!buffer || buffer->end_of_stream()) ? | 368 << ((!buffer || buffer->end_of_stream()) ? |
369 -1 : buffer->timestamp().InMilliseconds()) | 369 -1 : buffer->timestamp().InMilliseconds()) |
370 << ") : " << demuxer_client_id_; | 370 << ") : " << demuxer_client_id_; |
371 DCHECK(chunk_demuxer_); | 371 DCHECK(chunk_demuxer_); |
372 | 372 |
373 // No new OnReadFromDemuxer() will be called during seeking. So this callback | 373 // No new OnReadFromDemuxer() will be called during seeking. So this callback |
374 // must be from previous OnReadFromDemuxer() call and should be ignored. | 374 // must be from previous OnReadFromDemuxer() call and should be ignored. |
375 if (IsSeeking()) { | 375 if (IsSeeking()) { |
376 DVLOG(1) << __FUNCTION__ << ": Ignore previous read during seeking."; | 376 DVLOG(1) << __FUNCTION__ << ": Ignore previous read during seeking."; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 NOTIMPLEMENTED(); | 474 NOTIMPLEMENTED(); |
475 } | 475 } |
476 | 476 |
477 void MediaSourceDelegate::RemoveTextStream( | 477 void MediaSourceDelegate::RemoveTextStream( |
478 media::DemuxerStream* /* text_stream */ ) { | 478 media::DemuxerStream* /* text_stream */ ) { |
479 // TODO(matthewjheaney): remove text stream (http://crbug/322115). | 479 // TODO(matthewjheaney): remove text stream (http://crbug/322115). |
480 NOTIMPLEMENTED(); | 480 NOTIMPLEMENTED(); |
481 } | 481 } |
482 | 482 |
483 void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { | 483 void MediaSourceDelegate::OnDemuxerInitDone(media::PipelineStatus status) { |
484 DCHECK(media_loop_->BelongsToCurrentThread()); | 484 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
485 DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; | 485 DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; |
486 DCHECK(chunk_demuxer_); | 486 DCHECK(chunk_demuxer_); |
487 | 487 |
488 if (status != media::PIPELINE_OK) { | 488 if (status != media::PIPELINE_OK) { |
489 OnDemuxerError(status); | 489 OnDemuxerError(status); |
490 return; | 490 return; |
491 } | 491 } |
492 | 492 |
493 audio_stream_ = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); | 493 audio_stream_ = chunk_demuxer_->GetStream(DemuxerStream::AUDIO); |
494 video_stream_ = chunk_demuxer_->GetStream(DemuxerStream::VIDEO); | 494 video_stream_ = chunk_demuxer_->GetStream(DemuxerStream::VIDEO); |
(...skipping 11 matching lines...) Expand all Loading... |
506 InitVideoDecryptingDemuxerStream(); | 506 InitVideoDecryptingDemuxerStream(); |
507 return; | 507 return; |
508 } | 508 } |
509 | 509 |
510 // Notify demuxer ready when both streams are not encrypted. | 510 // Notify demuxer ready when both streams are not encrypted. |
511 is_demuxer_ready_ = true; | 511 is_demuxer_ready_ = true; |
512 NotifyDemuxerReady(); | 512 NotifyDemuxerReady(); |
513 } | 513 } |
514 | 514 |
515 void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { | 515 void MediaSourceDelegate::InitAudioDecryptingDemuxerStream() { |
516 DCHECK(media_loop_->BelongsToCurrentThread()); | 516 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
517 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 517 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
518 DCHECK(!set_decryptor_ready_cb_.is_null()); | 518 DCHECK(!set_decryptor_ready_cb_.is_null()); |
519 | 519 |
520 audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( | 520 audio_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( |
521 media_loop_, set_decryptor_ready_cb_)); | 521 media_task_runner_, set_decryptor_ready_cb_)); |
522 audio_decrypting_demuxer_stream_->Initialize( | 522 audio_decrypting_demuxer_stream_->Initialize( |
523 audio_stream_, | 523 audio_stream_, |
524 base::Bind(&MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone, | 524 base::Bind(&MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone, |
525 media_weak_factory_.GetWeakPtr())); | 525 media_weak_factory_.GetWeakPtr())); |
526 } | 526 } |
527 | 527 |
528 void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { | 528 void MediaSourceDelegate::InitVideoDecryptingDemuxerStream() { |
529 DCHECK(media_loop_->BelongsToCurrentThread()); | 529 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
530 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 530 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
531 DCHECK(!set_decryptor_ready_cb_.is_null()); | 531 DCHECK(!set_decryptor_ready_cb_.is_null()); |
532 | 532 |
533 video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( | 533 video_decrypting_demuxer_stream_.reset(new media::DecryptingDemuxerStream( |
534 media_loop_, set_decryptor_ready_cb_)); | 534 media_task_runner_, set_decryptor_ready_cb_)); |
535 video_decrypting_demuxer_stream_->Initialize( | 535 video_decrypting_demuxer_stream_->Initialize( |
536 video_stream_, | 536 video_stream_, |
537 base::Bind(&MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone, | 537 base::Bind(&MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone, |
538 media_weak_factory_.GetWeakPtr())); | 538 media_weak_factory_.GetWeakPtr())); |
539 } | 539 } |
540 | 540 |
541 void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( | 541 void MediaSourceDelegate::OnAudioDecryptingDemuxerStreamInitDone( |
542 media::PipelineStatus status) { | 542 media::PipelineStatus status) { |
543 DCHECK(media_loop_->BelongsToCurrentThread()); | 543 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
544 DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; | 544 DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; |
545 DCHECK(chunk_demuxer_); | 545 DCHECK(chunk_demuxer_); |
546 | 546 |
547 if (status != media::PIPELINE_OK) | 547 if (status != media::PIPELINE_OK) |
548 audio_decrypting_demuxer_stream_.reset(); | 548 audio_decrypting_demuxer_stream_.reset(); |
549 else | 549 else |
550 audio_stream_ = audio_decrypting_demuxer_stream_.get(); | 550 audio_stream_ = audio_decrypting_demuxer_stream_.get(); |
551 | 551 |
552 if (video_stream_ && video_stream_->video_decoder_config().is_encrypted()) { | 552 if (video_stream_ && video_stream_->video_decoder_config().is_encrypted()) { |
553 InitVideoDecryptingDemuxerStream(); | 553 InitVideoDecryptingDemuxerStream(); |
554 return; | 554 return; |
555 } | 555 } |
556 | 556 |
557 // Try to notify demuxer ready when audio DDS initialization finished and | 557 // Try to notify demuxer ready when audio DDS initialization finished and |
558 // video is not encrypted. | 558 // video is not encrypted. |
559 is_demuxer_ready_ = true; | 559 is_demuxer_ready_ = true; |
560 NotifyDemuxerReady(); | 560 NotifyDemuxerReady(); |
561 } | 561 } |
562 | 562 |
563 void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( | 563 void MediaSourceDelegate::OnVideoDecryptingDemuxerStreamInitDone( |
564 media::PipelineStatus status) { | 564 media::PipelineStatus status) { |
565 DCHECK(media_loop_->BelongsToCurrentThread()); | 565 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
566 DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; | 566 DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; |
567 DCHECK(chunk_demuxer_); | 567 DCHECK(chunk_demuxer_); |
568 | 568 |
569 if (status != media::PIPELINE_OK) | 569 if (status != media::PIPELINE_OK) |
570 video_decrypting_demuxer_stream_.reset(); | 570 video_decrypting_demuxer_stream_.reset(); |
571 else | 571 else |
572 video_stream_ = video_decrypting_demuxer_stream_.get(); | 572 video_stream_ = video_decrypting_demuxer_stream_.get(); |
573 | 573 |
574 // Try to notify demuxer ready when video DDS initialization finished. | 574 // Try to notify demuxer ready when video DDS initialization finished. |
575 is_demuxer_ready_ = true; | 575 is_demuxer_ready_ = true; |
576 NotifyDemuxerReady(); | 576 NotifyDemuxerReady(); |
577 } | 577 } |
578 | 578 |
579 void MediaSourceDelegate::OnDemuxerSeekDone(media::PipelineStatus status) { | 579 void MediaSourceDelegate::OnDemuxerSeekDone(media::PipelineStatus status) { |
580 DCHECK(media_loop_->BelongsToCurrentThread()); | 580 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
581 DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; | 581 DVLOG(1) << __FUNCTION__ << "(" << status << ") : " << demuxer_client_id_; |
582 DCHECK(IsSeeking()); | 582 DCHECK(IsSeeking()); |
583 | 583 |
584 if (status != media::PIPELINE_OK) { | 584 if (status != media::PIPELINE_OK) { |
585 OnDemuxerError(status); | 585 OnDemuxerError(status); |
586 return; | 586 return; |
587 } | 587 } |
588 | 588 |
589 ResetAudioDecryptingDemuxerStream(); | 589 ResetAudioDecryptingDemuxerStream(); |
590 } | 590 } |
591 | 591 |
592 void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { | 592 void MediaSourceDelegate::ResetAudioDecryptingDemuxerStream() { |
593 DCHECK(media_loop_->BelongsToCurrentThread()); | 593 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
594 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 594 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
595 if (audio_decrypting_demuxer_stream_) { | 595 if (audio_decrypting_demuxer_stream_) { |
596 audio_decrypting_demuxer_stream_->Reset( | 596 audio_decrypting_demuxer_stream_->Reset( |
597 base::Bind(&MediaSourceDelegate::ResetVideoDecryptingDemuxerStream, | 597 base::Bind(&MediaSourceDelegate::ResetVideoDecryptingDemuxerStream, |
598 media_weak_factory_.GetWeakPtr())); | 598 media_weak_factory_.GetWeakPtr())); |
599 return; | 599 return; |
600 } | 600 } |
601 | 601 |
602 ResetVideoDecryptingDemuxerStream(); | 602 ResetVideoDecryptingDemuxerStream(); |
603 } | 603 } |
604 | 604 |
605 void MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() { | 605 void MediaSourceDelegate::ResetVideoDecryptingDemuxerStream() { |
606 DCHECK(media_loop_->BelongsToCurrentThread()); | 606 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
607 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 607 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
608 if (video_decrypting_demuxer_stream_) { | 608 if (video_decrypting_demuxer_stream_) { |
609 video_decrypting_demuxer_stream_->Reset(base::Bind( | 609 video_decrypting_demuxer_stream_->Reset(base::Bind( |
610 &MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams, | 610 &MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams, |
611 media_weak_factory_.GetWeakPtr())); | 611 media_weak_factory_.GetWeakPtr())); |
612 return; | 612 return; |
613 } | 613 } |
614 | 614 |
615 FinishResettingDecryptingDemuxerStreams(); | 615 FinishResettingDecryptingDemuxerStreams(); |
616 } | 616 } |
617 | 617 |
618 void MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams() { | 618 void MediaSourceDelegate::FinishResettingDecryptingDemuxerStreams() { |
619 DCHECK(media_loop_->BelongsToCurrentThread()); | 619 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
620 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 620 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
621 | 621 |
622 base::AutoLock auto_lock(seeking_lock_); | 622 base::AutoLock auto_lock(seeking_lock_); |
623 DCHECK(seeking_); | 623 DCHECK(seeking_); |
624 seeking_ = false; | 624 seeking_ = false; |
625 doing_browser_seek_ = false; | 625 doing_browser_seek_ = false; |
626 demuxer_client_->DemuxerSeekDone(demuxer_client_id_, browser_seek_time_); | 626 demuxer_client_->DemuxerSeekDone(demuxer_client_id_, browser_seek_time_); |
627 } | 627 } |
628 | 628 |
629 void MediaSourceDelegate::OnDemuxerStopDone() { | 629 void MediaSourceDelegate::OnDemuxerStopDone() { |
630 DCHECK(media_loop_->BelongsToCurrentThread()); | 630 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
631 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 631 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
632 main_loop_->PostTask( | 632 main_task_runner_->PostTask( |
633 FROM_HERE, | 633 FROM_HERE, |
634 base::Bind(&MediaSourceDelegate::DeleteSelf, base::Unretained(this))); | 634 base::Bind(&MediaSourceDelegate::DeleteSelf, base::Unretained(this))); |
635 } | 635 } |
636 | 636 |
637 void MediaSourceDelegate::DeleteSelf() { | 637 void MediaSourceDelegate::DeleteSelf() { |
638 DCHECK(main_loop_->BelongsToCurrentThread()); | 638 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
639 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 639 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
640 chunk_demuxer_.reset(); | 640 chunk_demuxer_.reset(); |
641 delete this; | 641 delete this; |
642 } | 642 } |
643 | 643 |
644 void MediaSourceDelegate::NotifyDemuxerReady() { | 644 void MediaSourceDelegate::NotifyDemuxerReady() { |
645 DCHECK(media_loop_->BelongsToCurrentThread()); | 645 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
646 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; | 646 DVLOG(1) << __FUNCTION__ << " : " << demuxer_client_id_; |
647 DCHECK(is_demuxer_ready_); | 647 DCHECK(is_demuxer_ready_); |
648 | 648 |
649 scoped_ptr<DemuxerConfigs> configs(new DemuxerConfigs()); | 649 scoped_ptr<DemuxerConfigs> configs(new DemuxerConfigs()); |
650 GetDemuxerConfigFromStream(configs.get(), true); | 650 GetDemuxerConfigFromStream(configs.get(), true); |
651 GetDemuxerConfigFromStream(configs.get(), false); | 651 GetDemuxerConfigFromStream(configs.get(), false); |
652 configs->duration = GetDuration(); | 652 configs->duration = GetDuration(); |
653 | 653 |
654 if (demuxer_client_) | 654 if (demuxer_client_) |
655 demuxer_client_->DemuxerReady(demuxer_client_id_, *configs); | 655 demuxer_client_->DemuxerReady(demuxer_client_id_, *configs); |
656 | 656 |
657 base::AutoLock auto_lock(is_video_encrypted_lock_); | 657 base::AutoLock auto_lock(is_video_encrypted_lock_); |
658 is_video_encrypted_ = configs->is_video_encrypted; | 658 is_video_encrypted_ = configs->is_video_encrypted; |
659 } | 659 } |
660 | 660 |
661 base::TimeDelta MediaSourceDelegate::GetDuration() const { | 661 base::TimeDelta MediaSourceDelegate::GetDuration() const { |
662 DCHECK(media_loop_->BelongsToCurrentThread()); | 662 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
663 if (!chunk_demuxer_) | 663 if (!chunk_demuxer_) |
664 return media::kNoTimestamp(); | 664 return media::kNoTimestamp(); |
665 | 665 |
666 double duration = chunk_demuxer_->GetDuration(); | 666 double duration = chunk_demuxer_->GetDuration(); |
667 if (duration == std::numeric_limits<double>::infinity()) | 667 if (duration == std::numeric_limits<double>::infinity()) |
668 return media::kInfiniteDuration(); | 668 return media::kInfiniteDuration(); |
669 | 669 |
670 return ConvertSecondsToTimestamp(duration); | 670 return ConvertSecondsToTimestamp(duration); |
671 } | 671 } |
672 | 672 |
673 void MediaSourceDelegate::OnDemuxerOpened() { | 673 void MediaSourceDelegate::OnDemuxerOpened() { |
674 DCHECK(main_loop_->BelongsToCurrentThread()); | 674 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
675 if (media_source_opened_cb_.is_null()) | 675 if (media_source_opened_cb_.is_null()) |
676 return; | 676 return; |
677 | 677 |
678 media_source_opened_cb_.Run(new WebMediaSourceImpl( | 678 media_source_opened_cb_.Run(new WebMediaSourceImpl( |
679 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_))); | 679 chunk_demuxer_.get(), base::Bind(&LogMediaSourceError, media_log_))); |
680 } | 680 } |
681 | 681 |
682 void MediaSourceDelegate::OnNeedKey(const std::string& type, | 682 void MediaSourceDelegate::OnNeedKey(const std::string& type, |
683 const std::vector<uint8>& init_data) { | 683 const std::vector<uint8>& init_data) { |
684 DCHECK(main_loop_->BelongsToCurrentThread()); | 684 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
685 if (need_key_cb_.is_null()) | 685 if (need_key_cb_.is_null()) |
686 return; | 686 return; |
687 | 687 |
688 need_key_cb_.Run(type, init_data); | 688 need_key_cb_.Run(type, init_data); |
689 } | 689 } |
690 | 690 |
691 bool MediaSourceDelegate::IsSeeking() const { | 691 bool MediaSourceDelegate::IsSeeking() const { |
692 base::AutoLock auto_lock(seeking_lock_); | 692 base::AutoLock auto_lock(seeking_lock_); |
693 return seeking_; | 693 return seeking_; |
694 } | 694 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 // unlikely. This may cause unexpected playback stall due to seek pending an | 729 // unlikely. This may cause unexpected playback stall due to seek pending an |
730 // append for a GOP prior to the last GOP demuxed. | 730 // append for a GOP prior to the last GOP demuxed. |
731 // TODO(wolenetz): Remove the possibility for this seek to cause unexpected | 731 // TODO(wolenetz): Remove the possibility for this seek to cause unexpected |
732 // player stall by replaying cached data since last keyframe in browser player | 732 // player stall by replaying cached data since last keyframe in browser player |
733 // rather than issuing browser seek. See http://crbug.com/304234. | 733 // rather than issuing browser seek. See http://crbug.com/304234. |
734 return seek_time; | 734 return seek_time; |
735 } | 735 } |
736 | 736 |
737 bool MediaSourceDelegate::GetDemuxerConfigFromStream( | 737 bool MediaSourceDelegate::GetDemuxerConfigFromStream( |
738 media::DemuxerConfigs* configs, bool is_audio) { | 738 media::DemuxerConfigs* configs, bool is_audio) { |
739 DCHECK(media_loop_->BelongsToCurrentThread()); | 739 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
740 if (!is_demuxer_ready_) | 740 if (!is_demuxer_ready_) |
741 return false; | 741 return false; |
742 if (is_audio && audio_stream_) { | 742 if (is_audio && audio_stream_) { |
743 media::AudioDecoderConfig config = audio_stream_->audio_decoder_config(); | 743 media::AudioDecoderConfig config = audio_stream_->audio_decoder_config(); |
744 configs->audio_codec = config.codec(); | 744 configs->audio_codec = config.codec(); |
745 configs->audio_channels = | 745 configs->audio_channels = |
746 media::ChannelLayoutToChannelCount(config.channel_layout()); | 746 media::ChannelLayoutToChannelCount(config.channel_layout()); |
747 configs->audio_sampling_rate = config.samples_per_second(); | 747 configs->audio_sampling_rate = config.samples_per_second(); |
748 configs->is_audio_encrypted = config.is_encrypted(); | 748 configs->is_audio_encrypted = config.is_encrypted(); |
749 configs->audio_extra_data = std::vector<uint8>( | 749 configs->audio_extra_data = std::vector<uint8>( |
750 config.extra_data(), config.extra_data() + config.extra_data_size()); | 750 config.extra_data(), config.extra_data() + config.extra_data_size()); |
751 return true; | 751 return true; |
752 } | 752 } |
753 if (!is_audio && video_stream_) { | 753 if (!is_audio && video_stream_) { |
754 media::VideoDecoderConfig config = video_stream_->video_decoder_config(); | 754 media::VideoDecoderConfig config = video_stream_->video_decoder_config(); |
755 configs->video_codec = config.codec(); | 755 configs->video_codec = config.codec(); |
756 configs->video_size = config.natural_size(); | 756 configs->video_size = config.natural_size(); |
757 configs->is_video_encrypted = config.is_encrypted(); | 757 configs->is_video_encrypted = config.is_encrypted(); |
758 configs->video_extra_data = std::vector<uint8>( | 758 configs->video_extra_data = std::vector<uint8>( |
759 config.extra_data(), config.extra_data() + config.extra_data_size()); | 759 config.extra_data(), config.extra_data() + config.extra_data_size()); |
760 return true; | 760 return true; |
761 } | 761 } |
762 return false; | 762 return false; |
763 } | 763 } |
764 | 764 |
765 } // namespace content | 765 } // namespace content |
OLD | NEW |