1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef MEDIA_BASE_STREAM_PARSER_H_
6#define MEDIA_BASE_STREAM_PARSER_H_
7
8#include <deque>
9#include <map>
10#include <string>
11#include <vector>
12
13#include "base/callback_forward.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/time/time.h"
17#include "media/base/media_export.h"
18#include "media/base/media_log.h"
19
20namespace media {
21
22class AudioDecoderConfig;
23class StreamParserBuffer;
24class TextTrackConfig;
25class VideoDecoderConfig;
26
27// Abstract interface for parsing media byte streams.
28class MEDIA_EXPORT StreamParser {
29 public:
30  typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
31
32  // Range of |TrackId| is dependent upon stream parsers. It is currently
33  // the key for the buffer's text track config in the applicable
34  // TextTrackConfigMap (which is passed in StreamParser::NewConfigCB), or
35  // 0 for other media types that currently allow at most one track.
36  // WebMTracksParser uses -1 as an invalid text track number.
37  // TODO(wolenetz/acolwell): Change to size_type while fixing stream parsers to
38  // emit validated track configuration and buffer vectors rather than max 1
39  // audio, max 1 video, and N text tracks in a map keyed by
40  // bytestream-specific-ranged track numbers. See http://crbug.com/341581.
41  typedef int TrackId;
42
43  // Map of text track ID to the track configuration.
44  typedef std::map<TrackId, TextTrackConfig> TextTrackConfigMap;
45
46  // Map of text track ID to decode-timestamp-ordered buffers for the track.
47  typedef std::map<TrackId, const BufferQueue> TextBufferQueueMap;
48
49  // Stream parameters passed in InitCB.
50  struct InitParameters {
51    InitParameters(base::TimeDelta duration);
52
53    // Stream duration.
54    base::TimeDelta duration;
55
56    // Indicates the source time associated with presentation timestamp 0. A
57    // null Time is returned if no mapping to Time exists.
58    base::Time timeline_offset;
59
60    // Indicates that timestampOffset should be updated based on the earliest
61    // end timestamp (audio or video) provided during each NewBuffersCB.
62    bool auto_update_timestamp_offset;
63
64    // Indicates live stream.
65    Demuxer::Liveness liveness;
66  };
67
68  // Indicates completion of parser initialization.
69  //   success - True if initialization was successful.
70  //   params - Stream parameters, in case of successful initialization.
71  typedef base::Callback<void(bool success,
72                              const InitParameters& params)> InitCB;
73
74  // Indicates when new stream configurations have been parsed.
75  // First parameter - The new audio configuration. If the config is not valid
76  //                   then it means that there isn't an audio stream.
77  // Second parameter - The new video configuration. If the config is not valid
78  //                    then it means that there isn't an audio stream.
79  // Third parameter - The new text tracks configuration.  If the map is empty,
80  //                   then no text tracks were parsed from the stream.
81  // Return value - True if the new configurations are accepted.
82  //                False if the new configurations are not supported
83  //                and indicates that a parsing error should be signalled.
84  typedef base::Callback<bool(const AudioDecoderConfig&,
85                              const VideoDecoderConfig&,
86                              const TextTrackConfigMap&)> NewConfigCB;
87
88  // New stream buffers have been parsed.
89  // First parameter - A queue of newly parsed audio buffers.
90  // Second parameter - A queue of newly parsed video buffers.
91  // Third parameter - A map of text track ids to queues of newly parsed inband
92  //                   text buffers. If the map is not empty, it must contain
93  //                   at least one track with a non-empty queue of text
94  //                   buffers.
95  // Return value - True indicates that the buffers are accepted.
96  //                False if something was wrong with the buffers and a parsing
97  //                error should be signalled.
98  typedef base::Callback<bool(const BufferQueue&,
99                              const BufferQueue&,
100                              const TextBufferQueueMap&)> NewBuffersCB;
101
102  // Signals the beginning of a new media segment.
103  typedef base::Callback<void()> NewMediaSegmentCB;
104
105  // A new potentially encrypted stream has been parsed.
106  // First parameter - The type of the initialization data associated with the
107  //                   stream.
108  // Second parameter - The initialization data associated with the stream.
109  typedef base::Callback<void(const std::string&,
110                              const std::vector<uint8>&)> NeedKeyCB;
111
112  StreamParser();
113  virtual ~StreamParser();
114
115  // Initializes the parser with necessary callbacks. Must be called before any
116  // data is passed to Parse(). |init_cb| will be called once enough data has
117  // been parsed to determine the initial stream configurations, presentation
118  // start time, and duration. If |ignore_text_track| is true, then no text
119  // buffers should be passed later by the parser to |new_buffers_cb|.
120  virtual void Init(const InitCB& init_cb,
121                    const NewConfigCB& config_cb,
122                    const NewBuffersCB& new_buffers_cb,
123                    bool ignore_text_track,
124                    const NeedKeyCB& need_key_cb,
125                    const NewMediaSegmentCB& new_segment_cb,
126                    const base::Closure& end_of_segment_cb,
127                    const LogCB& log_cb) = 0;
128
129  // Called when a seek occurs. This flushes the current parser state
130  // and puts the parser in a state where it can receive data for the new seek
131  // point.
132  virtual void Flush() = 0;
133
134  // Called when there is new data to parse.
135  //
136  // Returns true if the parse succeeds.
137  virtual bool Parse(const uint8* buf, int size) = 0;
138
139 private:
140  DISALLOW_COPY_AND_ASSIGN(StreamParser);
141};
142
143// Appends to |merged_buffers| the provided buffers in decode-timestamp order.
144// Any previous contents of |merged_buffers| is assumed to have lower
145// decode timestamps versus the provided buffers. All provided buffer queues
146// are assumed to already be in decode-timestamp order.
147// Returns false if any of the provided audio/video/text buffers are found
148// to not be in decode timestamp order, or have a decode timestamp less than
149// the last buffer, if any, in |merged_buffers|. Partial results may exist
150// in |merged_buffers| in this case. Returns true on success.
151// No validation of media type within the various buffer queues is done here.
152// TODO(wolenetz/acolwell): Merge incrementally in parsers to eliminate
153// subtle issues with tie-breaking. See http://crbug.com/338484.
154MEDIA_EXPORT bool MergeBufferQueues(
155    const StreamParser::BufferQueue& audio_buffers,
156    const StreamParser::BufferQueue& video_buffers,
157    const StreamParser::TextBufferQueueMap& text_buffers,
158    StreamParser::BufferQueue* merged_buffers);
159
160}  // namespace media
161
162#endif  // MEDIA_BASE_STREAM_PARSER_H_
163