1 // Copyright (c) 2013 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.
5 #include "media/filters/fake_demuxer_stream.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h"
12 #include "media/base/bind_to_loop.h"
13 #include "media/base/decoder_buffer.h"
14 #include "media/base/test_helpers.h"
15 #include "media/base/video_frame.h"
16 #include "ui/gfx/rect.h"
17 #include "ui/gfx/size.h"
21 static const int kStartTimestampMs = 0;
22 static const int kDurationMs = 30;
23 static const int kStartWidth = 320;
24 static const int kStartHeight = 240;
25 static const int kWidthDelta = 4;
26 static const int kHeightDelta = 3;
28 FakeDemuxerStream::FakeDemuxerStream(int num_configs,
29 int num_buffers_in_one_config,
31 : message_loop_(base::MessageLoopProxy::current()),
32 num_configs_left_(num_configs),
33 num_buffers_in_one_config_(num_buffers_in_one_config),
34 is_encrypted_(is_encrypted),
35 num_buffers_left_in_current_config_(num_buffers_in_one_config),
36 num_buffers_returned_(0),
37 current_timestamp_(base::TimeDelta::FromMilliseconds(kStartTimestampMs)),
38 duration_(base::TimeDelta::FromMilliseconds(kDurationMs)),
39 next_coded_size_(kStartWidth, kStartHeight),
42 DCHECK_GT(num_configs_left_, 0);
43 DCHECK_GT(num_buffers_in_one_config_, 0);
44 UpdateVideoDecoderConfig();
47 FakeDemuxerStream::~FakeDemuxerStream() {}
49 void FakeDemuxerStream::Read(const ReadCB& read_cb) {
50 DCHECK(message_loop_->BelongsToCurrentThread());
51 DCHECK(read_cb_.is_null());
53 read_cb_ = BindToCurrentLoop(read_cb);
55 if (read_to_hold_ == next_read_num_)
58 DCHECK(read_to_hold_ == -1 || read_to_hold_ > next_read_num_);
62 AudioDecoderConfig FakeDemuxerStream::audio_decoder_config() {
63 DCHECK(message_loop_->BelongsToCurrentThread());
65 return AudioDecoderConfig();
68 VideoDecoderConfig FakeDemuxerStream::video_decoder_config() {
69 DCHECK(message_loop_->BelongsToCurrentThread());
70 return video_decoder_config_;
73 // TODO(xhwang): Support audio if needed.
74 DemuxerStream::Type FakeDemuxerStream::type() {
75 DCHECK(message_loop_->BelongsToCurrentThread());
79 void FakeDemuxerStream::EnableBitstreamConverter() {
80 DCHECK(message_loop_->BelongsToCurrentThread());
83 void FakeDemuxerStream::HoldNextRead() {
84 DCHECK(message_loop_->BelongsToCurrentThread());
85 read_to_hold_ = next_read_num_;
88 void FakeDemuxerStream::HoldNextConfigChangeRead() {
89 DCHECK(message_loop_->BelongsToCurrentThread());
90 // Set |read_to_hold_| to be the next config change read.
91 read_to_hold_ = next_read_num_ + num_buffers_in_one_config_ -
92 next_read_num_ % (num_buffers_in_one_config_ + 1);
95 void FakeDemuxerStream::SatisfyRead() {
96 DCHECK(message_loop_->BelongsToCurrentThread());
97 DCHECK_EQ(read_to_hold_, next_read_num_);
98 DCHECK(!read_cb_.is_null());
104 void FakeDemuxerStream::Reset() {
107 if (!read_cb_.is_null())
108 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
111 void FakeDemuxerStream::UpdateVideoDecoderConfig() {
112 const gfx::Rect kVisibleRect(kStartWidth, kStartHeight);
113 video_decoder_config_.Initialize(
114 kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, VideoFrame::YV12,
115 next_coded_size_, kVisibleRect, next_coded_size_,
116 NULL, 0, is_encrypted_, false);
117 next_coded_size_.Enlarge(kWidthDelta, kHeightDelta);
120 void FakeDemuxerStream::DoRead() {
121 DCHECK(message_loop_->BelongsToCurrentThread());
122 DCHECK(!read_cb_.is_null());
126 if (num_buffers_left_in_current_config_ == 0) {
128 if (num_configs_left_ == 0) {
129 base::ResetAndReturn(&read_cb_).Run(kOk,
130 DecoderBuffer::CreateEOSBuffer());
135 num_buffers_left_in_current_config_ = num_buffers_in_one_config_;
136 UpdateVideoDecoderConfig();
137 base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL);
141 scoped_refptr<DecoderBuffer> buffer = CreateFakeVideoBufferForTest(
142 video_decoder_config_, current_timestamp_, duration_);
144 // TODO(xhwang): Output out-of-order buffers if needed.
145 buffer->set_timestamp(current_timestamp_);
146 buffer->set_duration(duration_);
147 current_timestamp_ += duration_;
149 num_buffers_left_in_current_config_--;
150 if (num_buffers_left_in_current_config_ == 0)
153 num_buffers_returned_++;
154 base::ResetAndReturn(&read_cb_).Run(kOk, buffer);