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

Side by Side Diff: media/filters/ffmpeg_demuxer.cc

Issue 10855051: Use enum instead of string in MessageLoopFactory::GetMessageLoop* (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 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
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/filters/ffmpeg_demuxer.h" 5 #include "media/filters/ffmpeg_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 default: 52 default:
53 NOTREACHED(); 53 NOTREACHED();
54 break; 54 break;
55 } 55 }
56 56
57 // Calculate the duration. 57 // Calculate the duration.
58 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration); 58 duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration);
59 } 59 }
60 60
61 bool FFmpegDemuxerStream::HasPendingReads() { 61 bool FFmpegDemuxerStream::HasPendingReads() {
62 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 62 DCHECK(demuxer_->message_loop()->BelongsToCurrentThread());
63 base::AutoLock auto_lock(lock_); 63 base::AutoLock auto_lock(lock_);
64 DCHECK(!stopped_ || read_queue_.empty()) 64 DCHECK(!stopped_ || read_queue_.empty())
65 << "Read queue should have been emptied if demuxing stream is stopped"; 65 << "Read queue should have been emptied if demuxing stream is stopped";
66 return !read_queue_.empty(); 66 return !read_queue_.empty();
67 } 67 }
68 68
69 void FFmpegDemuxerStream::EnqueuePacket( 69 void FFmpegDemuxerStream::EnqueuePacket(
70 scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet) { 70 scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet) {
71 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 71 DCHECK(demuxer_->message_loop()->BelongsToCurrentThread());
72 72
73 base::AutoLock auto_lock(lock_); 73 base::AutoLock auto_lock(lock_);
74 if (stopped_) { 74 if (stopped_) {
75 NOTREACHED() << "Attempted to enqueue packet on a stopped stream"; 75 NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
76 return; 76 return;
77 } 77 }
78 78
79 scoped_refptr<DecoderBuffer> buffer; 79 scoped_refptr<DecoderBuffer> buffer;
80 if (!packet.get()) { 80 if (!packet.get()) {
81 buffer = DecoderBuffer::CreateEOSBuffer(); 81 buffer = DecoderBuffer::CreateEOSBuffer();
(...skipping 21 matching lines...) Expand all
103 } 103 }
104 last_packet_timestamp_ = buffer->GetTimestamp(); 104 last_packet_timestamp_ = buffer->GetTimestamp();
105 } 105 }
106 106
107 buffer_queue_.push_back(buffer); 107 buffer_queue_.push_back(buffer);
108 FulfillPendingRead(); 108 FulfillPendingRead();
109 return; 109 return;
110 } 110 }
111 111
112 void FFmpegDemuxerStream::FlushBuffers() { 112 void FFmpegDemuxerStream::FlushBuffers() {
113 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 113 DCHECK(demuxer_->message_loop()->BelongsToCurrentThread());
114 base::AutoLock auto_lock(lock_); 114 base::AutoLock auto_lock(lock_);
115 DCHECK(read_queue_.empty()) << "Read requests should be empty"; 115 DCHECK(read_queue_.empty()) << "Read requests should be empty";
116 buffer_queue_.clear(); 116 buffer_queue_.clear();
117 last_packet_timestamp_ = kNoTimestamp(); 117 last_packet_timestamp_ = kNoTimestamp();
118 } 118 }
119 119
120 void FFmpegDemuxerStream::Stop() { 120 void FFmpegDemuxerStream::Stop() {
121 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 121 DCHECK(demuxer_->message_loop()->BelongsToCurrentThread());
122 base::AutoLock auto_lock(lock_); 122 base::AutoLock auto_lock(lock_);
123 buffer_queue_.clear(); 123 buffer_queue_.clear();
124 for (ReadQueue::iterator it = read_queue_.begin(); 124 for (ReadQueue::iterator it = read_queue_.begin();
125 it != read_queue_.end(); ++it) { 125 it != read_queue_.end(); ++it) {
126 it->Run(DemuxerStream::kOk, 126 it->Run(DemuxerStream::kOk,
127 scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer())); 127 scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer()));
128 } 128 }
129 read_queue_.clear(); 129 read_queue_.clear();
130 stopped_ = true; 130 stopped_ = true;
131 } 131 }
(...skipping 29 matching lines...) Expand all
161 return; 161 return;
162 } 162 }
163 163
164 // Send the oldest buffer back. 164 // Send the oldest buffer back.
165 scoped_refptr<DecoderBuffer> buffer = buffer_queue_.front(); 165 scoped_refptr<DecoderBuffer> buffer = buffer_queue_.front();
166 buffer_queue_.pop_front(); 166 buffer_queue_.pop_front();
167 read_cb.Run(DemuxerStream::kOk, buffer); 167 read_cb.Run(DemuxerStream::kOk, buffer);
168 } 168 }
169 169
170 void FFmpegDemuxerStream::ReadTask(const ReadCB& read_cb) { 170 void FFmpegDemuxerStream::ReadTask(const ReadCB& read_cb) {
171 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 171 DCHECK(demuxer_->message_loop()->BelongsToCurrentThread());
172 172
173 base::AutoLock auto_lock(lock_); 173 base::AutoLock auto_lock(lock_);
174 // Don't accept any additional reads if we've been told to stop. 174 // Don't accept any additional reads if we've been told to stop.
175 // 175 //
176 // TODO(scherkus): it would be cleaner if we replied with an error message. 176 // TODO(scherkus): it would be cleaner if we replied with an error message.
177 if (stopped_) { 177 if (stopped_) {
178 read_cb.Run(DemuxerStream::kOk, 178 read_cb.Run(DemuxerStream::kOk,
179 scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer())); 179 scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer()));
180 return; 180 return;
181 } 181 }
182 182
183 // Enqueue the callback and attempt to satisfy it immediately. 183 // Enqueue the callback and attempt to satisfy it immediately.
184 read_queue_.push_back(read_cb); 184 read_queue_.push_back(read_cb);
185 FulfillPendingRead(); 185 FulfillPendingRead();
186 186
187 // Check if there are still pending reads, demux some more. 187 // Check if there are still pending reads, demux some more.
188 if (!read_queue_.empty()) { 188 if (!read_queue_.empty()) {
189 demuxer_->PostDemuxTask(); 189 demuxer_->PostDemuxTask();
190 } 190 }
191 } 191 }
192 192
193 void FFmpegDemuxerStream::FulfillPendingRead() { 193 void FFmpegDemuxerStream::FulfillPendingRead() {
194 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 194 DCHECK(demuxer_->message_loop()->BelongsToCurrentThread());
195 lock_.AssertAcquired(); 195 lock_.AssertAcquired();
196 if (buffer_queue_.empty() || read_queue_.empty()) { 196 if (buffer_queue_.empty() || read_queue_.empty()) {
197 return; 197 return;
198 } 198 }
199 199
200 // Dequeue a buffer and pending read pair. 200 // Dequeue a buffer and pending read pair.
201 scoped_refptr<DecoderBuffer> buffer = buffer_queue_.front(); 201 scoped_refptr<DecoderBuffer> buffer = buffer_queue_.front();
202 ReadCB read_cb(read_queue_.front()); 202 ReadCB read_cb(read_queue_.front());
203 buffer_queue_.pop_front(); 203 buffer_queue_.pop_front();
204 read_queue_.pop_front(); 204 read_queue_.pop_front();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE)) 248 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
249 return kNoTimestamp(); 249 return kNoTimestamp();
250 250
251 return ConvertFromTimeBase(time_base, timestamp); 251 return ConvertFromTimeBase(time_base, timestamp);
252 } 252 }
253 253
254 // 254 //
255 // FFmpegDemuxer 255 // FFmpegDemuxer
256 // 256 //
257 FFmpegDemuxer::FFmpegDemuxer( 257 FFmpegDemuxer::FFmpegDemuxer(
258 MessageLoop* message_loop, 258 const scoped_refptr<base::MessageLoopProxy>& message_loop,
259 const scoped_refptr<DataSource>& data_source) 259 const scoped_refptr<DataSource>& data_source)
260 : host_(NULL), 260 : host_(NULL),
261 message_loop_(message_loop), 261 message_loop_(message_loop),
262 format_context_(NULL), 262 format_context_(NULL),
263 data_source_(data_source), 263 data_source_(data_source),
264 read_event_(false, false), 264 read_event_(false, false),
265 read_has_failed_(false), 265 read_has_failed_(false),
266 last_read_bytes_(0), 266 last_read_bytes_(0),
267 read_position_(0), 267 read_position_(0),
268 bitrate_(0), 268 bitrate_(0),
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 DCHECK(data_source_); 401 DCHECK(data_source_);
402 return data_source_->GetSize(size_out); 402 return data_source_->GetSize(size_out);
403 } 403 }
404 404
405 bool FFmpegDemuxer::IsStreaming() { 405 bool FFmpegDemuxer::IsStreaming() {
406 DCHECK(host_); 406 DCHECK(host_);
407 DCHECK(data_source_); 407 DCHECK(data_source_);
408 return data_source_->IsStreaming(); 408 return data_source_->IsStreaming();
409 } 409 }
410 410
411 MessageLoop* FFmpegDemuxer::message_loop() { 411 scoped_refptr<base::MessageLoopProxy> FFmpegDemuxer::message_loop() {
412 return message_loop_; 412 return message_loop_;
413 } 413 }
414 414
415 // Helper for calculating the bitrate of the media based on information stored 415 // Helper for calculating the bitrate of the media based on information stored
416 // in |format_context| or failing that the size and duration of the media. 416 // in |format_context| or failing that the size and duration of the media.
417 // 417 //
418 // Returns 0 if a bitrate could not be determined. 418 // Returns 0 if a bitrate could not be determined.
419 static int CalculateBitrate( 419 static int CalculateBitrate(
420 AVFormatContext* format_context, 420 AVFormatContext* format_context,
421 const base::TimeDelta& duration, 421 const base::TimeDelta& duration,
(...skipping 21 matching lines...) Expand all
443 443
444 // Do math in floating point as we'd overflow an int64 if the filesize was 444 // Do math in floating point as we'd overflow an int64 if the filesize was
445 // larger than ~1073GB. 445 // larger than ~1073GB.
446 double bytes = filesize_in_bytes; 446 double bytes = filesize_in_bytes;
447 double duration_us = duration.InMicroseconds(); 447 double duration_us = duration.InMicroseconds();
448 return bytes * 8000000.0 / duration_us; 448 return bytes * 8000000.0 / duration_us;
449 } 449 }
450 450
451 void FFmpegDemuxer::InitializeTask(DemuxerHost* host, 451 void FFmpegDemuxer::InitializeTask(DemuxerHost* host,
452 const PipelineStatusCB& status_cb) { 452 const PipelineStatusCB& status_cb) {
453 DCHECK_EQ(MessageLoop::current(), message_loop_); 453 DCHECK(message_loop_->BelongsToCurrentThread());
454 host_ = host; 454 host_ = host;
455 455
456 // TODO(scherkus): DataSource should have a host by this point, 456 // TODO(scherkus): DataSource should have a host by this point,
457 // see http://crbug.com/122071 457 // see http://crbug.com/122071
458 data_source_->set_host(host); 458 data_source_->set_host(host);
459 459
460 // Add ourself to Protocol list and get our unique key. 460 // Add ourself to Protocol list and get our unique key.
461 std::string key = FFmpegGlue::GetInstance()->AddProtocol(this); 461 std::string key = FFmpegGlue::GetInstance()->AddProtocol(this);
462 462
463 // Open FFmpeg AVFormatContext. 463 // Open FFmpeg AVFormatContext.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 int64 filesize_in_bytes = 0; 562 int64 filesize_in_bytes = 0;
563 GetSize(&filesize_in_bytes); 563 GetSize(&filesize_in_bytes);
564 bitrate_ = CalculateBitrate(format_context_, max_duration, filesize_in_bytes); 564 bitrate_ = CalculateBitrate(format_context_, max_duration, filesize_in_bytes);
565 if (bitrate_ > 0) 565 if (bitrate_ > 0)
566 data_source_->SetBitrate(bitrate_); 566 data_source_->SetBitrate(bitrate_);
567 567
568 status_cb.Run(PIPELINE_OK); 568 status_cb.Run(PIPELINE_OK);
569 } 569 }
570 570
571 void FFmpegDemuxer::SeekTask(base::TimeDelta time, const PipelineStatusCB& cb) { 571 void FFmpegDemuxer::SeekTask(base::TimeDelta time, const PipelineStatusCB& cb) {
572 DCHECK_EQ(MessageLoop::current(), message_loop_); 572 DCHECK(message_loop_->BelongsToCurrentThread());
573 573
574 // Tell streams to flush buffers due to seeking. 574 // Tell streams to flush buffers due to seeking.
575 StreamVector::iterator iter; 575 StreamVector::iterator iter;
576 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 576 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
577 if (*iter) 577 if (*iter)
578 (*iter)->FlushBuffers(); 578 (*iter)->FlushBuffers();
579 } 579 }
580 580
581 // Always seek to a timestamp less than or equal to the desired timestamp. 581 // Always seek to a timestamp less than or equal to the desired timestamp.
582 int flags = AVSEEK_FLAG_BACKWARD; 582 int flags = AVSEEK_FLAG_BACKWARD;
583 583
584 // Passing -1 as our stream index lets FFmpeg pick a default stream. FFmpeg 584 // Passing -1 as our stream index lets FFmpeg pick a default stream. FFmpeg
585 // will attempt to use the lowest-index video stream, if present, followed by 585 // will attempt to use the lowest-index video stream, if present, followed by
586 // the lowest-index audio stream. 586 // the lowest-index audio stream.
587 if (av_seek_frame(format_context_, -1, time.InMicroseconds(), flags) < 0) { 587 if (av_seek_frame(format_context_, -1, time.InMicroseconds(), flags) < 0) {
588 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being 588 // Use VLOG(1) instead of NOTIMPLEMENTED() to prevent the message being
589 // captured from stdout and contaminates testing. 589 // captured from stdout and contaminates testing.
590 // TODO(scherkus): Implement this properly and signal error (BUG=23447). 590 // TODO(scherkus): Implement this properly and signal error (BUG=23447).
591 VLOG(1) << "Not implemented"; 591 VLOG(1) << "Not implemented";
592 } 592 }
593 593
594 // Notify we're finished seeking. 594 // Notify we're finished seeking.
595 cb.Run(PIPELINE_OK); 595 cb.Run(PIPELINE_OK);
596 } 596 }
597 597
598 void FFmpegDemuxer::DemuxTask() { 598 void FFmpegDemuxer::DemuxTask() {
599 DCHECK_EQ(MessageLoop::current(), message_loop_); 599 DCHECK(message_loop_->BelongsToCurrentThread());
600 600
601 // Make sure we have work to do before demuxing. 601 // Make sure we have work to do before demuxing.
602 if (!StreamsHavePendingReads()) { 602 if (!StreamsHavePendingReads()) {
603 return; 603 return;
604 } 604 }
605 605
606 // Allocate and read an AVPacket from the media. 606 // Allocate and read an AVPacket from the media.
607 scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet(new AVPacket()); 607 scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet(new AVPacket());
608 int result = av_read_frame(format_context_, packet.get()); 608 int result = av_read_frame(format_context_, packet.get());
609 if (result < 0) { 609 if (result < 0) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 } 648 }
649 649
650 // Create a loop by posting another task. This allows seek and message loop 650 // Create a loop by posting another task. This allows seek and message loop
651 // quit tasks to get processed. 651 // quit tasks to get processed.
652 if (StreamsHavePendingReads()) { 652 if (StreamsHavePendingReads()) {
653 PostDemuxTask(); 653 PostDemuxTask();
654 } 654 }
655 } 655 }
656 656
657 void FFmpegDemuxer::StopTask(const base::Closure& callback) { 657 void FFmpegDemuxer::StopTask(const base::Closure& callback) {
658 DCHECK_EQ(MessageLoop::current(), message_loop_); 658 DCHECK(message_loop_->BelongsToCurrentThread());
659 StreamVector::iterator iter; 659 StreamVector::iterator iter;
660 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 660 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
661 if (*iter) 661 if (*iter)
662 (*iter)->Stop(); 662 (*iter)->Stop();
663 } 663 }
664 if (data_source_) { 664 if (data_source_) {
665 data_source_->Stop(callback); 665 data_source_->Stop(callback);
666 } else { 666 } else {
667 callback.Run(); 667 callback.Run();
668 } 668 }
669 } 669 }
670 670
671 void FFmpegDemuxer::DisableAudioStreamTask() { 671 void FFmpegDemuxer::DisableAudioStreamTask() {
672 DCHECK_EQ(MessageLoop::current(), message_loop_); 672 DCHECK(message_loop_->BelongsToCurrentThread());
673 audio_disabled_ = true; 673 audio_disabled_ = true;
674 StreamVector::iterator iter; 674 StreamVector::iterator iter;
675 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 675 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
676 if (*iter && (*iter)->type() == DemuxerStream::AUDIO) { 676 if (*iter && (*iter)->type() == DemuxerStream::AUDIO) {
677 (*iter)->Stop(); 677 (*iter)->Stop();
678 } 678 }
679 } 679 }
680 } 680 }
681 681
682 bool FFmpegDemuxer::StreamsHavePendingReads() { 682 bool FFmpegDemuxer::StreamsHavePendingReads() {
683 DCHECK_EQ(MessageLoop::current(), message_loop_); 683 DCHECK(message_loop_->BelongsToCurrentThread());
684 StreamVector::iterator iter; 684 StreamVector::iterator iter;
685 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 685 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
686 if (*iter && (*iter)->HasPendingReads()) { 686 if (*iter && (*iter)->HasPendingReads()) {
687 return true; 687 return true;
688 } 688 }
689 } 689 }
690 return false; 690 return false;
691 } 691 }
692 692
693 void FFmpegDemuxer::StreamHasEnded() { 693 void FFmpegDemuxer::StreamHasEnded() {
694 DCHECK_EQ(MessageLoop::current(), message_loop_); 694 DCHECK(message_loop_->BelongsToCurrentThread());
695 StreamVector::iterator iter; 695 StreamVector::iterator iter;
696 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 696 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
697 if (!*iter || 697 if (!*iter ||
698 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { 698 (audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) {
699 continue; 699 continue;
700 } 700 }
701 (*iter)->EnqueuePacket( 701 (*iter)->EnqueuePacket(
702 scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket>()); 702 scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket>());
703 } 703 }
704 } 704 }
705 705
706 int FFmpegDemuxer::WaitForRead() { 706 int FFmpegDemuxer::WaitForRead() {
707 read_event_.Wait(); 707 read_event_.Wait();
708 return last_read_bytes_; 708 return last_read_bytes_;
709 } 709 }
710 710
711 void FFmpegDemuxer::SignalReadCompleted(int size) { 711 void FFmpegDemuxer::SignalReadCompleted(int size) {
712 last_read_bytes_ = size; 712 last_read_bytes_ = size;
713 read_event_.Signal(); 713 read_event_.Signal();
714 } 714 }
715 715
716 void FFmpegDemuxer::NotifyBufferingChanged() { 716 void FFmpegDemuxer::NotifyBufferingChanged() {
717 DCHECK_EQ(MessageLoop::current(), message_loop_); 717 DCHECK(message_loop_->BelongsToCurrentThread());
718 Ranges<base::TimeDelta> buffered; 718 Ranges<base::TimeDelta> buffered;
719 scoped_refptr<FFmpegDemuxerStream> audio = 719 scoped_refptr<FFmpegDemuxerStream> audio =
720 audio_disabled_ ? NULL : GetFFmpegStream(DemuxerStream::AUDIO); 720 audio_disabled_ ? NULL : GetFFmpegStream(DemuxerStream::AUDIO);
721 scoped_refptr<FFmpegDemuxerStream> video = 721 scoped_refptr<FFmpegDemuxerStream> video =
722 GetFFmpegStream(DemuxerStream::VIDEO); 722 GetFFmpegStream(DemuxerStream::VIDEO);
723 if (audio && video) { 723 if (audio && video) {
724 buffered = audio->GetBufferedRanges().IntersectionWith( 724 buffered = audio->GetBufferedRanges().IntersectionWith(
725 video->GetBufferedRanges()); 725 video->GetBufferedRanges());
726 } else if (audio) { 726 } else if (audio) {
727 buffered = audio->GetBufferedRanges(); 727 buffered = audio->GetBufferedRanges();
728 } else if (video) { 728 } else if (video) {
729 buffered = video->GetBufferedRanges(); 729 buffered = video->GetBufferedRanges();
730 } 730 }
731 for (size_t i = 0; i < buffered.size(); ++i) 731 for (size_t i = 0; i < buffered.size(); ++i)
732 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); 732 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
733 } 733 }
734 734
735 } // namespace media 735 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698