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

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

Issue 547223003: MSE: Notify Blink SourceBuffer on init segment received (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | no next file » | 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/chunk_demuxer.h" 5 #include "media/filters/chunk_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <list> 9 #include <list>
10 10
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 bool allow_audio, 104 bool allow_audio,
105 bool allow_video, 105 bool allow_video,
106 const StreamParser::NeedKeyCB& need_key_cb, 106 const StreamParser::NeedKeyCB& need_key_cb,
107 const NewTextTrackCB& new_text_track_cb); 107 const NewTextTrackCB& new_text_track_cb);
108 108
109 // Appends new data to the StreamParser. 109 // Appends new data to the StreamParser.
110 // Returns true if the data was successfully appended. Returns false if an 110 // Returns true if the data was successfully appended. Returns false if an
111 // error occurred. |*timestamp_offset| is used and possibly updated by the 111 // error occurred. |*timestamp_offset| is used and possibly updated by the
112 // append. |append_window_start| and |append_window_end| correspond to the MSE 112 // append. |append_window_start| and |append_window_end| correspond to the MSE
113 // spec's similarly named source buffer attributes that are used in coded 113 // spec's similarly named source buffer attributes that are used in coded
114 // frame processing. 114 // frame processing. |init_segment_received_cb| is run for each new fully
115 bool Append(const uint8* data, size_t length, 115 // parsed initialization segment.
116 TimeDelta append_window_start, 116 bool Append(
117 TimeDelta append_window_end, 117 const uint8* data,
118 TimeDelta* timestamp_offset); 118 size_t length,
119 TimeDelta append_window_start,
120 TimeDelta append_window_end,
121 TimeDelta* timestamp_offset,
122 const ChunkDemuxer::InitSegmentReceivedCB& init_segment_received_cb);
acolwell GONE FROM CHROMIUM 2014/09/09 22:36:37 nit: typedef this above so you don't have to menti
wolenetz 2014/09/10 00:43:46 Done.
119 123
120 // Aborts the current append sequence and resets the parser. 124 // Aborts the current append sequence and resets the parser.
121 void Abort(TimeDelta append_window_start, 125 void Abort(TimeDelta append_window_start,
122 TimeDelta append_window_end, 126 TimeDelta append_window_end,
123 TimeDelta* timestamp_offset); 127 TimeDelta* timestamp_offset);
124 128
125 // Calls Remove(|start|, |end|, |duration|) on all 129 // Calls Remove(|start|, |end|, |duration|) on all
126 // ChunkDemuxerStreams managed by this object. 130 // ChunkDemuxerStreams managed by this object.
127 void Remove(TimeDelta start, TimeDelta end, TimeDelta duration); 131 void Remove(TimeDelta start, TimeDelta end, TimeDelta duration);
128 132
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 196
193 CreateDemuxerStreamCB create_demuxer_stream_cb_; 197 CreateDemuxerStreamCB create_demuxer_stream_cb_;
194 NewTextTrackCB new_text_track_cb_; 198 NewTextTrackCB new_text_track_cb_;
195 199
196 // During Append(), if OnNewBuffers() coded frame processing updates the 200 // During Append(), if OnNewBuffers() coded frame processing updates the
197 // timestamp offset then |*timestamp_offset_during_append_| is also updated 201 // timestamp offset then |*timestamp_offset_during_append_| is also updated
198 // so Append()'s caller can know the new offset. This pointer is only non-NULL 202 // so Append()'s caller can know the new offset. This pointer is only non-NULL
199 // during the lifetime of an Append() call. 203 // during the lifetime of an Append() call.
200 TimeDelta* timestamp_offset_during_append_; 204 TimeDelta* timestamp_offset_during_append_;
201 205
206 // During Append(), OnNewConfigs() will trigger the initialization segment
207 // received algorithm. This callback is only non-NULL during the lifetime of
208 // an Append() call. Note, the MSE spec explicitly disallows this algorithm
209 // during an Abort(), since Abort() is allowed only to emit coded frames, and
210 // only if the parser is PARSING_MEDIA_SEGMENT (not an INIT segment).
211 ChunkDemuxer::InitSegmentReceivedCB init_segment_received_cb_during_append_;
212
202 // During Append(), coded frame processing triggered by OnNewBuffers() 213 // During Append(), coded frame processing triggered by OnNewBuffers()
203 // requires these two attributes. These are only valid during the lifetime of 214 // requires these two attributes. These are only valid during the lifetime of
204 // an Append() call. 215 // an Append() call.
205 TimeDelta append_window_start_during_append_; 216 TimeDelta append_window_start_during_append_;
206 TimeDelta append_window_end_during_append_; 217 TimeDelta append_window_end_during_append_;
207 218
208 // Set to true if the next buffers appended within the append window 219 // Set to true if the next buffers appended within the append window
209 // represent the start of a new media segment. This flag being set 220 // represent the start of a new media segment. This flag being set
210 // triggers a call to |new_segment_cb_| when the new buffers are 221 // triggers a call to |new_segment_cb_| when the new buffers are
211 // appended. The flag is set on actual media segment boundaries and 222 // appended. The flag is set on actual media segment boundaries and
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 frame_processor_->SetSequenceMode(sequence_mode); 303 frame_processor_->SetSequenceMode(sequence_mode);
293 } 304 }
294 305
295 void SourceState::SetGroupStartTimestampIfInSequenceMode( 306 void SourceState::SetGroupStartTimestampIfInSequenceMode(
296 base::TimeDelta timestamp_offset) { 307 base::TimeDelta timestamp_offset) {
297 DCHECK(!parsing_media_segment_); 308 DCHECK(!parsing_media_segment_);
298 309
299 frame_processor_->SetGroupStartTimestampIfInSequenceMode(timestamp_offset); 310 frame_processor_->SetGroupStartTimestampIfInSequenceMode(timestamp_offset);
300 } 311 }
301 312
302 bool SourceState::Append(const uint8* data, size_t length, 313 bool SourceState::Append(
303 TimeDelta append_window_start, 314 const uint8* data,
304 TimeDelta append_window_end, 315 size_t length,
305 TimeDelta* timestamp_offset) { 316 TimeDelta append_window_start,
317 TimeDelta append_window_end,
318 TimeDelta* timestamp_offset,
319 const ChunkDemuxer::InitSegmentReceivedCB& init_segment_received_cb) {
306 DCHECK(timestamp_offset); 320 DCHECK(timestamp_offset);
307 DCHECK(!timestamp_offset_during_append_); 321 DCHECK(!timestamp_offset_during_append_);
322 DCHECK(init_segment_received_cb_during_append_.is_null());
323 DCHECK(!init_segment_received_cb.is_null());
308 append_window_start_during_append_ = append_window_start; 324 append_window_start_during_append_ = append_window_start;
309 append_window_end_during_append_ = append_window_end; 325 append_window_end_during_append_ = append_window_end;
310 timestamp_offset_during_append_ = timestamp_offset; 326 timestamp_offset_during_append_ = timestamp_offset;
327 init_segment_received_cb_during_append_ = init_segment_received_cb;
311 328
312 // TODO(wolenetz/acolwell): Curry and pass a NewBuffersCB here bound with 329 // TODO(wolenetz/acolwell): Curry and pass a NewBuffersCB here bound with
313 // append window and timestamp offset pointer. See http://crbug.com/351454. 330 // append window and timestamp offset pointer. See http://crbug.com/351454.
314 bool err = stream_parser_->Parse(data, length); 331 bool err = stream_parser_->Parse(data, length);
315 timestamp_offset_during_append_ = NULL; 332 timestamp_offset_during_append_ = NULL;
333 init_segment_received_cb_during_append_.Reset();
316 return err; 334 return err;
317 } 335 }
318 336
319 void SourceState::Abort(TimeDelta append_window_start, 337 void SourceState::Abort(TimeDelta append_window_start,
320 TimeDelta append_window_end, 338 TimeDelta append_window_end,
321 base::TimeDelta* timestamp_offset) { 339 base::TimeDelta* timestamp_offset) {
322 DCHECK(timestamp_offset); 340 DCHECK(timestamp_offset);
323 DCHECK(!timestamp_offset_during_append_); 341 DCHECK(!timestamp_offset_during_append_);
324 timestamp_offset_during_append_ = timestamp_offset; 342 timestamp_offset_during_append_ = timestamp_offset;
325 append_window_start_during_append_ = append_window_start; 343 append_window_start_during_append_ = append_window_start;
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 << " does not match old one."; 676 << " does not match old one.";
659 break; 677 break;
660 } 678 }
661 } 679 }
662 } 680 }
663 } 681 }
664 682
665 frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint(); 683 frame_processor_->SetAllTrackBuffersNeedRandomAccessPoint();
666 684
667 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); 685 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed");
686 if (success) {
687 // BIG TODO: add parameters to init segment received algo...
688 init_segment_received_cb_during_append_.Run();
689 }
690
668 return success; 691 return success;
669 } 692 }
670 693
671 void SourceState::OnNewMediaSegment() { 694 void SourceState::OnNewMediaSegment() {
672 DVLOG(2) << "OnNewMediaSegment()"; 695 DVLOG(2) << "OnNewMediaSegment()";
673 parsing_media_segment_ = true; 696 parsing_media_segment_ = true;
674 new_media_segment_ = true; 697 new_media_segment_ = true;
675 } 698 }
676 699
677 void SourceState::OnEndOfMediaSegment() { 700 void SourceState::OnEndOfMediaSegment() {
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
1222 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { 1245 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const {
1223 base::AutoLock auto_lock(lock_); 1246 base::AutoLock auto_lock(lock_);
1224 DCHECK(!id.empty()); 1247 DCHECK(!id.empty());
1225 1248
1226 SourceStateMap::const_iterator itr = source_state_map_.find(id); 1249 SourceStateMap::const_iterator itr = source_state_map_.find(id);
1227 1250
1228 DCHECK(itr != source_state_map_.end()); 1251 DCHECK(itr != source_state_map_.end());
1229 return itr->second->GetBufferedRanges(duration_, state_ == ENDED); 1252 return itr->second->GetBufferedRanges(duration_, state_ == ENDED);
1230 } 1253 }
1231 1254
1232 void ChunkDemuxer::AppendData(const std::string& id, 1255 void ChunkDemuxer::AppendData(
1233 const uint8* data, size_t length, 1256 const std::string& id,
1234 TimeDelta append_window_start, 1257 const uint8* data,
1235 TimeDelta append_window_end, 1258 size_t length,
1236 TimeDelta* timestamp_offset) { 1259 TimeDelta append_window_start,
1260 TimeDelta append_window_end,
1261 TimeDelta* timestamp_offset,
1262 const InitSegmentReceivedCB& init_segment_received_cb) {
1237 DVLOG(1) << "AppendData(" << id << ", " << length << ")"; 1263 DVLOG(1) << "AppendData(" << id << ", " << length << ")";
1238 1264
1239 DCHECK(!id.empty()); 1265 DCHECK(!id.empty());
1240 DCHECK(timestamp_offset); 1266 DCHECK(timestamp_offset);
1267 DCHECK(!init_segment_received_cb.is_null());
1241 1268
1242 Ranges<TimeDelta> ranges; 1269 Ranges<TimeDelta> ranges;
1243 1270
1244 { 1271 {
1245 base::AutoLock auto_lock(lock_); 1272 base::AutoLock auto_lock(lock_);
1246 DCHECK_NE(state_, ENDED); 1273 DCHECK_NE(state_, ENDED);
1247 1274
1248 // Capture if any of the SourceBuffers are waiting for data before we start 1275 // Capture if any of the SourceBuffers are waiting for data before we start
1249 // parsing. 1276 // parsing.
1250 bool old_waiting_for_data = IsSeekWaitingForData_Locked(); 1277 bool old_waiting_for_data = IsSeekWaitingForData_Locked();
1251 1278
1252 if (length == 0u) 1279 if (length == 0u)
1253 return; 1280 return;
1254 1281
1255 DCHECK(data); 1282 DCHECK(data);
1256 1283
1257 switch (state_) { 1284 switch (state_) {
1258 case INITIALIZING: 1285 case INITIALIZING:
1259 DCHECK(IsValidId(id)); 1286 DCHECK(IsValidId(id));
1260 if (!source_state_map_[id]->Append(data, length, 1287 if (!source_state_map_[id]->Append(data, length,
1261 append_window_start, 1288 append_window_start,
1262 append_window_end, 1289 append_window_end,
1263 timestamp_offset)) { 1290 timestamp_offset,
1291 init_segment_received_cb)) {
1264 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); 1292 ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
1265 return; 1293 return;
1266 } 1294 }
1267 break; 1295 break;
1268 1296
1269 case INITIALIZED: { 1297 case INITIALIZED: {
1270 DCHECK(IsValidId(id)); 1298 DCHECK(IsValidId(id));
1271 if (!source_state_map_[id]->Append(data, length, 1299 if (!source_state_map_[id]->Append(data, length,
1272 append_window_start, 1300 append_window_start,
1273 append_window_end, 1301 append_window_end,
1274 timestamp_offset)) { 1302 timestamp_offset,
1303 init_segment_received_cb)) {
1275 ReportError_Locked(PIPELINE_ERROR_DECODE); 1304 ReportError_Locked(PIPELINE_ERROR_DECODE);
1276 return; 1305 return;
1277 } 1306 }
1278 } break; 1307 } break;
1279 1308
1280 case PARSE_ERROR: 1309 case PARSE_ERROR:
1281 DVLOG(1) << "AppendData(): Ignoring data after a parse error."; 1310 DVLOG(1) << "AppendData(): Ignoring data after a parse error.";
1282 return; 1311 return;
1283 1312
1284 case WAITING_FOR_INIT: 1313 case WAITING_FOR_INIT:
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 } 1781 }
1753 1782
1754 void ChunkDemuxer::ShutdownAllStreams() { 1783 void ChunkDemuxer::ShutdownAllStreams() {
1755 for (SourceStateMap::iterator itr = source_state_map_.begin(); 1784 for (SourceStateMap::iterator itr = source_state_map_.begin();
1756 itr != source_state_map_.end(); ++itr) { 1785 itr != source_state_map_.end(); ++itr) {
1757 itr->second->Shutdown(); 1786 itr->second->Shutdown();
1758 } 1787 }
1759 } 1788 }
1760 1789
1761 } // namespace media 1790 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698