summaryrefslogtreecommitdiffstats
path: root/chromium/media/filters/decoder_stream.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/filters/decoder_stream.h')
-rw-r--r--chromium/media/filters/decoder_stream.h223
1 files changed, 223 insertions, 0 deletions
diff --git a/chromium/media/filters/decoder_stream.h b/chromium/media/filters/decoder_stream.h
new file mode 100644
index 00000000000..7cb78738dac
--- /dev/null
+++ b/chromium/media/filters/decoder_stream.h
@@ -0,0 +1,223 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_FILTERS_DECODER_STREAM_H_
+#define MEDIA_FILTERS_DECODER_STREAM_H_
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_vector.h"
+#include "base/memory/weak_ptr.h"
+#include "media/base/audio_decoder.h"
+#include "media/base/decryptor.h"
+#include "media/base/demuxer_stream.h"
+#include "media/base/media_export.h"
+#include "media/base/pipeline_status.h"
+#include "media/filters/decoder_selector.h"
+#include "media/filters/decoder_stream_traits.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace media {
+
+class DecryptingDemuxerStream;
+
+// Wraps a DemuxerStream and a list of Decoders and provides decoded
+// output to its client (e.g. Audio/VideoRendererImpl).
+template<DemuxerStream::Type StreamType>
+class MEDIA_EXPORT DecoderStream {
+ public:
+ typedef DecoderStreamTraits<StreamType> StreamTraits;
+ typedef typename StreamTraits::DecoderType Decoder;
+ typedef typename StreamTraits::OutputType Output;
+ typedef typename StreamTraits::StreamInitCB InitCB;
+ typedef typename Decoder::Status DecoderStatus;
+
+ enum Status {
+ OK, // Everything went as planned.
+ ABORTED, // Read aborted due to Reset() during pending read.
+ DEMUXER_READ_ABORTED, // Demuxer returned aborted read.
+ DECODE_ERROR, // Decoder returned decode error.
+ DECRYPT_ERROR // Decoder returned decrypt error.
+ };
+
+ // Indicates completion of a DecoderStream read.
+ typedef base::Callback<void(Status, const scoped_refptr<Output>&)> ReadCB;
+
+ DecoderStream(
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+ ScopedVector<Decoder> decoders,
+ const SetDecryptorReadyCB& set_decryptor_ready_cb);
+ virtual ~DecoderStream();
+
+ // Initializes the DecoderStream and returns the initialization result
+ // through |init_cb|. Note that |init_cb| is always called asynchronously.
+ void Initialize(DemuxerStream* stream,
+ bool low_delay,
+ const StatisticsCB& statistics_cb,
+ const InitCB& init_cb);
+
+ // Reads a decoded Output and returns it via the |read_cb|. Note that
+ // |read_cb| is always called asynchronously. This method should only be
+ // called after initialization has succeeded and must not be called during
+ // any pending Reset() and/or Stop().
+ void Read(const ReadCB& read_cb);
+
+ // Resets the decoder, flushes all decoded outputs and/or internal buffers,
+ // fires any existing pending read callback and calls |closure| on completion.
+ // Note that |closure| is always called asynchronously. This method should
+ // only be called after initialization has succeeded and must not be called
+ // during any pending Reset() and/or Stop().
+ void Reset(const base::Closure& closure);
+
+ // Stops the decoder, fires any existing pending read callback or reset
+ // callback and calls |closure| on completion. Note that |closure| is always
+ // called asynchronously. The DecoderStream cannot be used anymore after
+ // it is stopped. This method can be called at any time but not during another
+ // pending Stop().
+ void Stop(const base::Closure& closure);
+
+ // Returns true if the decoder currently has the ability to decode and return
+ // an Output.
+ // TODO(rileya): Remove the need for this by refactoring Decoder queueing
+ // behavior.
+ bool CanReadWithoutStalling() const;
+
+ // Returns maximum concurrent decode requests for the current |decoder_|.
+ int GetMaxDecodeRequests() const;
+
+ // Returns true if one more decode request can be submitted to the decoder.
+ bool CanDecodeMore() const;
+
+ // Allows callers to register for notification of splice buffers from the
+ // demuxer. I.e., DecoderBuffer::splice_timestamp() is not kNoTimestamp().
+ //
+ // The observer will be notified of all buffers with a splice_timestamp() and
+ // the first buffer after which has a splice_timestamp() of kNoTimestamp().
+ typedef base::Callback<void(base::TimeDelta)> SpliceObserverCB;
+ void set_splice_observer(const SpliceObserverCB& splice_observer) {
+ splice_observer_cb_ = splice_observer;
+ }
+
+ // Allows callers to register for notification of config changes; this is
+ // called immediately after recieving the 'kConfigChanged' status from the
+ // DemuxerStream, before any action is taken to handle the config change.
+ typedef base::Closure ConfigChangeObserverCB;
+ void set_config_change_observer(
+ const ConfigChangeObserverCB& config_change_observer) {
+ config_change_observer_cb_ = config_change_observer;
+ }
+
+ private:
+ enum State {
+ STATE_UNINITIALIZED,
+ STATE_INITIALIZING,
+ STATE_NORMAL, // Includes idle, pending decoder decode/reset/stop.
+ STATE_FLUSHING_DECODER,
+ STATE_PENDING_DEMUXER_READ,
+ STATE_REINITIALIZING_DECODER,
+ STATE_END_OF_STREAM, // End of stream reached; returns EOS on all reads.
+ STATE_STOPPED,
+ STATE_ERROR
+ };
+
+ // Called when |decoder_selector| selected the |selected_decoder|.
+ // |decrypting_demuxer_stream| was also populated if a DecryptingDemuxerStream
+ // is created to help decrypt the encrypted stream.
+ void OnDecoderSelected(
+ scoped_ptr<Decoder> selected_decoder,
+ scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream);
+
+ // Satisfy pending |read_cb_| with |status| and |output|.
+ void SatisfyRead(Status status,
+ const scoped_refptr<Output>& output);
+
+ // Decodes |buffer| and returns the result via OnDecodeOutputReady().
+ void Decode(const scoped_refptr<DecoderBuffer>& buffer);
+
+ // Flushes the decoder with an EOS buffer to retrieve internally buffered
+ // decoder output.
+ void FlushDecoder();
+
+ // Callback for Decoder::Decode().
+ void OnDecodeDone(int buffer_size, bool end_of_stream, DecoderStatus status);
+
+ // Output callback passed to Decoder::Initialize().
+ void OnDecodeOutputReady(const scoped_refptr<Output>& output);
+
+ // Reads a buffer from |stream_| and returns the result via OnBufferReady().
+ void ReadFromDemuxerStream();
+
+ // Callback for DemuxerStream::Read().
+ void OnBufferReady(DemuxerStream::Status status,
+ const scoped_refptr<DecoderBuffer>& buffer);
+
+ void ReinitializeDecoder();
+
+ // Callback for Decoder reinitialization.
+ void OnDecoderReinitialized(PipelineStatus status);
+
+ void ResetDecoder();
+ void OnDecoderReset();
+
+ void StopDecoder();
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ State state_;
+
+ StatisticsCB statistics_cb_;
+ InitCB init_cb_;
+
+ ReadCB read_cb_;
+ base::Closure reset_cb_;
+ base::Closure stop_cb_;
+
+ DemuxerStream* stream_;
+ bool low_delay_;
+
+ scoped_ptr<DecoderSelector<StreamType> > decoder_selector_;
+
+ // These two will be set by DecoderSelector::SelectDecoder().
+ scoped_ptr<Decoder> decoder_;
+ scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
+
+ SpliceObserverCB splice_observer_cb_;
+ ConfigChangeObserverCB config_change_observer_cb_;
+
+ // If a splice_timestamp() has been seen, this is true until a
+ // splice_timestamp() of kNoTimestamp() is encountered.
+ bool active_splice_;
+
+ // Decoded buffers that haven't been read yet. Used when the decoder supports
+ // parallel decoding.
+ std::list<scoped_refptr<Output> > ready_outputs_;
+
+ // Number of outstanding decode requests sent to the |decoder_|.
+ int pending_decode_requests_;
+
+ // NOTE: Weak pointers must be invalidated before all other member variables.
+ base::WeakPtrFactory<DecoderStream<StreamType> > weak_factory_;
+
+ // This is required so the VideoFrameStream can access private members in
+ // FinishInitialization() and ReportStatistics().
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DecoderStream);
+};
+
+template <>
+bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const;
+
+template <>
+int DecoderStream<DemuxerStream::AUDIO>::GetMaxDecodeRequests() const;
+
+typedef DecoderStream<DemuxerStream::VIDEO> VideoFrameStream;
+typedef DecoderStream<DemuxerStream::AUDIO> AudioBufferStream;
+
+} // namespace media
+
+#endif // MEDIA_FILTERS_DECODER_STREAM_H_