Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / media / filters / frame_processor.h
index fcfe737..0afcf0a 100644 (file)
 #ifndef MEDIA_FILTERS_FRAME_PROCESSOR_H_
 #define MEDIA_FILTERS_FRAME_PROCESSOR_H_
 
+#include <map>
+
 #include "base/basictypes.h"
 #include "base/callback_forward.h"
 #include "base/time/time.h"
 #include "media/base/media_export.h"
 #include "media/base/stream_parser.h"
-#include "media/filters/frame_processor_base.h"
+#include "media/filters/chunk_demuxer.h"
 
 namespace media {
 
+class MseTrackBuffer;
+
 // Helper class that implements Media Source Extension's coded frame processing
 // algorithm.
-class MEDIA_EXPORT FrameProcessor : public FrameProcessorBase {
+class MEDIA_EXPORT FrameProcessor {
  public:
   typedef base::Callback<void(base::TimeDelta)> UpdateDurationCB;
+
+  // TODO(wolenetz/acolwell): Ensure that all TrackIds are coherent and unique
+  // for each track buffer. For now, special track identifiers are used for each
+  // of audio and video here, and text TrackIds are assumed to be non-negative.
+  // See http://crbug.com/341581.
+  enum {
+    kAudioTrackId = -2,
+    kVideoTrackId = -3
+  };
+
   explicit FrameProcessor(const UpdateDurationCB& update_duration_cb);
-  virtual ~FrameProcessor();
-
-  // FrameProcessorBase implementation
-  virtual void SetSequenceMode(bool sequence_mode) OVERRIDE;
-  virtual bool ProcessFrames(const StreamParser::BufferQueue& audio_buffers,
-                             const StreamParser::BufferQueue& video_buffers,
-                             const StreamParser::TextBufferQueueMap& text_map,
-                             base::TimeDelta append_window_start,
-                             base::TimeDelta append_window_end,
-                             bool* new_media_segment,
-                             base::TimeDelta* timestamp_offset) OVERRIDE;
+  ~FrameProcessor();
+
+  // Get/set the current append mode, which if true means "sequence" and if
+  // false means "segments".
+  // See http://www.w3.org/TR/media-source/#widl-SourceBuffer-mode.
+  bool sequence_mode() { return sequence_mode_; }
+  void SetSequenceMode(bool sequence_mode);
+
+  // Processes buffers in |audio_buffers|, |video_buffers|, and |text_map|.
+  // Returns true on success or false on failure which indicates decode error.
+  // |append_window_start| and |append_window_end| correspond to the MSE spec's
+  // similarly named source buffer attributes that are used in coded frame
+  // processing.
+  // |*new_media_segment| tracks whether the next buffers processed within the
+  // append window represent the start of a new media segment. This method may
+  // both use and update this flag.
+  // Uses |*timestamp_offset| according to the coded frame processing algorithm,
+  // including updating it as required in 'sequence' mode frame processing.
+  bool ProcessFrames(const StreamParser::BufferQueue& audio_buffers,
+                     const StreamParser::BufferQueue& video_buffers,
+                     const StreamParser::TextBufferQueueMap& text_map,
+                     base::TimeDelta append_window_start,
+                     base::TimeDelta append_window_end,
+                     bool* new_media_segment,
+                     base::TimeDelta* timestamp_offset);
+
+  // Signals the frame processor to update its group start timestamp to be
+  // |timestamp_offset| if it is in sequence append mode.
+  void SetGroupStartTimestampIfInSequenceMode(base::TimeDelta timestamp_offset);
+
+  // Adds a new track with unique track ID |id|.
+  // If |id| has previously been added, returns false to indicate error.
+  // Otherwise, returns true, indicating future ProcessFrames() will emit
+  // frames for the track |id| to |stream|.
+  bool AddTrack(StreamParser::TrackId id, ChunkDemuxerStream* stream);
+
+  // Updates the internal mapping of TrackId to track buffer for the track
+  // buffer formerly associated with |old_id| to be associated with |new_id|.
+  // Returns false to indicate failure due to either no existing track buffer
+  // for |old_id| or collision with previous track buffer already mapped to
+  // |new_id|. Otherwise returns true.
+  bool UpdateTrack(StreamParser::TrackId old_id, StreamParser::TrackId new_id);
+
+  // Sets the need random access point flag on all track buffers to true.
+  void SetAllTrackBuffersNeedRandomAccessPoint();
+
+  // Resets state for the coded frame processing algorithm as described in steps
+  // 2-5 of the MSE Reset Parser State algorithm described at
+  // http://www.w3.org/TR/media-source/#sourcebuffer-reset-parser-state
+  void Reset();
+
+  // Must be called when the audio config is updated.  Used to manage when
+  // the preroll buffer is cleared and the allowed "fudge" factor between
+  // preroll buffers.
+  void OnPossibleAudioConfigUpdate(const AudioDecoderConfig& config);
 
  private:
+  typedef std::map<StreamParser::TrackId, MseTrackBuffer*> TrackBufferMap;
+
+  // If |track_buffers_| contains |id|, returns a pointer to the associated
+  // MseTrackBuffer. Otherwise, returns NULL.
+  MseTrackBuffer* FindTrack(StreamParser::TrackId id);
+
+  // Signals all track buffers' streams that a new media segment is starting
+  // with decode timestamp |segment_timestamp|.
+  void NotifyNewMediaSegmentStarting(DecodeTimestamp segment_timestamp);
+
+  // Helper that signals each track buffer to append any processed, but not yet
+  // appended, frames to its stream. Returns true on success, or false if one or
+  // more of the appends failed.
+  bool FlushProcessedFrames();
+
+  // Handles partial append window trimming of |buffer|.  Returns true if the
+  // given |buffer| can be partially trimmed or have preroll added; otherwise,
+  // returns false.
+  //
+  // If |buffer| overlaps |append_window_start|, the portion of |buffer| before
+  // |append_window_start| will be marked for post-decode discard.  Further, if
+  // |audio_preroll_buffer_| exists and abuts |buffer|, it will be set as
+  // preroll on |buffer| and |audio_preroll_buffer_| will be cleared.  If the
+  // preroll buffer does not abut |buffer|, it will be discarded unused.
+  //
+  // Likewise, if |buffer| overlaps |append_window_end|, the portion of |buffer|
+  // after |append_window_end| will be marked for post-decode discard.
+  //
+  // If |buffer| lies entirely before |append_window_start|, and thus would
+  // normally be discarded, |audio_preroll_buffer_| will be set to |buffer| and
+  // the method will return false.
+  bool HandlePartialAppendWindowTrimming(
+      base::TimeDelta append_window_start,
+      base::TimeDelta append_window_end,
+      const scoped_refptr<StreamParserBuffer>& buffer);
+
   // Helper that processes one frame with the coded frame processing algorithm.
   // Returns false on error or true on success.
   bool ProcessFrame(const scoped_refptr<StreamParserBuffer>& frame,
@@ -41,6 +135,28 @@ class MEDIA_EXPORT FrameProcessor : public FrameProcessorBase {
                     base::TimeDelta* timestamp_offset,
                     bool* new_media_segment);
 
+  // TrackId-indexed map of each track's stream.
+  TrackBufferMap track_buffers_;
+
+  // The last audio buffer seen by the frame processor that was removed because
+  // it was entirely before the start of the append window.
+  scoped_refptr<StreamParserBuffer> audio_preroll_buffer_;
+
+  // The AudioDecoderConfig associated with buffers handed to ProcessFrames().
+  AudioDecoderConfig current_audio_config_;
+  base::TimeDelta sample_duration_;
+
+  // The AppendMode of the associated SourceBuffer.
+  // See SetSequenceMode() for interpretation of |sequence_mode_|.
+  // Per http://www.w3.org/TR/media-source/#widl-SourceBuffer-mode:
+  // Controls how a sequence of media segments are handled. This is initially
+  // set to false ("segments").
+  bool sequence_mode_;
+
+  // Tracks the MSE coded frame processing variable of same name.
+  // Initially kNoTimestamp(), meaning "unset".
+  base::TimeDelta group_start_timestamp_;
+
   // Tracks the MSE coded frame processing variable of same name. It stores the
   // highest coded frame end timestamp across all coded frames in the current
   // coded frame group. It is set to 0 when the SourceBuffer object is created