Chromium Code Reviews| 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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 void FrameProcessor::SetSequenceMode(bool sequence_mode) { | 178 void FrameProcessor::SetSequenceMode(bool sequence_mode) { |
| 179 DVLOG(2) << __FUNCTION__ << "(" << sequence_mode << ")"; | 179 DVLOG(2) << __FUNCTION__ << "(" << sequence_mode << ")"; |
| 180 | 180 |
| 181 // Per April 1, 2014 MSE spec editor's draft: | 181 // Per April 1, 2014 MSE spec editor's draft: |
| 182 // https://dvcs.w3.org/hg/html-media/raw-file/d471a4412040/media-source/media- source.html#widl-SourceBuffer-mode | 182 // https://dvcs.w3.org/hg/html-media/raw-file/d471a4412040/media-source/media- source.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_) { | |
| 189 // We're switching from 'sequence' to 'segments' mode. Be safe and signal a | |
| 190 // new coded frame group on the next frame emitted. | |
| 191 coded_frame_group_last_dts_ = kNoDecodeTimestamp(); | |
| 188 } | 192 } |
| 189 | 193 |
| 190 // Step 8: Update the attribute to new mode. | 194 // Step 8: Update the attribute to new mode. |
| 191 sequence_mode_ = sequence_mode; | 195 sequence_mode_ = sequence_mode; |
| 192 } | 196 } |
| 193 | 197 |
| 194 bool FrameProcessor::ProcessFrames( | 198 bool FrameProcessor::ProcessFrames( |
| 195 const StreamParser::BufferQueue& audio_buffers, | 199 const StreamParser::BufferQueue& audio_buffers, |
| 196 const StreamParser::BufferQueue& video_buffers, | 200 const StreamParser::BufferQueue& video_buffers, |
| 197 const StreamParser::TextBufferQueueMap& text_map, | 201 const StreamParser::TextBufferQueueMap& text_map, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 } | 287 } |
| 284 } | 288 } |
| 285 | 289 |
| 286 void FrameProcessor::Reset() { | 290 void FrameProcessor::Reset() { |
| 287 DVLOG(2) << __FUNCTION__ << "()"; | 291 DVLOG(2) << __FUNCTION__ << "()"; |
| 288 for (TrackBufferMap::iterator itr = track_buffers_.begin(); | 292 for (TrackBufferMap::iterator itr = track_buffers_.begin(); |
| 289 itr != track_buffers_.end(); ++itr) { | 293 itr != track_buffers_.end(); ++itr) { |
| 290 itr->second->Reset(); | 294 itr->second->Reset(); |
| 291 } | 295 } |
| 292 | 296 |
| 293 // Maintain current |in_coded_frame_group_| state for Reset() during | 297 // Maintain current |coded_frame_group_last_dts_| state for Reset() during |
| 294 // sequence mode. Reset it here only if in segments mode. | 298 // sequence mode. Reset it here only if in segments mode. |
|
chcunningham
2016/06/03 22:16:15
Can you say why? I know I've asked before, but I'v
wolenetz
2016/06/03 22:43:42
Done.
| |
| 295 if (!sequence_mode_) { | 299 if (!sequence_mode_) { |
| 296 in_coded_frame_group_ = false; | 300 coded_frame_group_last_dts_ = kNoDecodeTimestamp(); |
| 297 return; | 301 return; |
| 298 } | 302 } |
| 299 | 303 |
| 300 // Sequence mode | 304 // Sequence mode |
| 301 DCHECK(kNoTimestamp() != group_end_timestamp_); | 305 DCHECK(kNoTimestamp() != group_end_timestamp_); |
| 302 group_start_timestamp_ = group_end_timestamp_; | 306 group_start_timestamp_ = group_end_timestamp_; |
| 303 } | 307 } |
| 304 | 308 |
| 305 void FrameProcessor::OnPossibleAudioConfigUpdate( | 309 void FrameProcessor::OnPossibleAudioConfigUpdate( |
| 306 const AudioDecoderConfig& config) { | 310 const AudioDecoderConfig& config) { |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 // If last decode timestamp for track buffer is set and the difference | 595 // If last decode timestamp for track buffer is set and the difference |
| 592 // between decode timestamp and last decode timestamp is greater than 2 | 596 // between decode timestamp and last decode timestamp is greater than 2 |
| 593 // times last frame duration: | 597 // times last frame duration: |
| 594 DecodeTimestamp track_last_decode_timestamp = | 598 DecodeTimestamp track_last_decode_timestamp = |
| 595 track_buffer->last_decode_timestamp(); | 599 track_buffer->last_decode_timestamp(); |
| 596 if (track_last_decode_timestamp != kNoDecodeTimestamp()) { | 600 if (track_last_decode_timestamp != kNoDecodeTimestamp()) { |
| 597 base::TimeDelta track_dts_delta = | 601 base::TimeDelta track_dts_delta = |
| 598 decode_timestamp - track_last_decode_timestamp; | 602 decode_timestamp - track_last_decode_timestamp; |
| 599 if (track_dts_delta < base::TimeDelta() || | 603 if (track_dts_delta < base::TimeDelta() || |
| 600 track_dts_delta > 2 * track_buffer->last_frame_duration()) { | 604 track_dts_delta > 2 * track_buffer->last_frame_duration()) { |
| 601 DCHECK(in_coded_frame_group_); | 605 DCHECK(coded_frame_group_last_dts_ != kNoDecodeTimestamp()); |
| 602 // 7.1. If mode equals "segments": Set group end timestamp to | 606 // 7.1. If mode equals "segments": Set group end timestamp to |
| 603 // presentation timestamp. | 607 // presentation timestamp. |
| 604 // If mode equals "sequence": Set group start timestamp equal to | 608 // If mode equals "sequence": Set group start timestamp equal to |
| 605 // the group end timestamp. | 609 // the group end timestamp. |
| 606 if (!sequence_mode_) { | 610 if (!sequence_mode_) { |
| 607 group_end_timestamp_ = presentation_timestamp; | 611 group_end_timestamp_ = presentation_timestamp; |
| 608 // This triggers a discontinuity so we need to treat the next frames | 612 // This triggers a discontinuity so we need to treat the next frames |
| 609 // appended within the append window as if they were the beginning of | 613 // appended within the append window as if they were the beginning of |
| 610 // a new coded frame group. | 614 // a new coded frame group. |coded_frame_group_last_dts_| is reset in |
| 611 in_coded_frame_group_ = false; | 615 // Reset(), below, for "segments" mode. |
| 612 } else { | 616 } else { |
| 613 DVLOG(3) << __FUNCTION__ << " : Sequence mode discontinuity, GETS: " | 617 DVLOG(3) << __FUNCTION__ << " : Sequence mode discontinuity, GETS: " |
| 614 << group_end_timestamp_.InSecondsF(); | 618 << group_end_timestamp_.InSecondsF(); |
| 615 DCHECK(kNoTimestamp() != group_end_timestamp_); | 619 // Reset(), below, performs the "Set group start timestamp equal to |
| 616 group_start_timestamp_ = group_end_timestamp_; | 620 // the group end timestamp" operation for "sequence" mode. |
| 617 } | 621 } |
| 618 | 622 |
| 619 // 7.2. - 7.5.: | 623 // 7.2. - 7.5.: |
| 620 Reset(); | 624 Reset(); |
| 621 | 625 |
| 622 // 7.6. Jump to the Loop Top step above to restart processing of the | 626 // 7.6. Jump to the Loop Top step above to restart processing of the |
| 623 // current coded frame. | 627 // current coded frame. |
| 624 DVLOG(3) << __FUNCTION__ << ": Discontinuity: reprocessing frame"; | 628 DVLOG(3) << __FUNCTION__ << ": Discontinuity: reprocessing frame"; |
| 625 continue; | 629 continue; |
| 626 } | 630 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 } | 698 } |
| 695 | 699 |
| 696 // 12.2. Set the need random access point flag on track buffer to false. | 700 // 12.2. Set the need random access point flag on track buffer to false. |
| 697 track_buffer->set_needs_random_access_point(false); | 701 track_buffer->set_needs_random_access_point(false); |
| 698 } | 702 } |
| 699 | 703 |
| 700 // We now have a processed buffer to append to the track buffer's stream. | 704 // We now have a processed buffer to append to the track buffer's stream. |
| 701 // If it is the first in a new coded frame group (such as following a | 705 // If it is the first in a new coded frame group (such as following a |
| 702 // discontinuity), notify all the track buffers' streams that a coded frame | 706 // discontinuity), notify all the track buffers' streams that a coded frame |
| 703 // group is starting. | 707 // group is starting. |
| 704 if (!in_coded_frame_group_) { | 708 // If in 'sequence' appendMode, also check to make sure we don't need to |
| 709 // signal the start of a new coded frame group in the case where | |
| 710 // timestampOffset adjustments by the app may cause this coded frame to be | |
| 711 // in the timeline prior to the last frame processed. | |
| 712 if (coded_frame_group_last_dts_ == kNoDecodeTimestamp() || | |
| 713 (sequence_mode_ && coded_frame_group_last_dts_ > decode_timestamp)) { | |
| 705 // First, complete the append to track buffer streams of the previous | 714 // First, complete the append to track buffer streams of the previous |
| 706 // coded frame group's frames, if any. | 715 // coded frame group's frames, if any. |
| 707 if (!FlushProcessedFrames()) | 716 if (!FlushProcessedFrames()) |
| 708 return false; | 717 return false; |
| 709 | 718 |
| 710 // TODO(acolwell/wolenetz): This should be changed to a presentation | 719 // TODO(wolenetz): This should be changed to a presentation timestamp. See |
| 711 // timestamp. See http://crbug.com/402502 | 720 // http://crbug.com/402502 |
| 712 NotifyStartOfCodedFrameGroup(decode_timestamp); | 721 NotifyStartOfCodedFrameGroup(decode_timestamp); |
| 713 in_coded_frame_group_ = true; | |
| 714 } | 722 } |
| 715 | 723 |
| 724 coded_frame_group_last_dts_ = decode_timestamp; | |
| 725 | |
| 716 DVLOG(3) << __FUNCTION__ << ": Sending processed frame to stream, " | 726 DVLOG(3) << __FUNCTION__ << ": Sending processed frame to stream, " |
| 717 << "PTS=" << presentation_timestamp.InSecondsF() | 727 << "PTS=" << presentation_timestamp.InSecondsF() |
| 718 << ", DTS=" << decode_timestamp.InSecondsF(); | 728 << ", DTS=" << decode_timestamp.InSecondsF(); |
| 719 | 729 |
| 720 // Steps 13-18: Note, we optimize by appending groups of contiguous | 730 // Steps 13-18: Note, we optimize by appending groups of contiguous |
| 721 // processed frames for each track buffer at end of ProcessFrames() or prior | 731 // processed frames for each track buffer at end of ProcessFrames() or prior |
| 722 // to NotifyStartOfCodedFrameGroup(). | 732 // to NotifyStartOfCodedFrameGroup(). |
| 723 track_buffer->EnqueueProcessedFrame(frame); | 733 track_buffer->EnqueueProcessedFrame(frame); |
| 724 | 734 |
| 725 // 19. Set last decode timestamp for track buffer to decode timestamp. | 735 // 19. Set last decode timestamp for track buffer to decode timestamp. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 742 DCHECK(group_end_timestamp_ >= base::TimeDelta()); | 752 DCHECK(group_end_timestamp_ >= base::TimeDelta()); |
| 743 | 753 |
| 744 return true; | 754 return true; |
| 745 } | 755 } |
| 746 | 756 |
| 747 NOTREACHED(); | 757 NOTREACHED(); |
| 748 return false; | 758 return false; |
| 749 } | 759 } |
| 750 | 760 |
| 751 } // namespace media | 761 } // namespace media |
| OLD | NEW |