10de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
20de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
30de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// found in the LICENSE file.
40de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
50de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#ifndef MEDIA_FILTERS_FRAME_PROCESSOR_H_
60de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#define MEDIA_FILTERS_FRAME_PROCESSOR_H_
70de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <map>
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
100de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "base/basictypes.h"
110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "base/callback_forward.h"
120de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "base/time/time.h"
130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "media/base/media_export.h"
140de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "media/base/stream_parser.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/filters/chunk_demuxer.h"
160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
170de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)namespace media {
180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MseTrackBuffer;
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Helper class that implements Media Source Extension's coded frame processing
220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// algorithm.
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MEDIA_EXPORT FrameProcessor {
240de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) public:
250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  typedef base::Callback<void(base::TimeDelta)> UpdateDurationCB;
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(wolenetz/acolwell): Ensure that all TrackIds are coherent and unique
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // for each track buffer. For now, special track identifiers are used for each
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // of audio and video here, and text TrackIds are assumed to be non-negative.
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // See http://crbug.com/341581.
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  enum {
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    kAudioTrackId = -2,
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    kVideoTrackId = -3
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  explicit FrameProcessor(const UpdateDurationCB& update_duration_cb);
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ~FrameProcessor();
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Get/set the current append mode, which if true means "sequence" and if
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // false means "segments".
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // See http://www.w3.org/TR/media-source/#widl-SourceBuffer-mode.
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool sequence_mode() { return sequence_mode_; }
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void SetSequenceMode(bool sequence_mode);
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Processes buffers in |audio_buffers|, |video_buffers|, and |text_map|.
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns true on success or false on failure which indicates decode error.
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |append_window_start| and |append_window_end| correspond to the MSE spec's
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // similarly named source buffer attributes that are used in coded frame
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // processing.
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |*new_media_segment| tracks whether the next buffers processed within the
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // append window represent the start of a new media segment. This method may
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // both use and update this flag.
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Uses |*timestamp_offset| according to the coded frame processing algorithm,
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // including updating it as required in 'sequence' mode frame processing.
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool ProcessFrames(const StreamParser::BufferQueue& audio_buffers,
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     const StreamParser::BufferQueue& video_buffers,
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     const StreamParser::TextBufferQueueMap& text_map,
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     base::TimeDelta append_window_start,
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     base::TimeDelta append_window_end,
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     bool* new_media_segment,
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     base::TimeDelta* timestamp_offset);
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Signals the frame processor to update its group start timestamp to be
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |timestamp_offset| if it is in sequence append mode.
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void SetGroupStartTimestampIfInSequenceMode(base::TimeDelta timestamp_offset);
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Adds a new track with unique track ID |id|.
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If |id| has previously been added, returns false to indicate error.
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Otherwise, returns true, indicating future ProcessFrames() will emit
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // frames for the track |id| to |stream|.
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool AddTrack(StreamParser::TrackId id, ChunkDemuxerStream* stream);
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Updates the internal mapping of TrackId to track buffer for the track
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // buffer formerly associated with |old_id| to be associated with |new_id|.
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns false to indicate failure due to either no existing track buffer
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // for |old_id| or collision with previous track buffer already mapped to
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |new_id|. Otherwise returns true.
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool UpdateTrack(StreamParser::TrackId old_id, StreamParser::TrackId new_id);
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Sets the need random access point flag on all track buffers to true.
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void SetAllTrackBuffersNeedRandomAccessPoint();
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Resets state for the coded frame processing algorithm as described in steps
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // 2-5 of the MSE Reset Parser State algorithm described at
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // http://www.w3.org/TR/media-source/#sourcebuffer-reset-parser-state
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Reset();
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Must be called when the audio config is updated.  Used to manage when
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the preroll buffer is cleared and the allowed "fudge" factor between
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // preroll buffers.
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnPossibleAudioConfigUpdate(const AudioDecoderConfig& config);
920de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) private:
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  typedef std::map<StreamParser::TrackId, MseTrackBuffer*> TrackBufferMap;
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If |track_buffers_| contains |id|, returns a pointer to the associated
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // MseTrackBuffer. Otherwise, returns NULL.
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MseTrackBuffer* FindTrack(StreamParser::TrackId id);
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Signals all track buffers' streams that a new media segment is starting
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // with decode timestamp |segment_timestamp|.
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void NotifyNewMediaSegmentStarting(DecodeTimestamp segment_timestamp);
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Helper that signals each track buffer to append any processed, but not yet
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // appended, frames to its stream. Returns true on success, or false if one or
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // more of the appends failed.
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool FlushProcessedFrames();
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Handles partial append window trimming of |buffer|.  Returns true if the
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // given |buffer| can be partially trimmed or have preroll added; otherwise,
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // returns false.
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If |buffer| overlaps |append_window_start|, the portion of |buffer| before
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |append_window_start| will be marked for post-decode discard.  Further, if
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |audio_preroll_buffer_| exists and abuts |buffer|, it will be set as
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // preroll on |buffer| and |audio_preroll_buffer_| will be cleared.  If the
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // preroll buffer does not abut |buffer|, it will be discarded unused.
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  //
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Likewise, if |buffer| overlaps |append_window_end|, the portion of |buffer|
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // after |append_window_end| will be marked for post-decode discard.
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If |buffer| lies entirely before |append_window_start|, and thus would
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // normally be discarded, |audio_preroll_buffer_| will be set to |buffer| and
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the method will return false.
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool HandlePartialAppendWindowTrimming(
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::TimeDelta append_window_start,
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::TimeDelta append_window_end,
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const scoped_refptr<StreamParserBuffer>& buffer);
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1300de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Helper that processes one frame with the coded frame processing algorithm.
1310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Returns false on error or true on success.
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool ProcessFrame(const scoped_refptr<StreamParserBuffer>& frame,
1330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                    base::TimeDelta append_window_start,
1340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                    base::TimeDelta append_window_end,
1350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                    base::TimeDelta* timestamp_offset,
1360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)                    bool* new_media_segment);
1370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TrackId-indexed map of each track's stream.
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TrackBufferMap track_buffers_;
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The last audio buffer seen by the frame processor that was removed because
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // it was entirely before the start of the append window.
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<StreamParserBuffer> audio_preroll_buffer_;
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The AudioDecoderConfig associated with buffers handed to ProcessFrames().
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AudioDecoderConfig current_audio_config_;
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeDelta sample_duration_;
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The AppendMode of the associated SourceBuffer.
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // See SetSequenceMode() for interpretation of |sequence_mode_|.
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Per http://www.w3.org/TR/media-source/#widl-SourceBuffer-mode:
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Controls how a sequence of media segments are handled. This is initially
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // set to false ("segments").
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool sequence_mode_;
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Tracks the MSE coded frame processing variable of same name.
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Initially kNoTimestamp(), meaning "unset".
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeDelta group_start_timestamp_;
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1600de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Tracks the MSE coded frame processing variable of same name. It stores the
1610de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // highest coded frame end timestamp across all coded frames in the current
1620de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // coded frame group. It is set to 0 when the SourceBuffer object is created
1630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // and gets updated by ProcessFrames().
1640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  base::TimeDelta group_end_timestamp_;
1650de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1660de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  UpdateDurationCB update_duration_cb_;
1670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1680de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FrameProcessor);
1690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)};
1700de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1710de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}  // namespace media
1720de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1730de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#endif  // MEDIA_FILTERS_FRAME_PROCESSOR_H_
174