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

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

Issue 10800041: Update media duration if data is appended after the previous duration (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . 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
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/chunk_demuxer.h" 5 #include "media/filters/chunk_demuxer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 } 516 }
517 517
518 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) 518 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client)
519 : state_(WAITING_FOR_INIT), 519 : state_(WAITING_FOR_INIT),
520 host_(NULL), 520 host_(NULL),
521 client_(client), 521 client_(client),
522 start_time_(kNoTimestamp()) { 522 start_time_(kNoTimestamp()) {
523 DCHECK(client); 523 DCHECK(client);
524 } 524 }
525 525
526 void ChunkDemuxer::Initialize(DemuxerHost* host, 526 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) {
527 const PipelineStatusCB& cb) {
528 DVLOG(1) << "Init()"; 527 DVLOG(1) << "Init()";
529 { 528 {
530 base::AutoLock auto_lock(lock_); 529 base::AutoLock auto_lock(lock_);
531 DCHECK_EQ(state_, WAITING_FOR_INIT); 530 DCHECK_EQ(state_, WAITING_FOR_INIT);
532 host_ = host; 531 host_ = host;
533 532
534 ChangeState_Locked(INITIALIZING); 533 ChangeState_Locked(INITIALIZING);
535 init_cb_ = cb; 534 init_cb_ = cb;
536 } 535 }
537 536
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 DVLOG(1) << "AppendData(): called in unexpected state " << state_; 780 DVLOG(1) << "AppendData(): called in unexpected state " << state_;
782 return false; 781 return false;
783 } 782 }
784 783
785 // Check to see if data was appended at the pending seek point. This 784 // Check to see if data was appended at the pending seek point. This
786 // indicates we have parsed enough data to complete the seek. 785 // indicates we have parsed enough data to complete the seek.
787 if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null()) { 786 if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null()) {
788 std::swap(cb, seek_cb_); 787 std::swap(cb, seek_cb_);
789 } 788 }
790 789
791 if (audio_ && !video_) { 790 ranges = GetBufferedRanges();
792 ranges = audio_->GetBufferedRanges();
793 } else if (!audio_ && video_) {
794 ranges = video_->GetBufferedRanges();
795 } else {
796 ranges = ComputeIntersection();
797 }
798 } 791 }
799 792
800 for (size_t i = 0; i < ranges.size(); ++i) 793 for (size_t i = 0; i < ranges.size(); ++i)
801 host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i)); 794 host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i));
802 795
803 if (!cb.is_null()) 796 if (!cb.is_null())
804 cb.Run(PIPELINE_OK); 797 cb.Run(PIPELINE_OK);
805 798
806 return true; 799 return true;
807 } 800 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 DVLOG(1) << "OnStreamParserInitDone(" << success << ", " 954 DVLOG(1) << "OnStreamParserInitDone(" << success << ", "
962 << duration.InSecondsF() << ")"; 955 << duration.InSecondsF() << ")";
963 lock_.AssertAcquired(); 956 lock_.AssertAcquired();
964 DCHECK_EQ(state_, INITIALIZING); 957 DCHECK_EQ(state_, INITIALIZING);
965 if (!success || (!audio_ && !video_)) { 958 if (!success || (!audio_ && !video_)) {
966 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 959 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
967 return; 960 return;
968 } 961 }
969 962
970 if (duration > duration_) 963 if (duration > duration_)
971 duration_ = duration; 964 UpdateDuration(duration);
972 965
973 // Wait until all streams have initialized. 966 // Wait until all streams have initialized.
974 if ((!source_id_audio_.empty() && !audio_) || 967 if ((!source_id_audio_.empty() && !audio_) ||
975 (!source_id_video_.empty() && !video_)) 968 (!source_id_video_.empty() && !video_))
976 return; 969 return;
977 970
978 host_->SetDuration(duration_);
979
980 ChangeState_Locked(WAITING_FOR_START_TIME); 971 ChangeState_Locked(WAITING_FOR_START_TIME);
981 } 972 }
982 973
983 bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video, 974 bool ChunkDemuxer::OnNewConfigs(bool has_audio, bool has_video,
984 const AudioDecoderConfig& audio_config, 975 const AudioDecoderConfig& audio_config,
985 const VideoDecoderConfig& video_config) { 976 const VideoDecoderConfig& video_config) {
986 DVLOG(1) << "OnNewConfigs(" << has_audio << ", " << has_video 977 DVLOG(1) << "OnNewConfigs(" << has_audio << ", " << has_video
987 << ", " << audio_config.IsValidConfig() 978 << ", " << audio_config.IsValidConfig()
988 << ", " << video_config.IsValidConfig() << ")"; 979 << ", " << video_config.IsValidConfig() << ")";
989 CHECK(audio_config.IsValidConfig() || video_config.IsValidConfig()); 980 CHECK(audio_config.IsValidConfig() || video_config.IsValidConfig());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 lock_.AssertAcquired(); 1019 lock_.AssertAcquired();
1029 DCHECK_NE(state_, SHUTDOWN); 1020 DCHECK_NE(state_, SHUTDOWN);
1030 1021
1031 if (!audio_) 1022 if (!audio_)
1032 return false; 1023 return false;
1033 1024
1034 CHECK(IsValidId(source_id_audio_)); 1025 CHECK(IsValidId(source_id_audio_));
1035 AdjustBufferTimestamps( 1026 AdjustBufferTimestamps(
1036 buffers, source_info_map_[source_id_audio_].timestamp_offset); 1027 buffers, source_info_map_[source_id_audio_].timestamp_offset);
1037 1028
1029 IncreaseDurationIfNecessary(buffers);
1030
1038 return audio_->Append(buffers); 1031 return audio_->Append(buffers);
1039 } 1032 }
1040 1033
1041 bool ChunkDemuxer::OnVideoBuffers(const StreamParser::BufferQueue& buffers) { 1034 bool ChunkDemuxer::OnVideoBuffers(const StreamParser::BufferQueue& buffers) {
1042 lock_.AssertAcquired(); 1035 lock_.AssertAcquired();
1043 DCHECK_NE(state_, SHUTDOWN); 1036 DCHECK_NE(state_, SHUTDOWN);
1044 1037
1045 if (!video_) 1038 if (!video_)
1046 return false; 1039 return false;
1047 1040
1048 CHECK(IsValidId(source_id_video_)); 1041 CHECK(IsValidId(source_id_video_));
1049 AdjustBufferTimestamps( 1042 AdjustBufferTimestamps(
1050 buffers, source_info_map_[source_id_video_].timestamp_offset); 1043 buffers, source_info_map_[source_id_video_].timestamp_offset);
1051 1044
1045 IncreaseDurationIfNecessary(buffers);
1046
1052 return video_->Append(buffers); 1047 return video_->Append(buffers);
1053 } 1048 }
1054 1049
1055 bool ChunkDemuxer::OnNeedKey(scoped_array<uint8> init_data, 1050 bool ChunkDemuxer::OnNeedKey(scoped_array<uint8> init_data,
1056 int init_data_size) { 1051 int init_data_size) {
1057 client_->DemuxerNeedKey(init_data.Pass(), init_data_size); 1052 client_->DemuxerNeedKey(init_data.Pass(), init_data_size);
1058 return true; 1053 return true;
1059 } 1054 }
1060 1055
1061 void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id, 1056 void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id,
(...skipping 24 matching lines...) Expand all
1086 1081
1087 if (audio_) { 1082 if (audio_) {
1088 audio_->SetStartTime(start_time_); 1083 audio_->SetStartTime(start_time_);
1089 audio_->Seek(start_time_); 1084 audio_->Seek(start_time_);
1090 } 1085 }
1091 if (video_) { 1086 if (video_) {
1092 video_->SetStartTime(start_time_); 1087 video_->SetStartTime(start_time_);
1093 video_->Seek(start_time_); 1088 video_->Seek(start_time_);
1094 } 1089 }
1095 1090
1091 if (start_time_ > duration_)
1092 UpdateDuration(start_time_);
acolwell GONE FROM CHROMIUM 2012/07/27 00:03:23 nit: Could this be up where start_time_ is initial
vrk (LEFT CHROMIUM) 2012/07/28 01:42:05 Done.
1093
1096 // The demuxer is now initialized after the |start_timestamp_| was set. 1094 // The demuxer is now initialized after the |start_timestamp_| was set.
1097 ChangeState_Locked(INITIALIZED); 1095 ChangeState_Locked(INITIALIZED);
1098 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 1096 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
1099 } 1097 }
1100 1098
1101 void ChunkDemuxer::OnEndOfMediaSegment(const std::string& source_id) { 1099 void ChunkDemuxer::OnEndOfMediaSegment(const std::string& source_id) {
1102 DVLOG(2) << "OnEndOfMediaSegment(" << source_id << ")"; 1100 DVLOG(2) << "OnEndOfMediaSegment(" << source_id << ")";
1103 CHECK(IsValidId(source_id)); 1101 CHECK(IsValidId(source_id));
1104 source_info_map_[source_id].can_update_offset = true; 1102 source_info_map_[source_id].can_update_offset = true;
1105 } 1103 }
(...skipping 10 matching lines...) Expand all
1116 (*itr)->GetDecodeTimestamp() + timestamp_offset); 1114 (*itr)->GetDecodeTimestamp() + timestamp_offset);
1117 (*itr)->SetTimestamp((*itr)->GetTimestamp() + timestamp_offset); 1115 (*itr)->SetTimestamp((*itr)->GetTimestamp() + timestamp_offset);
1118 } 1116 }
1119 } 1117 }
1120 1118
1121 bool ChunkDemuxer::IsValidId(const std::string& source_id) const { 1119 bool ChunkDemuxer::IsValidId(const std::string& source_id) const {
1122 return source_info_map_.count(source_id) > 0u && 1120 return source_info_map_.count(source_id) > 0u &&
1123 stream_parser_map_.count(source_id) > 0u; 1121 stream_parser_map_.count(source_id) > 0u;
1124 } 1122 }
1125 1123
1124 void ChunkDemuxer::UpdateDuration(base::TimeDelta new_duration) {
1125 duration_ = new_duration;
acolwell GONE FROM CHROMIUM 2012/07/27 00:03:23 DCHECK(duration_ != new_duration) to make sure cod
vrk (LEFT CHROMIUM) 2012/07/28 01:42:05 Done.
1126 host_->SetDuration(new_duration);
acolwell GONE FROM CHROMIUM 2012/07/27 00:03:23 Does this cause double duration notifications on m
vrk (LEFT CHROMIUM) 2012/07/28 01:42:05 Yes this happens!
1127 }
1128
1129 void ChunkDemuxer::IncreaseDurationIfNecessary(
1130 const StreamParser::BufferQueue& buffers) {
1131 DCHECK(!buffers.empty());
1132 if (buffers.back()->GetTimestamp() <= duration_)
1133 return;
1134
1135 Ranges<TimeDelta> ranges = GetBufferedRanges();
1136 base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
1137 DCHECK(last_timestamp_buffered > duration_);
acolwell GONE FROM CHROMIUM 2012/07/27 00:03:23 I don't think this is right. The buffers aren't ap
vrk (LEFT CHROMIUM) 2012/07/28 01:42:05 AHH you are right! I must have fiddled with this b
1138 UpdateDuration(last_timestamp_buffered);
1139 }
1140
1141 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const {
1142 lock_.AssertAcquired();
1143
1144 if (audio_ && !video_)
1145 return audio_->GetBufferedRanges();
1146 else if (!audio_ && video_)
1147 return video_->GetBufferedRanges();
1148
1149 return ComputeIntersection();
1150 }
1151
1126 } // namespace media 1152 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698