• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #ifndef MEDIA_FILTERS_DECODER_STREAM_H_
6 #define MEDIA_FILTERS_DECODER_STREAM_H_
7 
8 #include "base/basictypes.h"
9 #include "base/callback.h"
10 #include "base/compiler_specific.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/memory/weak_ptr.h"
14 #include "media/base/audio_decoder.h"
15 #include "media/base/decryptor.h"
16 #include "media/base/demuxer_stream.h"
17 #include "media/base/media_export.h"
18 #include "media/base/pipeline_status.h"
19 #include "media/filters/decoder_selector.h"
20 #include "media/filters/decoder_stream_traits.h"
21 
22 namespace base {
23 class SingleThreadTaskRunner;
24 }
25 
26 namespace media {
27 
28 class DecryptingDemuxerStream;
29 
30 // Wraps a DemuxerStream and a list of Decoders and provides decoded
31 // output to its client (e.g. Audio/VideoRendererImpl).
32 template<DemuxerStream::Type StreamType>
33 class MEDIA_EXPORT DecoderStream {
34  public:
35   typedef DecoderStreamTraits<StreamType> StreamTraits;
36   typedef typename StreamTraits::DecoderType Decoder;
37   typedef typename StreamTraits::OutputType Output;
38   typedef typename StreamTraits::StreamInitCB InitCB;
39   typedef typename Decoder::Status DecoderStatus;
40 
41   enum Status {
42     OK,  // Everything went as planned.
43     ABORTED,  // Read aborted due to Reset() during pending read.
44     DEMUXER_READ_ABORTED,  // Demuxer returned aborted read.
45     DECODE_ERROR,  // Decoder returned decode error.
46     DECRYPT_ERROR  // Decoder returned decrypt error.
47   };
48 
49   // Indicates completion of a DecoderStream read.
50   typedef base::Callback<void(Status, const scoped_refptr<Output>&)> ReadCB;
51 
52   DecoderStream(
53       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
54       ScopedVector<Decoder> decoders,
55       const SetDecryptorReadyCB& set_decryptor_ready_cb);
56   virtual ~DecoderStream();
57 
58   // Initializes the DecoderStream and returns the initialization result
59   // through |init_cb|. Note that |init_cb| is always called asynchronously.
60   void Initialize(DemuxerStream* stream,
61                   bool low_delay,
62                   const StatisticsCB& statistics_cb,
63                   const InitCB& init_cb);
64 
65   // Reads a decoded Output and returns it via the |read_cb|. Note that
66   // |read_cb| is always called asynchronously. This method should only be
67   // called after initialization has succeeded and must not be called during
68   // any pending Reset() and/or Stop().
69   void Read(const ReadCB& read_cb);
70 
71   // Resets the decoder, flushes all decoded outputs and/or internal buffers,
72   // fires any existing pending read callback and calls |closure| on completion.
73   // Note that |closure| is always called asynchronously. This method should
74   // only be called after initialization has succeeded and must not be called
75   // during any pending Reset() and/or Stop().
76   void Reset(const base::Closure& closure);
77 
78   // Stops the decoder, fires any existing pending read callback or reset
79   // callback and calls |closure| on completion. Note that |closure| is always
80   // called asynchronously. The DecoderStream cannot be used anymore after
81   // it is stopped. This method can be called at any time but not during another
82   // pending Stop().
83   void Stop(const base::Closure& closure);
84 
85   // Returns true if the decoder currently has the ability to decode and return
86   // an Output.
87   // TODO(rileya): Remove the need for this by refactoring Decoder queueing
88   // behavior.
89   bool CanReadWithoutStalling() const;
90 
91   // Returns maximum concurrent decode requests for the current |decoder_|.
92   int GetMaxDecodeRequests() const;
93 
94   // Returns true if one more decode request can be submitted to the decoder.
95   bool CanDecodeMore() const;
96 
97   // Allows callers to register for notification of splice buffers from the
98   // demuxer.  I.e., DecoderBuffer::splice_timestamp() is not kNoTimestamp().
99   //
100   // The observer will be notified of all buffers with a splice_timestamp() and
101   // the first buffer after which has a splice_timestamp() of kNoTimestamp().
102   typedef base::Callback<void(base::TimeDelta)> SpliceObserverCB;
set_splice_observer(const SpliceObserverCB & splice_observer)103   void set_splice_observer(const SpliceObserverCB& splice_observer) {
104     splice_observer_cb_ = splice_observer;
105   }
106 
107   // Allows callers to register for notification of config changes; this is
108   // called immediately after recieving the 'kConfigChanged' status from the
109   // DemuxerStream, before any action is taken to handle the config change.
110   typedef base::Closure ConfigChangeObserverCB;
set_config_change_observer(const ConfigChangeObserverCB & config_change_observer)111   void set_config_change_observer(
112       const ConfigChangeObserverCB& config_change_observer) {
113     config_change_observer_cb_ = config_change_observer;
114   }
115 
116  private:
117   enum State {
118     STATE_UNINITIALIZED,
119     STATE_INITIALIZING,
120     STATE_NORMAL,  // Includes idle, pending decoder decode/reset/stop.
121     STATE_FLUSHING_DECODER,
122     STATE_PENDING_DEMUXER_READ,
123     STATE_REINITIALIZING_DECODER,
124     STATE_END_OF_STREAM,  // End of stream reached; returns EOS on all reads.
125     STATE_STOPPED,
126     STATE_ERROR
127   };
128 
129   // Called when |decoder_selector| selected the |selected_decoder|.
130   // |decrypting_demuxer_stream| was also populated if a DecryptingDemuxerStream
131   // is created to help decrypt the encrypted stream.
132   void OnDecoderSelected(
133       scoped_ptr<Decoder> selected_decoder,
134       scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream);
135 
136   // Satisfy pending |read_cb_| with |status| and |output|.
137   void SatisfyRead(Status status,
138                    const scoped_refptr<Output>& output);
139 
140   // Decodes |buffer| and returns the result via OnDecodeOutputReady().
141   void Decode(const scoped_refptr<DecoderBuffer>& buffer);
142 
143   // Flushes the decoder with an EOS buffer to retrieve internally buffered
144   // decoder output.
145   void FlushDecoder();
146 
147   // Callback for Decoder::Decode().
148   void OnDecodeDone(int buffer_size, bool end_of_stream, DecoderStatus status);
149 
150   // Output callback passed to Decoder::Initialize().
151   void OnDecodeOutputReady(const scoped_refptr<Output>& output);
152 
153   // Reads a buffer from |stream_| and returns the result via OnBufferReady().
154   void ReadFromDemuxerStream();
155 
156   // Callback for DemuxerStream::Read().
157   void OnBufferReady(DemuxerStream::Status status,
158                      const scoped_refptr<DecoderBuffer>& buffer);
159 
160   void ReinitializeDecoder();
161 
162   // Callback for Decoder reinitialization.
163   void OnDecoderReinitialized(PipelineStatus status);
164 
165   void ResetDecoder();
166   void OnDecoderReset();
167 
168   void StopDecoder();
169 
170   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
171 
172   State state_;
173 
174   StatisticsCB statistics_cb_;
175   InitCB init_cb_;
176 
177   ReadCB read_cb_;
178   base::Closure reset_cb_;
179   base::Closure stop_cb_;
180 
181   DemuxerStream* stream_;
182   bool low_delay_;
183 
184   scoped_ptr<DecoderSelector<StreamType> > decoder_selector_;
185 
186   // These two will be set by DecoderSelector::SelectDecoder().
187   scoped_ptr<Decoder> decoder_;
188   scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
189 
190   SpliceObserverCB splice_observer_cb_;
191   ConfigChangeObserverCB config_change_observer_cb_;
192 
193   // If a splice_timestamp() has been seen, this is true until a
194   // splice_timestamp() of kNoTimestamp() is encountered.
195   bool active_splice_;
196 
197   // Decoded buffers that haven't been read yet. Used when the decoder supports
198   // parallel decoding.
199   std::list<scoped_refptr<Output> > ready_outputs_;
200 
201   // Number of outstanding decode requests sent to the |decoder_|.
202   int pending_decode_requests_;
203 
204   // NOTE: Weak pointers must be invalidated before all other member variables.
205   base::WeakPtrFactory<DecoderStream<StreamType> > weak_factory_;
206 
207   // This is required so the VideoFrameStream can access private members in
208   // FinishInitialization() and ReportStatistics().
209   DISALLOW_IMPLICIT_CONSTRUCTORS(DecoderStream);
210 };
211 
212 template <>
213 bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const;
214 
215 template <>
216 int DecoderStream<DemuxerStream::AUDIO>::GetMaxDecodeRequests() const;
217 
218 typedef DecoderStream<DemuxerStream::VIDEO> VideoFrameStream;
219 typedef DecoderStream<DemuxerStream::AUDIO> AudioBufferStream;
220 
221 }  // namespace media
222 
223 #endif  // MEDIA_FILTERS_DECODER_STREAM_H_
224