Chromium Code Reviews| Index: media/filters/fake_video_decoder.h |
| diff --git a/media/filters/fake_video_decoder.h b/media/filters/fake_video_decoder.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f389c4da12d17821c1d919ec37c6ca482bf35b9f |
| --- /dev/null |
| +++ b/media/filters/fake_video_decoder.h |
| @@ -0,0 +1,151 @@ |
| +// Copyright (c) 2013 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_FAKE_VIDEO_DECODER_H_ |
| +#define MEDIA_FILTERS_FAKE_VIDEO_DECODER_H_ |
| + |
| +#include <list> |
| + |
| +#include "base/bind.h" |
| +#include "base/callback.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "media/base/decoder_buffer.h" |
| +#include "media/base/demuxer_stream.h" |
| +#include "media/base/media_export.h" |
| +#include "media/base/pipeline_status.h" |
| +#include "media/base/video_decoder.h" |
| +#include "media/base/video_decoder_config.h" |
| +#include "media/base/video_frame.h" |
| +#include "ui/gfx/size.h" |
| + |
| +namespace base { |
| +class MessageLoopProxy; |
| +} |
| + |
| +namespace media { |
| + |
| +class MEDIA_EXPORT FakeVideoDecoder : public VideoDecoder { |
| + public: |
| + // Constructs an object with a decoding delay of |decoding_delay| frames. |
| + explicit FakeVideoDecoder(int decoding_delay); |
| + virtual ~FakeVideoDecoder(); |
| + |
| + // VideoDecoder implementation. |
| + virtual void Initialize(DemuxerStream* stream, |
| + const PipelineStatusCB& status_cb, |
| + const StatisticsCB& statistics_cb) OVERRIDE; |
| + virtual void Read(const ReadCB& read_cb) OVERRIDE; |
| + virtual void Reset(const base::Closure& closure) OVERRIDE; |
| + virtual void Stop(const base::Closure& closure) OVERRIDE; |
| + |
| + // Holds the next read/reset/stop callback from firing. |
| + void HoldNextRead(); |
| + void HoldNextReset(); |
| + void HoldNextStop(); |
| + |
| + // Satisfies the pending read/reset/stop callback, which must be ready to fire |
| + // when these methods are called. |
| + void SatisfyRead(); |
| + void SatisfyReset(); |
| + void SatisfyStop(); |
| + |
| + private: |
| + enum State { |
| + UNINITIALIZED, |
| + NORMAL |
| + }; |
| + |
| + // A helper class that can hold a callback from being fired. |
| + template <typename CB> class CallbackHolder { |
|
scherkus (not reviewing)
2013/05/09 20:07:09
this is complex enough that I feel it should warra
xhwang
2013/05/22 04:29:42
Done.
|
| + public: |
| + CallbackHolder() : hold_callback_(false) {} |
| + |
| + ~CallbackHolder() { |
| + // Make sure all callbacks are satisfied! |
| + DCHECK(!hold_callback_); |
| + DCHECK(original_cb_.is_null()); |
| + DCHECK(held_cb_.is_null()); |
| + } |
| + |
| + // Sets the callback to be potentially held. |
| + void SetCallback(const CB& cb) { |
| + DCHECK(original_cb_.is_null()); |
| + DCHECK(held_cb_.is_null()); |
| + original_cb_ = cb; |
| + } |
| + |
| + bool is_null() const { |
| + return original_cb_.is_null() && held_cb_.is_null(); |
| + } |
| + |
| + // Holds the callback when Run() is called. |
| + void HoldCallback() { hold_callback_ = true; } |
| + |
| + // Runs or holds the callback as specified by |hold_next_callback_|. |
|
scherkus (not reviewing)
2013/05/09 20:07:09
s/hold_next_callback_/hold_callback_/
xhwang
2013/05/22 04:29:42
Done.
|
| + // This method has overloaded versions to support different types of CB. |
| + void Run() { |
|
scherkus (not reviewing)
2013/05/09 20:07:09
I don't like how CH emulates the regular API but d
xhwang
2013/05/22 04:29:42
Done.
|
| + DCHECK(held_cb_.is_null()); |
| + if (hold_callback_) |
| + held_cb_ = base::Bind(ResetAndReturn(&original_cb_)); |
|
scherkus (not reviewing)
2013/05/09 20:07:09
nit: base::Bind() not needed
xhwang
2013/05/22 04:29:42
Done.
|
| + else |
| + ResetAndReturn(&original_cb_).Run(); |
| + } |
| + |
| + template <typename A1, typename A2> void Run(A1 a1, A2 a2) { |
| + if (hold_callback_) |
| + held_cb_ = |
| + base::Bind(ResetAndReturn(&original_cb_), a1, a2); |
| + else |
| + ResetAndReturn(&original_cb_).Run(a1, a2); |
| + } |
| + |
| + // Releases and runs the held callback. |
| + void Release() { |
|
scherkus (not reviewing)
2013/05/09 20:07:09
RunHeldCallback()?
xhwang
2013/05/22 04:29:42
Done.
|
| + DCHECK(hold_callback_); |
| + DCHECK(!held_cb_.is_null()); |
| + hold_callback_ = false; |
| + ResetAndReturn(&held_cb_).Run(); |
| + } |
| + |
| + private: |
| + bool hold_callback_; |
| + CB original_cb_; |
| + base::Closure held_cb_; |
| + }; |
| + |
| + void ReadFromDemuxerStream(); |
| + |
| + // Callback for DemuxerStream::Read(). |
| + void BufferReady(DemuxerStream::Status status, |
| + const scoped_refptr<DecoderBuffer>& buffer); |
| + |
| + void DoReset(); |
| + void DoStop(); |
| + |
| + scoped_refptr<base::MessageLoopProxy> message_loop_; |
| + base::WeakPtrFactory<FakeVideoDecoder> weak_factory_; |
| + base::WeakPtr<FakeVideoDecoder> weak_this_; |
| + |
| + const int decoding_delay_; |
| + |
| + State state_; |
| + |
| + StatisticsCB statistics_cb_; |
| + CallbackHolder<ReadCB> read_cb_; |
| + CallbackHolder<base::Closure> reset_cb_; |
| + CallbackHolder<base::Closure> stop_cb_; |
| + |
| + // Pointer to the demuxer stream that will feed us compressed buffers. |
| + DemuxerStream* demuxer_stream_; |
| + |
| + VideoDecoderConfig current_config_; |
| + |
| + std::list<scoped_refptr<VideoFrame> > decoded_frames_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoder); |
| +}; |
| + |
| +} // namespace media |
| + |
| +#endif // MEDIA_FILTERS_FAKE_VIDEO_DECODER_H_ |