OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/frame_processor.h" | 5 #include "media/filters/frame_processor.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <cstdlib> | 9 #include <cstdlib> |
10 | 10 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 MseTrackBuffer::MseTrackBuffer(ChunkDemuxerStream* stream) | 116 MseTrackBuffer::MseTrackBuffer(ChunkDemuxerStream* stream) |
117 : last_decode_timestamp_(kNoDecodeTimestamp()), | 117 : last_decode_timestamp_(kNoDecodeTimestamp()), |
118 last_frame_duration_(kNoTimestamp), | 118 last_frame_duration_(kNoTimestamp), |
119 highest_presentation_timestamp_(kNoTimestamp), | 119 highest_presentation_timestamp_(kNoTimestamp), |
120 needs_random_access_point_(true), | 120 needs_random_access_point_(true), |
121 stream_(stream) { | 121 stream_(stream) { |
122 DCHECK(stream_); | 122 DCHECK(stream_); |
123 } | 123 } |
124 | 124 |
125 MseTrackBuffer::~MseTrackBuffer() { | 125 MseTrackBuffer::~MseTrackBuffer() { |
126 DVLOG(2) << __FUNCTION__ << "()"; | 126 DVLOG(2) << __func__ << "()"; |
127 } | 127 } |
128 | 128 |
129 void MseTrackBuffer::Reset() { | 129 void MseTrackBuffer::Reset() { |
130 DVLOG(2) << __FUNCTION__ << "()"; | 130 DVLOG(2) << __func__ << "()"; |
131 | 131 |
132 last_decode_timestamp_ = kNoDecodeTimestamp(); | 132 last_decode_timestamp_ = kNoDecodeTimestamp(); |
133 last_frame_duration_ = kNoTimestamp; | 133 last_frame_duration_ = kNoTimestamp; |
134 highest_presentation_timestamp_ = kNoTimestamp; | 134 highest_presentation_timestamp_ = kNoTimestamp; |
135 needs_random_access_point_ = true; | 135 needs_random_access_point_ = true; |
136 } | 136 } |
137 | 137 |
138 void MseTrackBuffer::SetHighestPresentationTimestampIfIncreased( | 138 void MseTrackBuffer::SetHighestPresentationTimestampIfIncreased( |
139 base::TimeDelta timestamp) { | 139 base::TimeDelta timestamp) { |
140 if (highest_presentation_timestamp_ == kNoTimestamp || | 140 if (highest_presentation_timestamp_ == kNoTimestamp || |
141 timestamp > highest_presentation_timestamp_) { | 141 timestamp > highest_presentation_timestamp_) { |
142 highest_presentation_timestamp_ = timestamp; | 142 highest_presentation_timestamp_ = timestamp; |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 void MseTrackBuffer::EnqueueProcessedFrame( | 146 void MseTrackBuffer::EnqueueProcessedFrame( |
147 const scoped_refptr<StreamParserBuffer>& frame) { | 147 const scoped_refptr<StreamParserBuffer>& frame) { |
148 processed_frames_.push_back(frame); | 148 processed_frames_.push_back(frame); |
149 } | 149 } |
150 | 150 |
151 bool MseTrackBuffer::FlushProcessedFrames() { | 151 bool MseTrackBuffer::FlushProcessedFrames() { |
152 if (processed_frames_.empty()) | 152 if (processed_frames_.empty()) |
153 return true; | 153 return true; |
154 | 154 |
155 bool result = stream_->Append(processed_frames_); | 155 bool result = stream_->Append(processed_frames_); |
156 processed_frames_.clear(); | 156 processed_frames_.clear(); |
157 | 157 |
158 DVLOG_IF(3, !result) << __FUNCTION__ | 158 DVLOG_IF(3, !result) << __func__ |
159 << "(): Failure appending processed frames to stream"; | 159 << "(): Failure appending processed frames to stream"; |
160 | 160 |
161 return result; | 161 return result; |
162 } | 162 } |
163 | 163 |
164 FrameProcessor::FrameProcessor(const UpdateDurationCB& update_duration_cb, | 164 FrameProcessor::FrameProcessor(const UpdateDurationCB& update_duration_cb, |
165 const scoped_refptr<MediaLog>& media_log) | 165 const scoped_refptr<MediaLog>& media_log) |
166 : group_start_timestamp_(kNoTimestamp), | 166 : group_start_timestamp_(kNoTimestamp), |
167 update_duration_cb_(update_duration_cb), | 167 update_duration_cb_(update_duration_cb), |
168 media_log_(media_log) { | 168 media_log_(media_log) { |
169 DVLOG(2) << __FUNCTION__ << "()"; | 169 DVLOG(2) << __func__ << "()"; |
170 DCHECK(!update_duration_cb.is_null()); | 170 DCHECK(!update_duration_cb.is_null()); |
171 } | 171 } |
172 | 172 |
173 FrameProcessor::~FrameProcessor() { | 173 FrameProcessor::~FrameProcessor() { |
174 DVLOG(2) << __FUNCTION__ << "()"; | 174 DVLOG(2) << __func__ << "()"; |
175 STLDeleteValues(&track_buffers_); | 175 STLDeleteValues(&track_buffers_); |
176 } | 176 } |
177 | 177 |
178 void FrameProcessor::SetSequenceMode(bool sequence_mode) { | 178 void FrameProcessor::SetSequenceMode(bool sequence_mode) { |
179 DVLOG(2) << __FUNCTION__ << "(" << sequence_mode << ")"; | 179 DVLOG(2) << __func__ << "(" << sequence_mode << ")"; |
180 // Per June 9, 2016 MSE spec editor's draft: | 180 // Per June 9, 2016 MSE spec editor's draft: |
181 // https://rawgit.com/w3c/media-source/d8f901f22/ | 181 // https://rawgit.com/w3c/media-source/d8f901f22/ |
182 // index.html#widl-SourceBuffer-mode | 182 // index.html#widl-SourceBuffer-mode |
183 // Step 7: If the new mode equals "sequence", then set the group start | 183 // Step 7: If the new mode equals "sequence", then set the group start |
184 // timestamp to the group end timestamp. | 184 // timestamp to the group end timestamp. |
185 if (sequence_mode) { | 185 if (sequence_mode) { |
186 DCHECK(kNoTimestamp != group_end_timestamp_); | 186 DCHECK(kNoTimestamp != group_end_timestamp_); |
187 group_start_timestamp_ = group_end_timestamp_; | 187 group_start_timestamp_ = group_end_timestamp_; |
188 } else if (sequence_mode_) { | 188 } else if (sequence_mode_) { |
189 // We're switching from 'sequence' to 'segments' mode. Be safe and signal a | 189 // We're switching from 'sequence' to 'segments' mode. Be safe and signal a |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 // 5. If the media segment contains data beyond the current duration, then run | 234 // 5. If the media segment contains data beyond the current duration, then run |
235 // the duration change algorithm with new duration set to the maximum of | 235 // the duration change algorithm with new duration set to the maximum of |
236 // the current duration and the group end timestamp. | 236 // the current duration and the group end timestamp. |
237 update_duration_cb_.Run(group_end_timestamp_); | 237 update_duration_cb_.Run(group_end_timestamp_); |
238 | 238 |
239 return true; | 239 return true; |
240 } | 240 } |
241 | 241 |
242 void FrameProcessor::SetGroupStartTimestampIfInSequenceMode( | 242 void FrameProcessor::SetGroupStartTimestampIfInSequenceMode( |
243 base::TimeDelta timestamp_offset) { | 243 base::TimeDelta timestamp_offset) { |
244 DVLOG(2) << __FUNCTION__ << "(" << timestamp_offset.InSecondsF() << ")"; | 244 DVLOG(2) << __func__ << "(" << timestamp_offset.InSecondsF() << ")"; |
245 DCHECK(kNoTimestamp != timestamp_offset); | 245 DCHECK(kNoTimestamp != timestamp_offset); |
246 if (sequence_mode_) | 246 if (sequence_mode_) |
247 group_start_timestamp_ = timestamp_offset; | 247 group_start_timestamp_ = timestamp_offset; |
248 | 248 |
249 // Changes to timestampOffset should invalidate the preroll buffer. | 249 // Changes to timestampOffset should invalidate the preroll buffer. |
250 audio_preroll_buffer_ = NULL; | 250 audio_preroll_buffer_ = NULL; |
251 } | 251 } |
252 | 252 |
253 bool FrameProcessor::AddTrack(StreamParser::TrackId id, | 253 bool FrameProcessor::AddTrack(StreamParser::TrackId id, |
254 ChunkDemuxerStream* stream) { | 254 ChunkDemuxerStream* stream) { |
255 DVLOG(2) << __FUNCTION__ << "(): id=" << id; | 255 DVLOG(2) << __func__ << "(): id=" << id; |
256 | 256 |
257 MseTrackBuffer* existing_track = FindTrack(id); | 257 MseTrackBuffer* existing_track = FindTrack(id); |
258 DCHECK(!existing_track); | 258 DCHECK(!existing_track); |
259 if (existing_track) { | 259 if (existing_track) { |
260 MEDIA_LOG(ERROR, media_log_) << "Failure adding track with duplicate ID " | 260 MEDIA_LOG(ERROR, media_log_) << "Failure adding track with duplicate ID " |
261 << id; | 261 << id; |
262 return false; | 262 return false; |
263 } | 263 } |
264 | 264 |
265 track_buffers_[id] = new MseTrackBuffer(stream); | 265 track_buffers_[id] = new MseTrackBuffer(stream); |
266 return true; | 266 return true; |
267 } | 267 } |
268 | 268 |
269 bool FrameProcessor::UpdateTrack(StreamParser::TrackId old_id, | 269 bool FrameProcessor::UpdateTrack(StreamParser::TrackId old_id, |
270 StreamParser::TrackId new_id) { | 270 StreamParser::TrackId new_id) { |
271 DVLOG(2) << __FUNCTION__ << "() : old_id=" << old_id << ", new_id=" << new_id; | 271 DVLOG(2) << __func__ << "() : old_id=" << old_id << ", new_id=" << new_id; |
272 | 272 |
273 if (old_id == new_id || !FindTrack(old_id) || FindTrack(new_id)) { | 273 if (old_id == new_id || !FindTrack(old_id) || FindTrack(new_id)) { |
274 MEDIA_LOG(ERROR, media_log_) << "Failure updating track id from " << old_id | 274 MEDIA_LOG(ERROR, media_log_) << "Failure updating track id from " << old_id |
275 << " to " << new_id; | 275 << " to " << new_id; |
276 return false; | 276 return false; |
277 } | 277 } |
278 | 278 |
279 track_buffers_[new_id] = track_buffers_[old_id]; | 279 track_buffers_[new_id] = track_buffers_[old_id]; |
280 CHECK_EQ(1u, track_buffers_.erase(old_id)); | 280 CHECK_EQ(1u, track_buffers_.erase(old_id)); |
281 return true; | 281 return true; |
282 } | 282 } |
283 | 283 |
284 void FrameProcessor::SetAllTrackBuffersNeedRandomAccessPoint() { | 284 void FrameProcessor::SetAllTrackBuffersNeedRandomAccessPoint() { |
285 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 285 for (TrackBufferMap::iterator itr = track_buffers_.begin(); |
286 itr != track_buffers_.end(); | 286 itr != track_buffers_.end(); |
287 ++itr) { | 287 ++itr) { |
288 itr->second->set_needs_random_access_point(true); | 288 itr->second->set_needs_random_access_point(true); |
289 } | 289 } |
290 } | 290 } |
291 | 291 |
292 void FrameProcessor::Reset() { | 292 void FrameProcessor::Reset() { |
293 DVLOG(2) << __FUNCTION__ << "()"; | 293 DVLOG(2) << __func__ << "()"; |
294 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 294 for (TrackBufferMap::iterator itr = track_buffers_.begin(); |
295 itr != track_buffers_.end(); ++itr) { | 295 itr != track_buffers_.end(); ++itr) { |
296 itr->second->Reset(); | 296 itr->second->Reset(); |
297 } | 297 } |
298 | 298 |
299 // Maintain current |coded_frame_group_last_dts_| state for Reset() during | 299 // Maintain current |coded_frame_group_last_dts_| state for Reset() during |
300 // sequence mode. Reset it here only if in segments mode. In sequence mode, | 300 // sequence mode. Reset it here only if in segments mode. In sequence mode, |
301 // the current coded frame group may be continued across Reset() operations to | 301 // the current coded frame group may be continued across Reset() operations to |
302 // allow the stream to coaelesce what might otherwise be gaps in the buffered | 302 // allow the stream to coaelesce what might otherwise be gaps in the buffered |
303 // ranges. See also the declaration for |coded_frame_group_last_dts_|. | 303 // ranges. See also the declaration for |coded_frame_group_last_dts_|. |
(...skipping 25 matching lines...) Expand all Loading... |
329 MseTrackBuffer* FrameProcessor::FindTrack(StreamParser::TrackId id) { | 329 MseTrackBuffer* FrameProcessor::FindTrack(StreamParser::TrackId id) { |
330 TrackBufferMap::iterator itr = track_buffers_.find(id); | 330 TrackBufferMap::iterator itr = track_buffers_.find(id); |
331 if (itr == track_buffers_.end()) | 331 if (itr == track_buffers_.end()) |
332 return NULL; | 332 return NULL; |
333 | 333 |
334 return itr->second; | 334 return itr->second; |
335 } | 335 } |
336 | 336 |
337 void FrameProcessor::NotifyStartOfCodedFrameGroup( | 337 void FrameProcessor::NotifyStartOfCodedFrameGroup( |
338 DecodeTimestamp start_timestamp) { | 338 DecodeTimestamp start_timestamp) { |
339 DVLOG(2) << __FUNCTION__ << "(" << start_timestamp.InSecondsF() << ")"; | 339 DVLOG(2) << __func__ << "(" << start_timestamp.InSecondsF() << ")"; |
340 | 340 |
341 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 341 for (TrackBufferMap::iterator itr = track_buffers_.begin(); |
342 itr != track_buffers_.end(); | 342 itr != track_buffers_.end(); |
343 ++itr) { | 343 ++itr) { |
344 itr->second->stream()->OnStartOfCodedFrameGroup(start_timestamp); | 344 itr->second->stream()->OnStartOfCodedFrameGroup(start_timestamp); |
345 } | 345 } |
346 } | 346 } |
347 | 347 |
348 bool FrameProcessor::FlushProcessedFrames() { | 348 bool FrameProcessor::FlushProcessedFrames() { |
349 DVLOG(2) << __FUNCTION__ << "()"; | 349 DVLOG(2) << __func__ << "()"; |
350 | 350 |
351 bool result = true; | 351 bool result = true; |
352 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 352 for (TrackBufferMap::iterator itr = track_buffers_.begin(); |
353 itr != track_buffers_.end(); | 353 itr != track_buffers_.end(); |
354 ++itr) { | 354 ++itr) { |
355 if (!itr->second->FlushProcessedFrames()) | 355 if (!itr->second->FlushProcessedFrames()) |
356 result = false; | 356 result = false; |
357 } | 357 } |
358 | 358 |
359 return result; | 359 return result; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 // seconds. | 476 // seconds. |
477 // 1.2. Let decode timestamp be a double precision floating point | 477 // 1.2. Let decode timestamp be a double precision floating point |
478 // representation of the coded frame's decode timestamp in seconds. | 478 // representation of the coded frame's decode timestamp in seconds. |
479 // 2. Let frame duration be a double precision floating point representation | 479 // 2. Let frame duration be a double precision floating point representation |
480 // of the coded frame's duration in seconds. | 480 // of the coded frame's duration in seconds. |
481 // We use base::TimeDelta and DecodeTimestamp instead of double. | 481 // We use base::TimeDelta and DecodeTimestamp instead of double. |
482 base::TimeDelta presentation_timestamp = frame->timestamp(); | 482 base::TimeDelta presentation_timestamp = frame->timestamp(); |
483 DecodeTimestamp decode_timestamp = frame->GetDecodeTimestamp(); | 483 DecodeTimestamp decode_timestamp = frame->GetDecodeTimestamp(); |
484 base::TimeDelta frame_duration = frame->duration(); | 484 base::TimeDelta frame_duration = frame->duration(); |
485 | 485 |
486 DVLOG(3) << __FUNCTION__ << ": Processing frame " | 486 DVLOG(3) << __func__ << ": Processing frame Type=" << frame->type() |
487 << "Type=" << frame->type() | |
488 << ", TrackID=" << frame->track_id() | 487 << ", TrackID=" << frame->track_id() |
489 << ", PTS=" << presentation_timestamp.InSecondsF() | 488 << ", PTS=" << presentation_timestamp.InSecondsF() |
490 << ", DTS=" << decode_timestamp.InSecondsF() | 489 << ", DTS=" << decode_timestamp.InSecondsF() |
491 << ", DUR=" << frame_duration.InSecondsF() | 490 << ", DUR=" << frame_duration.InSecondsF() |
492 << ", RAP=" << frame->is_key_frame(); | 491 << ", RAP=" << frame->is_key_frame(); |
493 | 492 |
494 // Sanity check the timestamps. | 493 // Sanity check the timestamps. |
495 if (presentation_timestamp == kNoTimestamp) { | 494 if (presentation_timestamp == kNoTimestamp) { |
496 MEDIA_LOG(ERROR, media_log_) << "Unknown PTS for " << frame->GetTypeName() | 495 MEDIA_LOG(ERROR, media_log_) << "Unknown PTS for " << frame->GetTypeName() |
497 << " frame"; | 496 << " frame"; |
498 return false; | 497 return false; |
499 } | 498 } |
500 if (decode_timestamp == kNoDecodeTimestamp()) { | 499 if (decode_timestamp == kNoDecodeTimestamp()) { |
501 MEDIA_LOG(ERROR, media_log_) << "Unknown DTS for " << frame->GetTypeName() | 500 MEDIA_LOG(ERROR, media_log_) << "Unknown DTS for " << frame->GetTypeName() |
502 << " frame"; | 501 << " frame"; |
503 return false; | 502 return false; |
504 } | 503 } |
505 if (decode_timestamp.ToPresentationTime() > presentation_timestamp) { | 504 if (decode_timestamp.ToPresentationTime() > presentation_timestamp) { |
506 // TODO(wolenetz): Determine whether DTS>PTS should really be allowed. See | 505 // TODO(wolenetz): Determine whether DTS>PTS should really be allowed. See |
507 // http://crbug.com/354518. | 506 // http://crbug.com/354518. |
508 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_dts_beyond_pts_warnings_, | 507 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_dts_beyond_pts_warnings_, |
509 kMaxDtsBeyondPtsWarnings) | 508 kMaxDtsBeyondPtsWarnings) |
510 << "Parsed " << frame->GetTypeName() << " frame has DTS " | 509 << "Parsed " << frame->GetTypeName() << " frame has DTS " |
511 << decode_timestamp.InMicroseconds() | 510 << decode_timestamp.InMicroseconds() |
512 << "us, which is after the frame's PTS " | 511 << "us, which is after the frame's PTS " |
513 << presentation_timestamp.InMicroseconds() << "us"; | 512 << presentation_timestamp.InMicroseconds() << "us"; |
514 DVLOG(2) << __FUNCTION__ << ": WARNING: Frame DTS(" | 513 DVLOG(2) << __func__ << ": WARNING: Frame DTS(" |
515 << decode_timestamp.InSecondsF() << ") > PTS(" | 514 << decode_timestamp.InSecondsF() << ") > PTS(" |
516 << presentation_timestamp.InSecondsF() | 515 << presentation_timestamp.InSecondsF() |
517 << "), frame type=" << frame->GetTypeName(); | 516 << "), frame type=" << frame->GetTypeName(); |
518 } | 517 } |
519 | 518 |
520 // All stream parsers must emit valid (non-negative) frame durations. | 519 // All stream parsers must emit valid (non-negative) frame durations. |
521 // Note that duration of 0 can occur for at least WebM alt-ref frames. | 520 // Note that duration of 0 can occur for at least WebM alt-ref frames. |
522 if (frame_duration == kNoTimestamp) { | 521 if (frame_duration == kNoTimestamp) { |
523 MEDIA_LOG(ERROR, media_log_) | 522 MEDIA_LOG(ERROR, media_log_) |
524 << "Unknown duration for " << frame->GetTypeName() << " frame at PTS " | 523 << "Unknown duration for " << frame->GetTypeName() << " frame at PTS " |
525 << presentation_timestamp.InMicroseconds() << "us"; | 524 << presentation_timestamp.InMicroseconds() << "us"; |
526 return false; | 525 return false; |
527 } | 526 } |
528 if (frame_duration < base::TimeDelta()) { | 527 if (frame_duration < base::TimeDelta()) { |
529 MEDIA_LOG(ERROR, media_log_) | 528 MEDIA_LOG(ERROR, media_log_) |
530 << "Negative duration " << frame_duration.InMicroseconds() | 529 << "Negative duration " << frame_duration.InMicroseconds() |
531 << "us for " << frame->GetTypeName() << " frame at PTS " | 530 << "us for " << frame->GetTypeName() << " frame at PTS " |
532 << presentation_timestamp.InMicroseconds() << "us"; | 531 << presentation_timestamp.InMicroseconds() << "us"; |
533 return false; | 532 return false; |
534 } | 533 } |
535 | 534 |
536 // 3. If mode equals "sequence" and group start timestamp is set, then run | 535 // 3. If mode equals "sequence" and group start timestamp is set, then run |
537 // the following steps: | 536 // the following steps: |
538 if (sequence_mode_ && group_start_timestamp_ != kNoTimestamp) { | 537 if (sequence_mode_ && group_start_timestamp_ != kNoTimestamp) { |
539 // 3.1. Set timestampOffset equal to group start timestamp - | 538 // 3.1. Set timestampOffset equal to group start timestamp - |
540 // presentation timestamp. | 539 // presentation timestamp. |
541 *timestamp_offset = group_start_timestamp_ - presentation_timestamp; | 540 *timestamp_offset = group_start_timestamp_ - presentation_timestamp; |
542 | 541 |
543 DVLOG(3) << __FUNCTION__ << ": updated timestampOffset is now " | 542 DVLOG(3) << __func__ << ": updated timestampOffset is now " |
544 << timestamp_offset->InSecondsF(); | 543 << timestamp_offset->InSecondsF(); |
545 | 544 |
546 // 3.2. Set group end timestamp equal to group start timestamp. | 545 // 3.2. Set group end timestamp equal to group start timestamp. |
547 group_end_timestamp_ = group_start_timestamp_; | 546 group_end_timestamp_ = group_start_timestamp_; |
548 | 547 |
549 // 3.3. Set the need random access point flag on all track buffers to | 548 // 3.3. Set the need random access point flag on all track buffers to |
550 // true. | 549 // true. |
551 SetAllTrackBuffersNeedRandomAccessPoint(); | 550 SetAllTrackBuffersNeedRandomAccessPoint(); |
552 | 551 |
553 // 3.4. Unset group start timestamp. | 552 // 3.4. Unset group start timestamp. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 // presentation timestamp. | 612 // presentation timestamp. |
614 // If mode equals "sequence": Set group start timestamp equal to | 613 // If mode equals "sequence": Set group start timestamp equal to |
615 // the group end timestamp. | 614 // the group end timestamp. |
616 if (!sequence_mode_) { | 615 if (!sequence_mode_) { |
617 group_end_timestamp_ = presentation_timestamp; | 616 group_end_timestamp_ = presentation_timestamp; |
618 // This triggers a discontinuity so we need to treat the next frames | 617 // This triggers a discontinuity so we need to treat the next frames |
619 // appended within the append window as if they were the beginning of | 618 // appended within the append window as if they were the beginning of |
620 // a new coded frame group. |coded_frame_group_last_dts_| is reset in | 619 // a new coded frame group. |coded_frame_group_last_dts_| is reset in |
621 // Reset(), below, for "segments" mode. | 620 // Reset(), below, for "segments" mode. |
622 } else { | 621 } else { |
623 DVLOG(3) << __FUNCTION__ << " : Sequence mode discontinuity, GETS: " | 622 DVLOG(3) << __func__ << " : Sequence mode discontinuity, GETS: " |
624 << group_end_timestamp_.InSecondsF(); | 623 << group_end_timestamp_.InSecondsF(); |
625 // Reset(), below, performs the "Set group start timestamp equal to | 624 // Reset(), below, performs the "Set group start timestamp equal to |
626 // the group end timestamp" operation for "sequence" mode. | 625 // the group end timestamp" operation for "sequence" mode. |
627 } | 626 } |
628 | 627 |
629 // 6.2. - 6.5.: | 628 // 6.2. - 6.5.: |
630 Reset(); | 629 Reset(); |
631 | 630 |
632 // 6.6. Jump to the Loop Top step above to restart processing of the | 631 // 6.6. Jump to the Loop Top step above to restart processing of the |
633 // current coded frame. | 632 // current coded frame. |
634 DVLOG(3) << __FUNCTION__ << ": Discontinuity: reprocessing frame"; | 633 DVLOG(3) << __func__ << ": Discontinuity: reprocessing frame"; |
635 continue; | 634 continue; |
636 } | 635 } |
637 } | 636 } |
638 | 637 |
639 // 7. Let frame end timestamp equal the sum of presentation timestamp and | 638 // 7. Let frame end timestamp equal the sum of presentation timestamp and |
640 // frame duration. | 639 // frame duration. |
641 base::TimeDelta frame_end_timestamp = | 640 base::TimeDelta frame_end_timestamp = |
642 presentation_timestamp + frame_duration; | 641 presentation_timestamp + frame_duration; |
643 | 642 |
644 // 8. If presentation timestamp is less than appendWindowStart, then set | 643 // 8. If presentation timestamp is less than appendWindowStart, then set |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 return false; | 690 return false; |
692 } | 691 } |
693 | 692 |
694 // 10. If the need random access point flag on track buffer equals true, | 693 // 10. If the need random access point flag on track buffer equals true, |
695 // then run the following steps: | 694 // then run the following steps: |
696 if (track_buffer->needs_random_access_point()) { | 695 if (track_buffer->needs_random_access_point()) { |
697 // 10.1. If the coded frame is not a random access point, then drop the | 696 // 10.1. If the coded frame is not a random access point, then drop the |
698 // coded frame and jump to the top of the loop to start processing | 697 // coded frame and jump to the top of the loop to start processing |
699 // the next coded frame. | 698 // the next coded frame. |
700 if (!frame->is_key_frame()) { | 699 if (!frame->is_key_frame()) { |
701 DVLOG(3) << __FUNCTION__ | 700 DVLOG(3) << __func__ |
702 << ": Dropping frame that is not a random access point"; | 701 << ": Dropping frame that is not a random access point"; |
703 return true; | 702 return true; |
704 } | 703 } |
705 | 704 |
706 // 10.2. Set the need random access point flag on track buffer to false. | 705 // 10.2. Set the need random access point flag on track buffer to false. |
707 track_buffer->set_needs_random_access_point(false); | 706 track_buffer->set_needs_random_access_point(false); |
708 } | 707 } |
709 | 708 |
710 // We now have a processed buffer to append to the track buffer's stream. | 709 // We now have a processed buffer to append to the track buffer's stream. |
711 // If it is the first in a new coded frame group (such as following a | 710 // If it is the first in a new coded frame group (such as following a |
(...skipping 10 matching lines...) Expand all Loading... |
722 if (!FlushProcessedFrames()) | 721 if (!FlushProcessedFrames()) |
723 return false; | 722 return false; |
724 | 723 |
725 // TODO(wolenetz): This should be changed to a presentation timestamp. See | 724 // TODO(wolenetz): This should be changed to a presentation timestamp. See |
726 // http://crbug.com/402502 | 725 // http://crbug.com/402502 |
727 NotifyStartOfCodedFrameGroup(decode_timestamp); | 726 NotifyStartOfCodedFrameGroup(decode_timestamp); |
728 } | 727 } |
729 | 728 |
730 coded_frame_group_last_dts_ = decode_timestamp; | 729 coded_frame_group_last_dts_ = decode_timestamp; |
731 | 730 |
732 DVLOG(3) << __FUNCTION__ << ": Sending processed frame to stream, " | 731 DVLOG(3) << __func__ << ": Sending processed frame to stream, " |
733 << "PTS=" << presentation_timestamp.InSecondsF() | 732 << "PTS=" << presentation_timestamp.InSecondsF() |
734 << ", DTS=" << decode_timestamp.InSecondsF(); | 733 << ", DTS=" << decode_timestamp.InSecondsF(); |
735 | 734 |
736 // Steps 11-16: Note, we optimize by appending groups of contiguous | 735 // Steps 11-16: Note, we optimize by appending groups of contiguous |
737 // processed frames for each track buffer at end of ProcessFrames() or prior | 736 // processed frames for each track buffer at end of ProcessFrames() or prior |
738 // to NotifyStartOfCodedFrameGroup(). | 737 // to NotifyStartOfCodedFrameGroup(). |
739 track_buffer->EnqueueProcessedFrame(frame); | 738 track_buffer->EnqueueProcessedFrame(frame); |
740 | 739 |
741 // 17. Set last decode timestamp for track buffer to decode timestamp. | 740 // 17. Set last decode timestamp for track buffer to decode timestamp. |
742 track_buffer->set_last_decode_timestamp(decode_timestamp); | 741 track_buffer->set_last_decode_timestamp(decode_timestamp); |
(...skipping 17 matching lines...) Expand all Loading... |
760 // Step 21 is currently handled differently. See MediaSourceState's | 759 // Step 21 is currently handled differently. See MediaSourceState's |
761 // |auto_update_timestamp_offset_|. | 760 // |auto_update_timestamp_offset_|. |
762 return true; | 761 return true; |
763 } | 762 } |
764 | 763 |
765 NOTREACHED(); | 764 NOTREACHED(); |
766 return false; | 765 return false; |
767 } | 766 } |
768 | 767 |
769 } // namespace media | 768 } // namespace media |
OLD | NEW |