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

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

Issue 10581050: Ensure media's buffered ranges always have a range that includes currentTime. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Alternative implementation, introducing DataSourceHost::AddBufferedTimeRange(). Created 8 years, 6 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
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 const NotifyBufferedCB& notify_buffered_cb,
35 : demuxer_(demuxer), 35 FFmpegDemuxer* demuxer,
36 AVStream* stream)
37 : notify_buffered_cb_(notify_buffered_cb),
38 demuxer_(demuxer),
36 stream_(stream), 39 stream_(stream),
37 type_(UNKNOWN), 40 type_(UNKNOWN),
38 discontinuous_(false), 41 discontinuous_(false),
39 stopped_(false) { 42 stopped_(false) {
40 DCHECK(demuxer_); 43 DCHECK(demuxer_);
41 44
42 // Determine our media format. 45 // Determine our media format.
43 switch (stream->codec->codec_type) { 46 switch (stream->codec->codec_type) {
44 case AVMEDIA_TYPE_AUDIO: 47 case AVMEDIA_TYPE_AUDIO:
45 type_ = AUDIO; 48 type_ = AUDIO;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 !bitstream_converter_->ConvertPacket(packet.get())) { 88 !bitstream_converter_->ConvertPacket(packet.get())) {
86 LOG(ERROR) << "Format converstion failed."; 89 LOG(ERROR) << "Format converstion failed.";
87 } 90 }
88 91
89 // If a packet is returned by FFmpeg's av_parser_parse2() the packet will 92 // 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 93 // reference inner memory of FFmpeg. As such we should transfer the packet
91 // into memory we control. 94 // into memory we control.
92 buffer = DecoderBuffer::CopyFrom(packet->data, packet->size); 95 buffer = DecoderBuffer::CopyFrom(packet->data, packet->size);
93 buffer->SetTimestamp(ConvertStreamTimestamp( 96 buffer->SetTimestamp(ConvertStreamTimestamp(
94 stream_->time_base, packet->pts)); 97 stream_->time_base, packet->pts));
95 buffer->SetDuration(ConvertStreamTimestamp( 98 buffer->SetDuration(std::max(
96 stream_->time_base, packet->duration)); 99 base::TimeDelta(), ConvertStreamTimestamp(
scherkus (not reviewing) 2012/06/21 21:57:04 this means duration can no longer be kNoTimestamp(
Ami GONE FROM CHROMIUM 2012/06/21 22:49:02 That's interesting that you say that. What would y
scherkus (not reviewing) 2012/06/21 22:58:22 How negative were these durations? Were they −9,22
Ami GONE FROM CHROMIUM 2012/06/21 23:18:11 They were between 0 and -1.
100 stream_->time_base, packet->duration)));
101 if (last_packet_timestamp_ > base::TimeDelta() &&
scherkus (not reviewing) 2012/06/21 21:57:04 timestamps can be negative -- do you mean to check
Ami GONE FROM CHROMIUM 2012/06/21 22:49:02 No, I meant to check for TimeDelta() (to detect a
scherkus (not reviewing) 2012/06/21 22:58:22 Why not use kNoTS() to detect a flush isntead of z
Ami GONE FROM CHROMIUM 2012/06/21 23:18:11 Done.
102 last_packet_timestamp_ < buffer->GetTimestamp()) {
103 DCHECK(buffer->GetDuration() >= base::TimeDelta())
scherkus (not reviewing) 2012/06/21 21:57:04 ditto around here
Ami GONE FROM CHROMIUM 2012/06/21 22:49:02 This is leftover from debugging the aforementioned
104 << buffer->GetDuration().ToInternalValue();
105 notify_buffered_cb_.Run(last_packet_timestamp_,
106 buffer->GetTimestamp() + buffer->GetDuration());
107 }
108 last_packet_timestamp_ = buffer->GetTimestamp();
97 } 109 }
98 110
99 buffer_queue_.push_back(buffer); 111 buffer_queue_.push_back(buffer);
100 FulfillPendingRead(); 112 FulfillPendingRead();
101 return; 113 return;
102 } 114 }
103 115
104 void FFmpegDemuxerStream::FlushBuffers() { 116 void FFmpegDemuxerStream::FlushBuffers() {
105 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 117 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop());
106 base::AutoLock auto_lock(lock_); 118 base::AutoLock auto_lock(lock_);
107 DCHECK(read_queue_.empty()) << "Read requests should be empty"; 119 DCHECK(read_queue_.empty()) << "Read requests should be empty";
108 buffer_queue_.clear(); 120 buffer_queue_.clear();
121 last_packet_timestamp_ = base::TimeDelta();
scherkus (not reviewing) 2012/06/21 21:57:04 kNoTS() here + ctor initializer list?
109 } 122 }
110 123
111 void FFmpegDemuxerStream::Stop() { 124 void FFmpegDemuxerStream::Stop() {
112 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); 125 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop());
113 base::AutoLock auto_lock(lock_); 126 base::AutoLock auto_lock(lock_);
114 buffer_queue_.clear(); 127 buffer_queue_.clear();
115 for (ReadQueue::iterator it = read_queue_.begin(); 128 for (ReadQueue::iterator it = read_queue_.begin();
116 it != read_queue_.end(); ++it) { 129 it != read_queue_.end(); ++it) {
117 it->Run(scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer())); 130 it->Run(scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer()));
118 } 131 }
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 // Ensure the codec is supported. 513 // Ensure the codec is supported.
501 if (CodecIDToVideoCodec(codec_context->codec_id) == kUnknownVideoCodec) 514 if (CodecIDToVideoCodec(codec_context->codec_id) == kUnknownVideoCodec)
502 continue; 515 continue;
503 found_video_stream = true; 516 found_video_stream = true;
504 } else { 517 } else {
505 continue; 518 continue;
506 } 519 }
507 520
508 AVStream* stream = format_context_->streams[i]; 521 AVStream* stream = format_context_->streams[i];
509 scoped_refptr<FFmpegDemuxerStream> demuxer_stream( 522 scoped_refptr<FFmpegDemuxerStream> demuxer_stream(
510 new FFmpegDemuxerStream(this, stream)); 523 new FFmpegDemuxerStream(
524 base::Bind(&DemuxerHost::AddBufferedTimeRange,
525 base::Unretained(host_)),
526 this, stream));
511 527
512 streams_[i] = demuxer_stream; 528 streams_[i] = demuxer_stream;
513 max_duration = std::max(max_duration, demuxer_stream->duration()); 529 max_duration = std::max(max_duration, demuxer_stream->duration());
514 530
515 if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) { 531 if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) {
516 const base::TimeDelta first_dts = ConvertFromTimeBase( 532 const base::TimeDelta first_dts = ConvertFromTimeBase(
517 stream->time_base, stream->first_dts); 533 stream->time_base, stream->first_dts);
518 if (start_time_ == kNoTimestamp() || first_dts < start_time_) 534 if (start_time_ == kNoTimestamp() || first_dts < start_time_)
519 start_time_ = first_dts; 535 start_time_ = first_dts;
520 } 536 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 DCHECK_GE(packet->stream_index, 0); 647 DCHECK_GE(packet->stream_index, 0);
632 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size())); 648 DCHECK_LT(packet->stream_index, static_cast<int>(streams_.size()));
633 649
634 // Defend against ffmpeg giving us a bad stream index. 650 // Defend against ffmpeg giving us a bad stream index.
635 if (packet->stream_index >= 0 && 651 if (packet->stream_index >= 0 &&
636 packet->stream_index < static_cast<int>(streams_.size()) && 652 packet->stream_index < static_cast<int>(streams_.size()) &&
637 streams_[packet->stream_index] && 653 streams_[packet->stream_index] &&
638 (!audio_disabled_ || 654 (!audio_disabled_ ||
639 streams_[packet->stream_index]->type() != DemuxerStream::AUDIO)) { 655 streams_[packet->stream_index]->type() != DemuxerStream::AUDIO)) {
640 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index]; 656 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index];
657
641 demuxer_stream->EnqueuePacket(packet.Pass()); 658 demuxer_stream->EnqueuePacket(packet.Pass());
642 } 659 }
643 660
644 // Create a loop by posting another task. This allows seek and message loop 661 // Create a loop by posting another task. This allows seek and message loop
645 // quit tasks to get processed. 662 // quit tasks to get processed.
646 if (StreamsHavePendingReads()) { 663 if (StreamsHavePendingReads()) {
647 PostDemuxTask(); 664 PostDemuxTask();
648 } 665 }
649 } 666 }
650 667
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 read_event_.Wait(); 718 read_event_.Wait();
702 return last_read_bytes_; 719 return last_read_bytes_;
703 } 720 }
704 721
705 void FFmpegDemuxer::SignalReadCompleted(int size) { 722 void FFmpegDemuxer::SignalReadCompleted(int size) {
706 last_read_bytes_ = size; 723 last_read_bytes_ = size;
707 read_event_.Signal(); 724 read_event_.Signal();
708 } 725 }
709 726
710 } // namespace media 727 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698