| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |