OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "media/base/android/media_codec_decoder.h" | 5 #include "media/base/android/media_codec_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 decoder_thread_(decoder_thread_name), | 43 decoder_thread_(decoder_thread_name), |
44 needs_reconfigure_(false), | 44 needs_reconfigure_(false), |
45 drain_decoder_(false), | 45 drain_decoder_(false), |
46 always_reconfigure_for_tests_(false), | 46 always_reconfigure_for_tests_(false), |
47 external_request_data_cb_(external_request_data_cb), | 47 external_request_data_cb_(external_request_data_cb), |
48 starvation_cb_(starvation_cb), | 48 starvation_cb_(starvation_cb), |
49 decoder_drained_cb_(decoder_drained_cb), | 49 decoder_drained_cb_(decoder_drained_cb), |
50 stop_done_cb_(stop_done_cb), | 50 stop_done_cb_(stop_done_cb), |
51 error_cb_(error_cb), | 51 error_cb_(error_cb), |
52 state_(kStopped), | 52 state_(kStopped), |
53 preroll_mode_(kPrerollTillPTS), | 53 is_prepared_(false), |
54 eos_enqueued_(false), | 54 eos_enqueued_(false), |
55 completed_(false), | 55 completed_(false), |
56 last_frame_posted_(false), | 56 last_frame_posted_(false), |
57 is_data_request_in_progress_(false), | 57 is_data_request_in_progress_(false), |
58 is_incoming_data_invalid_(false), | 58 is_incoming_data_invalid_(false), |
59 #ifndef NDEBUG | 59 #ifndef NDEBUG |
60 verify_next_frame_is_key_(false), | 60 verify_next_frame_is_key_(false), |
61 #endif | 61 #endif |
62 weak_factory_(this) { | 62 weak_factory_(this) { |
63 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 63 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
(...skipping 24 matching lines...) Expand all Loading... |
88 // Flush() is a part of the Seek request. Whenever we request a seek we need | 88 // Flush() is a part of the Seek request. Whenever we request a seek we need |
89 // to invalidate the current data request. | 89 // to invalidate the current data request. |
90 if (is_data_request_in_progress_) | 90 if (is_data_request_in_progress_) |
91 is_incoming_data_invalid_ = true; | 91 is_incoming_data_invalid_ = true; |
92 | 92 |
93 eos_enqueued_ = false; | 93 eos_enqueued_ = false; |
94 completed_ = false; | 94 completed_ = false; |
95 drain_decoder_ = false; | 95 drain_decoder_ = false; |
96 au_queue_.Flush(); | 96 au_queue_.Flush(); |
97 | 97 |
| 98 // |is_prepared_| is set on the decoder thread, it shouldn't be running now. |
| 99 DCHECK(!decoder_thread_.IsRunning()); |
| 100 is_prepared_ = false; |
| 101 |
98 #ifndef NDEBUG | 102 #ifndef NDEBUG |
99 // We check and reset |verify_next_frame_is_key_| on Decoder thread. | 103 // We check and reset |verify_next_frame_is_key_| on Decoder thread. |
100 // This DCHECK ensures we won't need to lock this variable. | 104 // We have just DCHECKed that decoder thread is not running. |
101 DCHECK(!decoder_thread_.IsRunning()); | |
102 | 105 |
103 // For video the first frame after flush must be key frame. | 106 // For video the first frame after flush must be key frame. |
104 verify_next_frame_is_key_ = true; | 107 verify_next_frame_is_key_ = true; |
105 #endif | 108 #endif |
106 | 109 |
107 preroll_mode_ = kPrerollTillPTS; | |
108 | |
109 if (media_codec_bridge_) { | 110 if (media_codec_bridge_) { |
110 // MediaCodecBridge::Reset() performs MediaCodecBridge.flush() | 111 // MediaCodecBridge::Reset() performs MediaCodecBridge.flush() |
111 MediaCodecStatus flush_status = media_codec_bridge_->Reset(); | 112 MediaCodecStatus flush_status = media_codec_bridge_->Reset(); |
112 if (flush_status != MEDIA_CODEC_OK) { | 113 if (flush_status != MEDIA_CODEC_OK) { |
113 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 114 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
114 << "MediaCodecBridge::Reset() failed"; | 115 << "MediaCodecBridge::Reset() failed"; |
115 media_task_runner_->PostTask(FROM_HERE, internal_error_cb_); | 116 media_task_runner_->PostTask(FROM_HERE, internal_error_cb_); |
116 } | 117 } |
117 } | 118 } |
118 } | 119 } |
119 | 120 |
120 void MediaCodecDecoder::ReleaseMediaCodec() { | 121 void MediaCodecDecoder::ReleaseMediaCodec() { |
121 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 122 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
122 | 123 |
123 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 124 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
124 | 125 |
| 126 DCHECK(!decoder_thread_.IsRunning()); |
| 127 |
125 media_codec_bridge_.reset(); | 128 media_codec_bridge_.reset(); |
126 preroll_mode_ = kPrerollTillPTS; | 129 |
| 130 // |is_prepared_| is set on the decoder thread, it shouldn't be running now. |
| 131 is_prepared_ = false; |
127 } | 132 } |
128 | 133 |
129 bool MediaCodecDecoder::IsPrefetchingOrPlaying() const { | 134 bool MediaCodecDecoder::IsPrefetchingOrPlaying() const { |
130 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 135 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
131 | 136 |
132 // Whether decoder needs to be stopped. | 137 // Whether decoder needs to be stopped. |
133 base::AutoLock lock(state_lock_); | 138 base::AutoLock lock(state_lock_); |
134 switch (state_) { | 139 switch (state_) { |
135 case kPrefetching: | 140 case kPrefetching: |
136 case kPrefetched: | 141 case kPrefetched: |
(...skipping 19 matching lines...) Expand all Loading... |
156 | 161 |
157 bool MediaCodecDecoder::IsCompleted() const { | 162 bool MediaCodecDecoder::IsCompleted() const { |
158 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 163 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
159 | 164 |
160 return completed_; | 165 return completed_; |
161 } | 166 } |
162 | 167 |
163 bool MediaCodecDecoder::NotCompletedAndNeedsPreroll() const { | 168 bool MediaCodecDecoder::NotCompletedAndNeedsPreroll() const { |
164 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 169 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
165 | 170 |
166 return HasStream() && preroll_mode_ != kNoPreroll && !completed_; | 171 return HasStream() && !completed_ && |
| 172 (!is_prepared_ || preroll_timestamp_ != base::TimeDelta()); |
167 } | 173 } |
168 | 174 |
169 void MediaCodecDecoder::SetDecodingUntilOutputIsPresent() { | 175 void MediaCodecDecoder::SetPrerollTimestamp(base::TimeDelta preroll_timestamp) { |
170 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 176 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
171 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 177 DVLOG(1) << class_name() << "::" << __FUNCTION__ << ": " << preroll_timestamp; |
172 | 178 |
173 preroll_mode_ = kPrerollTillOutputIsPresent; | 179 preroll_timestamp_ = preroll_timestamp; |
174 } | 180 } |
175 | 181 |
176 base::android::ScopedJavaLocalRef<jobject> MediaCodecDecoder::GetMediaCrypto() { | 182 base::android::ScopedJavaLocalRef<jobject> MediaCodecDecoder::GetMediaCrypto() { |
177 base::android::ScopedJavaLocalRef<jobject> media_crypto; | 183 base::android::ScopedJavaLocalRef<jobject> media_crypto; |
178 | 184 |
179 // TODO(timav): implement DRM. | 185 // TODO(timav): implement DRM. |
180 // drm_bridge_ is not implemented | 186 // drm_bridge_ is not implemented |
181 // if (drm_bridge_) | 187 // if (drm_bridge_) |
182 // media_crypto = drm_bridge_->GetMediaCrypto(); | 188 // media_crypto = drm_bridge_->GetMediaCrypto(); |
183 return media_crypto; | 189 return media_crypto; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 DCHECK(!decoder_thread_.IsRunning()); | 241 DCHECK(!decoder_thread_.IsRunning()); |
236 | 242 |
237 // For video the first frame after reconfiguration must be key frame. | 243 // For video the first frame after reconfiguration must be key frame. |
238 if (result == kConfigOk) | 244 if (result == kConfigOk) |
239 verify_next_frame_is_key_ = true; | 245 verify_next_frame_is_key_ = true; |
240 #endif | 246 #endif |
241 | 247 |
242 return result; | 248 return result; |
243 } | 249 } |
244 | 250 |
245 bool MediaCodecDecoder::Preroll(base::TimeDelta preroll_timestamp, | 251 bool MediaCodecDecoder::Preroll(const base::Closure& preroll_done_cb) { |
246 const base::Closure& preroll_done_cb) { | |
247 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 252 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
248 | 253 |
249 DVLOG(1) << class_name() << "::" << __FUNCTION__ | 254 DVLOG(1) << class_name() << "::" << __FUNCTION__ |
250 << " preroll_timestamp:" << preroll_timestamp; | 255 << " preroll_timestamp:" << preroll_timestamp_; |
251 | 256 |
252 DecoderState state = GetState(); | 257 DecoderState state = GetState(); |
253 if (state != kPrefetched) { | 258 if (state != kPrefetched) { |
254 DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": wrong state " | 259 DVLOG(0) << class_name() << "::" << __FUNCTION__ << ": wrong state " |
255 << AsString(state) << ", ignoring"; | 260 << AsString(state) << ", ignoring"; |
256 return false; | 261 return false; |
257 } | 262 } |
258 | 263 |
259 if (!media_codec_bridge_) { | 264 if (!media_codec_bridge_) { |
260 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 265 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
261 << ": not configured, ignoring"; | 266 << ": not configured, ignoring"; |
262 return false; | 267 return false; |
263 } | 268 } |
264 | 269 |
265 DCHECK(!decoder_thread_.IsRunning()); | 270 DCHECK(!decoder_thread_.IsRunning()); |
266 DCHECK(preroll_mode_ != kNoPreroll); | |
267 | 271 |
268 preroll_done_cb_ = preroll_done_cb; | 272 preroll_done_cb_ = preroll_done_cb; |
269 | 273 |
270 // We only synchronize video stream. | 274 // We only synchronize video stream. |
271 DissociatePTSFromTime(); // associaton will happen after preroll is done. | 275 DissociatePTSFromTime(); // associaton will happen after preroll is done. |
272 | 276 |
273 preroll_timestamp_ = (preroll_mode_ == kPrerollTillPTS) ? preroll_timestamp | |
274 : base::TimeDelta(); | |
275 | |
276 last_frame_posted_ = false; | 277 last_frame_posted_ = false; |
277 | 278 |
278 // Start the decoder thread | 279 // Start the decoder thread |
279 if (!decoder_thread_.Start()) { | 280 if (!decoder_thread_.Start()) { |
280 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 281 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
281 << ": cannot start decoder thread"; | 282 << ": cannot start decoder thread"; |
282 return false; | 283 return false; |
283 } | 284 } |
284 | 285 |
285 SetState(kPrerolling); | 286 SetState(kPrerolling); |
(...skipping 20 matching lines...) Expand all Loading... |
306 } | 307 } |
307 | 308 |
308 if (!media_codec_bridge_) { | 309 if (!media_codec_bridge_) { |
309 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 310 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
310 << ": not configured, ignoring"; | 311 << ": not configured, ignoring"; |
311 return false; | 312 return false; |
312 } | 313 } |
313 | 314 |
314 // We only synchronize video stream. | 315 // We only synchronize video stream. |
315 AssociateCurrentTimeWithPTS(start_timestamp); | 316 AssociateCurrentTimeWithPTS(start_timestamp); |
316 preroll_timestamp_ = base::TimeDelta(); | 317 |
| 318 DCHECK(preroll_timestamp_ == base::TimeDelta()); |
317 | 319 |
318 // Start the decoder thread | 320 // Start the decoder thread |
319 if (!decoder_thread_.IsRunning()) { | 321 if (!decoder_thread_.IsRunning()) { |
320 last_frame_posted_ = false; | 322 last_frame_posted_ = false; |
321 if (!decoder_thread_.Start()) { | 323 if (!decoder_thread_.Start()) { |
322 DVLOG(1) << class_name() << "::" << __FUNCTION__ | 324 DVLOG(1) << class_name() << "::" << __FUNCTION__ |
323 << ": cannot start decoder thread"; | 325 << ": cannot start decoder thread"; |
324 return false; | 326 return false; |
325 } | 327 } |
326 } | 328 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 break; | 368 break; |
367 case kPrerolling: | 369 case kPrerolling: |
368 case kPrerolled: | 370 case kPrerolled: |
369 DCHECK(decoder_thread_.IsRunning()); | 371 DCHECK(decoder_thread_.IsRunning()); |
370 // Synchronous stop. | 372 // Synchronous stop. |
371 decoder_thread_.Stop(); | 373 decoder_thread_.Stop(); |
372 SetState(kStopped); | 374 SetState(kStopped); |
373 media_task_runner_->PostTask(FROM_HERE, stop_done_cb_); | 375 media_task_runner_->PostTask(FROM_HERE, stop_done_cb_); |
374 break; | 376 break; |
375 case kStopping: | 377 case kStopping: |
| 378 case kStopped: |
376 break; // ignore | 379 break; // ignore |
377 case kStopped: | |
378 case kPrefetching: | 380 case kPrefetching: |
379 case kPrefetched: | 381 case kPrefetched: |
380 // There is nothing to wait for, we can sent notification right away. | 382 // There is nothing to wait for, we can sent notification right away. |
381 DCHECK(!decoder_thread_.IsRunning()); | 383 DCHECK(!decoder_thread_.IsRunning()); |
382 SetState(kStopped); | 384 SetState(kStopped); |
383 media_task_runner_->PostTask(FROM_HERE, stop_done_cb_); | 385 media_task_runner_->PostTask(FROM_HERE, stop_done_cb_); |
384 break; | 386 break; |
385 default: | 387 default: |
386 NOTREACHED(); | 388 NOTREACHED(); |
387 break; | 389 break; |
388 } | 390 } |
389 } | 391 } |
390 | 392 |
391 void MediaCodecDecoder::OnLastFrameRendered(bool eos_encountered) { | 393 void MediaCodecDecoder::OnLastFrameRendered(bool eos_encountered) { |
392 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 394 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
393 | 395 |
394 // http://crbug.com/526755 | 396 // http://crbug.com/526755 |
395 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 397 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
396 << " eos_encountered:" << eos_encountered; | 398 << " eos_encountered:" << eos_encountered; |
397 | 399 |
398 decoder_thread_.Stop(); // synchronous | 400 decoder_thread_.Stop(); // synchronous |
399 | 401 |
400 SetState(kStopped); | 402 SetState(kStopped); |
401 completed_ = (eos_encountered && !drain_decoder_); | 403 completed_ = (eos_encountered && !drain_decoder_); |
402 | 404 |
| 405 // If the stream is completed during preroll we need to report it since |
| 406 // another stream might be running and the player waits for two callbacks. |
403 if (completed_ && !preroll_done_cb_.is_null()) { | 407 if (completed_ && !preroll_done_cb_.is_null()) { |
404 // http://crbug.com/526755 | 408 // http://crbug.com/526755 |
405 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 409 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
406 << ": completed, calling preroll_done_cb_"; | 410 << ": completed, calling preroll_done_cb_"; |
| 411 |
| 412 preroll_timestamp_ = base::TimeDelta(); |
407 media_task_runner_->PostTask(FROM_HERE, | 413 media_task_runner_->PostTask(FROM_HERE, |
408 base::ResetAndReturn(&preroll_done_cb_)); | 414 base::ResetAndReturn(&preroll_done_cb_)); |
409 } | 415 } |
410 | 416 |
411 if (eos_encountered && drain_decoder_) { | 417 if (eos_encountered && drain_decoder_) { |
412 ReleaseMediaCodec(); | |
413 drain_decoder_ = false; | 418 drain_decoder_ = false; |
414 eos_enqueued_ = false; | 419 eos_enqueued_ = false; |
415 preroll_mode_ = kPrerollTillOutputIsPresent; | 420 ReleaseMediaCodec(); |
416 media_task_runner_->PostTask(FROM_HERE, decoder_drained_cb_); | 421 media_task_runner_->PostTask(FROM_HERE, decoder_drained_cb_); |
417 } | 422 } |
418 | 423 |
419 media_task_runner_->PostTask(FROM_HERE, stop_done_cb_); | 424 media_task_runner_->PostTask(FROM_HERE, stop_done_cb_); |
420 } | 425 } |
421 | 426 |
422 void MediaCodecDecoder::OnPrerollDone() { | 427 void MediaCodecDecoder::OnPrerollDone() { |
423 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 428 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
424 | 429 |
425 // http://crbug.com/526755 | 430 // http://crbug.com/526755 |
426 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 431 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
427 << " state:" << AsString(GetState()); | 432 << " state:" << AsString(GetState()); |
428 | 433 |
429 preroll_mode_ = kNoPreroll; | 434 preroll_timestamp_ = base::TimeDelta(); |
430 | 435 |
431 // The state might be kStopping. | 436 // The state might be kStopping (?) |
432 if (GetState() == kPrerolling) { | 437 if (GetState() == kPrerolling) |
433 SetState(kPrerolled); | 438 SetState(kPrerolled); |
434 media_task_runner_->PostTask(FROM_HERE, | 439 |
435 base::ResetAndReturn(&preroll_done_cb_)); | 440 if (!preroll_done_cb_.is_null()) |
436 } | 441 base::ResetAndReturn(&preroll_done_cb_).Run(); |
437 } | 442 } |
438 | 443 |
439 void MediaCodecDecoder::OnDemuxerDataAvailable(const DemuxerData& data) { | 444 void MediaCodecDecoder::OnDemuxerDataAvailable(const DemuxerData& data) { |
440 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 445 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
441 | 446 |
442 // If |data| contains an aborted data, the last AU will have kAborted status. | 447 // If |data| contains an aborted data, the last AU will have kAborted status. |
443 bool aborted_data = | 448 bool aborted_data = |
444 !data.access_units.empty() && | 449 !data.access_units.empty() && |
445 data.access_units.back().status == DemuxerStream::kAborted; | 450 data.access_units.back().status == DemuxerStream::kAborted; |
446 | 451 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 596 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
592 << ": kStopping, no delayed tasks, posting OnLastFrameRendered"; | 597 << ": kStopping, no delayed tasks, posting OnLastFrameRendered"; |
593 media_task_runner_->PostTask( | 598 media_task_runner_->PostTask( |
594 FROM_HERE, base::Bind(&MediaCodecDecoder::OnLastFrameRendered, | 599 FROM_HERE, base::Bind(&MediaCodecDecoder::OnLastFrameRendered, |
595 weak_factory_.GetWeakPtr(), false)); | 600 weak_factory_.GetWeakPtr(), false)); |
596 last_frame_posted_ = true; | 601 last_frame_posted_ = true; |
597 } | 602 } |
598 | 603 |
599 // We can stop processing, the |au_queue_| and MediaCodec queues can freeze. | 604 // We can stop processing, the |au_queue_| and MediaCodec queues can freeze. |
600 // We only need to let finish the delayed rendering tasks. | 605 // We only need to let finish the delayed rendering tasks. |
| 606 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " kStopping, returning"; |
601 return; | 607 return; |
602 } | 608 } |
603 | 609 |
604 DCHECK(state == kPrerolling || state == kRunning); | 610 DCHECK(state == kPrerolling || state == kRunning); |
605 | 611 |
606 if (!EnqueueInputBuffer()) | 612 if (!EnqueueInputBuffer()) |
607 return; | 613 return; |
608 | 614 |
609 if (!DepleteOutputBufferQueue()) | 615 if (!DepleteOutputBufferQueue()) |
610 return; | 616 return; |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 | 816 |
811 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: | 817 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: |
812 DVLOG(2) << class_name() << "::" << __FUNCTION__ | 818 DVLOG(2) << class_name() << "::" << __FUNCTION__ |
813 << " MEDIA_CODEC_OUTPUT_FORMAT_CHANGED"; | 819 << " MEDIA_CODEC_OUTPUT_FORMAT_CHANGED"; |
814 OnOutputFormatChanged(); | 820 OnOutputFormatChanged(); |
815 break; | 821 break; |
816 | 822 |
817 case MEDIA_CODEC_OK: | 823 case MEDIA_CODEC_OK: |
818 // We got the decoded frame. | 824 // We got the decoded frame. |
819 | 825 |
| 826 is_prepared_ = true; |
| 827 |
820 if (pts < preroll_timestamp_) | 828 if (pts < preroll_timestamp_) |
821 render_mode = kRenderSkip; | 829 render_mode = kRenderSkip; |
822 else if (GetState() == kPrerolling) | 830 else if (GetState() == kPrerolling) |
823 render_mode = kRenderAfterPreroll; | 831 render_mode = kRenderAfterPreroll; |
824 else | 832 else |
825 render_mode = kRenderNow; | 833 render_mode = kRenderNow; |
826 | 834 |
827 Render(buffer_index, offset, size, render_mode, pts, eos_encountered); | 835 Render(buffer_index, offset, size, render_mode, pts, eos_encountered); |
828 | 836 |
829 if (render_mode == kRenderAfterPreroll) { | 837 if (render_mode == kRenderAfterPreroll) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 RETURN_STRING(kStopping); | 913 RETURN_STRING(kStopping); |
906 RETURN_STRING(kInEmergencyStop); | 914 RETURN_STRING(kInEmergencyStop); |
907 RETURN_STRING(kError); | 915 RETURN_STRING(kError); |
908 } | 916 } |
909 return nullptr; // crash early | 917 return nullptr; // crash early |
910 } | 918 } |
911 | 919 |
912 #undef RETURN_STRING | 920 #undef RETURN_STRING |
913 | 921 |
914 } // namespace media | 922 } // namespace media |
OLD | NEW |