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