| 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 #ifndef MEDIA_FILTERS_FRAME_PROCESSOR_H_ | 5 #ifndef MEDIA_FILTERS_FRAME_PROCESSOR_H_ |
| 6 #define MEDIA_FILTERS_FRAME_PROCESSOR_H_ | 6 #define MEDIA_FILTERS_FRAME_PROCESSOR_H_ |
| 7 | 7 |
| 8 #include <map> |
| 9 |
| 8 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 9 #include "base/callback_forward.h" | 11 #include "base/callback_forward.h" |
| 10 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 11 #include "media/base/media_export.h" | 13 #include "media/base/media_export.h" |
| 12 #include "media/base/stream_parser.h" | 14 #include "media/base/stream_parser.h" |
| 13 #include "media/filters/frame_processor_base.h" | 15 #include "media/filters/chunk_demuxer.h" |
| 14 | 16 |
| 15 namespace media { | 17 namespace media { |
| 16 | 18 |
| 19 class MseTrackBuffer; |
| 20 |
| 17 // Helper class that implements Media Source Extension's coded frame processing | 21 // Helper class that implements Media Source Extension's coded frame processing |
| 18 // algorithm. | 22 // algorithm. |
| 19 class MEDIA_EXPORT FrameProcessor : public FrameProcessorBase { | 23 class MEDIA_EXPORT FrameProcessor { |
| 20 public: | 24 public: |
| 21 typedef base::Callback<void(base::TimeDelta)> UpdateDurationCB; | 25 typedef base::Callback<void(base::TimeDelta)> UpdateDurationCB; |
| 26 |
| 27 // TODO(wolenetz/acolwell): Ensure that all TrackIds are coherent and unique |
| 28 // for each track buffer. For now, special track identifiers are used for each |
| 29 // of audio and video here, and text TrackIds are assumed to be non-negative. |
| 30 // See http://crbug.com/341581. |
| 31 enum { |
| 32 kAudioTrackId = -2, |
| 33 kVideoTrackId = -3 |
| 34 }; |
| 35 |
| 22 explicit FrameProcessor(const UpdateDurationCB& update_duration_cb); | 36 explicit FrameProcessor(const UpdateDurationCB& update_duration_cb); |
| 23 virtual ~FrameProcessor(); | 37 ~FrameProcessor(); |
| 24 | 38 |
| 25 // FrameProcessorBase implementation | 39 // Get/set the current append mode, which if true means "sequence" and if |
| 26 virtual void SetSequenceMode(bool sequence_mode) OVERRIDE; | 40 // false means "segments". |
| 27 virtual bool ProcessFrames(const StreamParser::BufferQueue& audio_buffers, | 41 // See http://www.w3.org/TR/media-source/#widl-SourceBuffer-mode. |
| 28 const StreamParser::BufferQueue& video_buffers, | 42 bool sequence_mode() { return sequence_mode_; } |
| 29 const StreamParser::TextBufferQueueMap& text_map, | 43 void SetSequenceMode(bool sequence_mode); |
| 30 base::TimeDelta append_window_start, | 44 |
| 31 base::TimeDelta append_window_end, | 45 // Processes buffers in |audio_buffers|, |video_buffers|, and |text_map|. |
| 32 bool* new_media_segment, | 46 // Returns true on success or false on failure which indicates decode error. |
| 33 base::TimeDelta* timestamp_offset) OVERRIDE; | 47 // |append_window_start| and |append_window_end| correspond to the MSE spec's |
| 48 // similarly named source buffer attributes that are used in coded frame |
| 49 // processing. |
| 50 // |*new_media_segment| tracks whether the next buffers processed within the |
| 51 // append window represent the start of a new media segment. This method may |
| 52 // both use and update this flag. |
| 53 // Uses |*timestamp_offset| according to the coded frame processing algorithm, |
| 54 // including updating it as required in 'sequence' mode frame processing. |
| 55 bool ProcessFrames(const StreamParser::BufferQueue& audio_buffers, |
| 56 const StreamParser::BufferQueue& video_buffers, |
| 57 const StreamParser::TextBufferQueueMap& text_map, |
| 58 base::TimeDelta append_window_start, |
| 59 base::TimeDelta append_window_end, |
| 60 bool* new_media_segment, |
| 61 base::TimeDelta* timestamp_offset); |
| 62 |
| 63 // Signals the frame processor to update its group start timestamp to be |
| 64 // |timestamp_offset| if it is in sequence append mode. |
| 65 void SetGroupStartTimestampIfInSequenceMode(base::TimeDelta timestamp_offset); |
| 66 |
| 67 // Adds a new track with unique track ID |id|. |
| 68 // If |id| has previously been added, returns false to indicate error. |
| 69 // Otherwise, returns true, indicating future ProcessFrames() will emit |
| 70 // frames for the track |id| to |stream|. |
| 71 bool AddTrack(StreamParser::TrackId id, ChunkDemuxerStream* stream); |
| 72 |
| 73 // Updates the internal mapping of TrackId to track buffer for the track |
| 74 // buffer formerly associated with |old_id| to be associated with |new_id|. |
| 75 // Returns false to indicate failure due to either no existing track buffer |
| 76 // for |old_id| or collision with previous track buffer already mapped to |
| 77 // |new_id|. Otherwise returns true. |
| 78 bool UpdateTrack(StreamParser::TrackId old_id, StreamParser::TrackId new_id); |
| 79 |
| 80 // Sets the need random access point flag on all track buffers to true. |
| 81 void SetAllTrackBuffersNeedRandomAccessPoint(); |
| 82 |
| 83 // Resets state for the coded frame processing algorithm as described in steps |
| 84 // 2-5 of the MSE Reset Parser State algorithm described at |
| 85 // http://www.w3.org/TR/media-source/#sourcebuffer-reset-parser-state |
| 86 void Reset(); |
| 87 |
| 88 // Must be called when the audio config is updated. Used to manage when |
| 89 // the preroll buffer is cleared and the allowed "fudge" factor between |
| 90 // preroll buffers. |
| 91 void OnPossibleAudioConfigUpdate(const AudioDecoderConfig& config); |
| 34 | 92 |
| 35 private: | 93 private: |
| 94 typedef std::map<StreamParser::TrackId, MseTrackBuffer*> TrackBufferMap; |
| 95 |
| 96 // If |track_buffers_| contains |id|, returns a pointer to the associated |
| 97 // MseTrackBuffer. Otherwise, returns NULL. |
| 98 MseTrackBuffer* FindTrack(StreamParser::TrackId id); |
| 99 |
| 100 // Signals all track buffers' streams that a new media segment is starting |
| 101 // with timestamp |segment_timestamp|. |
| 102 void NotifyNewMediaSegmentStarting(base::TimeDelta segment_timestamp); |
| 103 |
| 104 // Handles partial append window trimming of |buffer|. Returns true if the |
| 105 // given |buffer| can be partially trimmed or have preroll added; otherwise, |
| 106 // returns false. |
| 107 // |
| 108 // If |buffer| overlaps |append_window_start|, the portion of |buffer| before |
| 109 // |append_window_start| will be marked for post-decode discard. Further, if |
| 110 // |audio_preroll_buffer_| exists and abuts |buffer|, it will be set as |
| 111 // preroll on |buffer| and |audio_preroll_buffer_| will be cleared. If the |
| 112 // preroll buffer does not abut |buffer|, it will be discarded, but not used. |
| 113 // |
| 114 // If |buffer| lies entirely before |append_window_start|, and thus would |
| 115 // normally be discarded, |audio_preroll_buffer_| will be set to |buffer| and |
| 116 // the method will return false. |
| 117 bool HandlePartialAppendWindowTrimming( |
| 118 base::TimeDelta append_window_start, |
| 119 base::TimeDelta append_window_end, |
| 120 const scoped_refptr<StreamParserBuffer>& buffer); |
| 121 |
| 36 // Helper that processes one frame with the coded frame processing algorithm. | 122 // Helper that processes one frame with the coded frame processing algorithm. |
| 37 // Returns false on error or true on success. | 123 // Returns false on error or true on success. |
| 38 bool ProcessFrame(const scoped_refptr<StreamParserBuffer>& frame, | 124 bool ProcessFrame(const scoped_refptr<StreamParserBuffer>& frame, |
| 39 base::TimeDelta append_window_start, | 125 base::TimeDelta append_window_start, |
| 40 base::TimeDelta append_window_end, | 126 base::TimeDelta append_window_end, |
| 41 base::TimeDelta* timestamp_offset, | 127 base::TimeDelta* timestamp_offset, |
| 42 bool* new_media_segment); | 128 bool* new_media_segment); |
| 43 | 129 |
| 130 // TrackId-indexed map of each track's stream. |
| 131 TrackBufferMap track_buffers_; |
| 132 |
| 133 // The last audio buffer seen by the frame processor that was removed because |
| 134 // it was entirely before the start of the append window. |
| 135 scoped_refptr<StreamParserBuffer> audio_preroll_buffer_; |
| 136 |
| 137 // The AudioDecoderConfig associated with buffers handed to ProcessFrames(). |
| 138 AudioDecoderConfig current_audio_config_; |
| 139 base::TimeDelta sample_duration_; |
| 140 |
| 141 // The AppendMode of the associated SourceBuffer. |
| 142 // See SetSequenceMode() for interpretation of |sequence_mode_|. |
| 143 // Per http://www.w3.org/TR/media-source/#widl-SourceBuffer-mode: |
| 144 // Controls how a sequence of media segments are handled. This is initially |
| 145 // set to false ("segments"). |
| 146 bool sequence_mode_; |
| 147 |
| 148 // Tracks the MSE coded frame processing variable of same name. |
| 149 // Initially kNoTimestamp(), meaning "unset". |
| 150 base::TimeDelta group_start_timestamp_; |
| 151 |
| 44 // Tracks the MSE coded frame processing variable of same name. It stores the | 152 // Tracks the MSE coded frame processing variable of same name. It stores the |
| 45 // highest coded frame end timestamp across all coded frames in the current | 153 // highest coded frame end timestamp across all coded frames in the current |
| 46 // coded frame group. It is set to 0 when the SourceBuffer object is created | 154 // coded frame group. It is set to 0 when the SourceBuffer object is created |
| 47 // and gets updated by ProcessFrames(). | 155 // and gets updated by ProcessFrames(). |
| 48 base::TimeDelta group_end_timestamp_; | 156 base::TimeDelta group_end_timestamp_; |
| 49 | 157 |
| 50 UpdateDurationCB update_duration_cb_; | 158 UpdateDurationCB update_duration_cb_; |
| 51 | 159 |
| 52 DISALLOW_COPY_AND_ASSIGN(FrameProcessor); | 160 DISALLOW_COPY_AND_ASSIGN(FrameProcessor); |
| 53 }; | 161 }; |
| 54 | 162 |
| 55 } // namespace media | 163 } // namespace media |
| 56 | 164 |
| 57 #endif // MEDIA_FILTERS_FRAME_PROCESSOR_H_ | 165 #endif // MEDIA_FILTERS_FRAME_PROCESSOR_H_ |
| OLD | NEW |