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

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

Issue 10704142: Merge 143765 - Ensure media's buffered ranges always have a range that includes currentTime. (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1180/src/
Patch Set: Created 8 years, 5 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 12 matching lines...) Expand all
23 #include "media/ffmpeg/ffmpeg_common.h" 23 #include "media/ffmpeg/ffmpeg_common.h"
24 #include "media/filters/bitstream_converter.h" 24 #include "media/filters/bitstream_converter.h"
25 #include "media/filters/ffmpeg_glue.h" 25 #include "media/filters/ffmpeg_glue.h"
26 #include "media/filters/ffmpeg_h264_bitstream_converter.h" 26 #include "media/filters/ffmpeg_h264_bitstream_converter.h"
27 27
28 namespace media { 28 namespace media {
29 29
30 // 30 //
31 // FFmpegDemuxerStream 31 // FFmpegDemuxerStream
32 // 32 //
33 FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer, 33 FFmpegDemuxerStream::FFmpegDemuxerStream(
34 AVStream* stream) 34 FFmpegDemuxer* demuxer,
35 AVStream* stream)
35 : demuxer_(demuxer), 36 : demuxer_(demuxer),
36 stream_(stream), 37 stream_(stream),
37 type_(UNKNOWN), 38 type_(UNKNOWN),
38 discontinuous_(false), 39 discontinuous_(false),
39 stopped_(false) { 40 stopped_(false),
41 last_packet_timestamp_(kNoTimestamp()) {
40 DCHECK(demuxer_); 42 DCHECK(demuxer_);
41 43
42 // Determine our media format. 44 // Determine our media format.
43 switch (stream->codec->codec_type) { 45 switch (stream->codec->codec_type) {
44 case AVMEDIA_TYPE_AUDIO: 46 case AVMEDIA_TYPE_AUDIO:
45 type_ = AUDIO; 47 type_ = AUDIO;
46 AVCodecContextToAudioDecoderConfig(stream->codec, &audio_config_); 48 AVCodecContextToAudioDecoderConfig(stream->codec, &audio_config_);
47 break; 49 break;
48 case AVMEDIA_TYPE_VIDEO: 50 case AVMEDIA_TYPE_VIDEO:
49 type_ = VIDEO; 51 type_ = VIDEO;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 } 89 }
88 90
89 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will 91 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will
90 // reference inner memory of FFmpeg. As such we should transfer the packet 92 // reference inner memory of FFmpeg. As such we should transfer the packet
91 // into memory we control. 93 // into memory we control.
92 buffer = DecoderBuffer::CopyFrom(packet->data, packet->size); 94 buffer = DecoderBuffer::CopyFrom(packet->data, packet->size);
93 buffer->SetTimestamp(ConvertStreamTimestamp( 95 buffer->SetTimestamp(ConvertStreamTimestamp(
94 stream_->time_base, packet->pts)); 96 stream_->time_base, packet->pts));
95 buffer->SetDuration(ConvertStreamTimestamp( 97 buffer->SetDuration(ConvertStreamTimestamp(
96 stream_->time_base, packet->duration)); 98 stream_->time_base, packet->duration));
99 if (buffer->GetTimestamp() != kNoTimestamp() &&
100 last_packet_timestamp_ != kNoTimestamp() &&
101 last_packet_timestamp_ < buffer->GetTimestamp()) {
102 buffered_ranges_.Add(last_packet_timestamp_, buffer->GetTimestamp());
103 demuxer_->message_loop()->PostTask(FROM_HERE, base::Bind(
104 &FFmpegDemuxer::NotifyBufferingChanged, demuxer_));
105 }
106 last_packet_timestamp_ = buffer->GetTimestamp();
97 } 107 }
98 108
99 buffer_queue_.push_back(buffer); 109 buffer_queue_.push_back(buffer);
100 FulfillPendingRead(); 110 FulfillPendingRead();
101 return; 111 return;
102 } 112 }
103 113
104 void FFmpegDemuxerStream::FlushBuffers() { 114 void FFmpegDemuxerStream::FlushBuffers() {
105 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 115 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop());
106 base::AutoLock auto_lock(lock_); 116 base::AutoLock auto_lock(lock_);
107 DCHECK(read_queue_.empty()) << "Read requests should be empty"; 117 DCHECK(read_queue_.empty()) << "Read requests should be empty";
108 buffer_queue_.clear(); 118 buffer_queue_.clear();
119 last_packet_timestamp_ = kNoTimestamp();
109 } 120 }
110 121
111 void FFmpegDemuxerStream::Stop() { 122 void FFmpegDemuxerStream::Stop() {
112 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 123 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop());
113 base::AutoLock auto_lock(lock_); 124 base::AutoLock auto_lock(lock_);
114 buffer_queue_.clear(); 125 buffer_queue_.clear();
115 for (ReadQueue::iterator it = read_queue_.begin(); 126 for (ReadQueue::iterator it = read_queue_.begin();
116 it != read_queue_.end(); ++it) { 127 it != read_queue_.end(); ++it) {
117 it->Run(scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer())); 128 it->Run(scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer()));
118 } 129 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 base::AutoLock auto_lock(lock_); 239 base::AutoLock auto_lock(lock_);
229 DCHECK(stopped_); 240 DCHECK(stopped_);
230 DCHECK(read_queue_.empty()); 241 DCHECK(read_queue_.empty());
231 DCHECK(buffer_queue_.empty()); 242 DCHECK(buffer_queue_.empty());
232 } 243 }
233 244
234 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const { 245 base::TimeDelta FFmpegDemuxerStream::GetElapsedTime() const {
235 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts); 246 return ConvertStreamTimestamp(stream_->time_base, stream_->cur_dts);
236 } 247 }
237 248
249 Ranges<base::TimeDelta> FFmpegDemuxerStream::GetBufferedRanges() {
250 base::AutoLock auto_lock(lock_);
251 return buffered_ranges_;
252 }
253
238 // static 254 // static
239 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp( 255 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
240 const AVRational& time_base, int64 timestamp) { 256 const AVRational& time_base, int64 timestamp) {
241 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE)) 257 if (timestamp == static_cast<int64>(AV_NOPTS_VALUE))
242 return kNoTimestamp(); 258 return kNoTimestamp();
243 259
244 return ConvertFromTimeBase(time_base, timestamp); 260 return ConvertFromTimeBase(time_base, timestamp);
245 } 261 }
246 262
247 // 263 //
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 int FFmpegDemuxer::WaitForRead() { 716 int FFmpegDemuxer::WaitForRead() {
701 read_event_.Wait(); 717 read_event_.Wait();
702 return last_read_bytes_; 718 return last_read_bytes_;
703 } 719 }
704 720
705 void FFmpegDemuxer::SignalReadCompleted(int size) { 721 void FFmpegDemuxer::SignalReadCompleted(int size) {
706 last_read_bytes_ = size; 722 last_read_bytes_ = size;
707 read_event_.Signal(); 723 read_event_.Signal();
708 } 724 }
709 725
726 void FFmpegDemuxer::NotifyBufferingChanged() {
727 DCHECK_EQ(MessageLoop::current(), message_loop_);
728 Ranges<base::TimeDelta> buffered;
729 scoped_refptr<DemuxerStream> audio =
730 audio_disabled_ ? NULL : GetStream(DemuxerStream::AUDIO);
731 scoped_refptr<DemuxerStream> video = GetStream(DemuxerStream::VIDEO);
732 if (audio && video) {
733 buffered = audio->GetBufferedRanges().IntersectionWith(
734 video->GetBufferedRanges());
735 } else if (audio) {
736 buffered = audio->GetBufferedRanges();
737 } else if (video) {
738 buffered = video->GetBufferedRanges();
739 }
740 for (size_t i = 0; i < buffered.size(); ++i)
741 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i));
742 }
743
710 } // namespace media 744 } // 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