Restore simple fling status bookkeeping
[chromium-blink-merge.git] / media / filters / fake_demuxer_stream.cc
blob15748d5ce46923253bf28988f203ce7daa5e8ea9
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"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "media/base/bind_to_current_loop.h"
14 #include "media/base/decoder_buffer.h"
15 #include "media/base/test_helpers.h"
16 #include "media/base/video_frame.h"
17 #include "ui/gfx/geometry/rect.h"
18 #include "ui/gfx/geometry/size.h"
20 namespace media {
22 const int kStartTimestampMs = 0;
23 const int kDurationMs = 30;
24 const int kStartWidth = 320;
25 const int kStartHeight = 240;
26 const int kWidthDelta = 4;
27 const int kHeightDelta = 3;
28 const uint8 kKeyId[] = { 0x00, 0x01, 0x02, 0x03 };
29 const uint8 kIv[] = {
30 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
34 FakeDemuxerStream::FakeDemuxerStream(int num_configs,
35 int num_buffers_in_one_config,
36 bool is_encrypted)
37 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
38 num_configs_(num_configs),
39 num_buffers_in_one_config_(num_buffers_in_one_config),
40 config_changes_(num_configs > 1),
41 is_encrypted_(is_encrypted),
42 read_to_hold_(-1) {
43 DCHECK_GT(num_configs, 0);
44 DCHECK_GT(num_buffers_in_one_config, 0);
45 Initialize();
46 UpdateVideoDecoderConfig();
49 FakeDemuxerStream::~FakeDemuxerStream() {}
51 void FakeDemuxerStream::Initialize() {
52 DCHECK_EQ(-1, read_to_hold_);
53 num_configs_left_ = num_configs_;
54 num_buffers_left_in_current_config_ = num_buffers_in_one_config_;
55 num_buffers_returned_ = 0;
56 current_timestamp_ = base::TimeDelta::FromMilliseconds(kStartTimestampMs);
57 duration_ = base::TimeDelta::FromMilliseconds(kDurationMs);
58 splice_timestamp_ = kNoTimestamp();
59 next_coded_size_ = gfx::Size(kStartWidth, kStartHeight);
60 next_read_num_ = 0;
63 void FakeDemuxerStream::Read(const ReadCB& read_cb) {
64 DCHECK(task_runner_->BelongsToCurrentThread());
65 DCHECK(read_cb_.is_null());
67 read_cb_ = BindToCurrentLoop(read_cb);
69 if (read_to_hold_ == next_read_num_)
70 return;
72 DCHECK(read_to_hold_ == -1 || read_to_hold_ > next_read_num_);
73 DoRead();
76 AudioDecoderConfig FakeDemuxerStream::audio_decoder_config() {
77 DCHECK(task_runner_->BelongsToCurrentThread());
78 NOTREACHED();
79 return AudioDecoderConfig();
82 VideoDecoderConfig FakeDemuxerStream::video_decoder_config() {
83 DCHECK(task_runner_->BelongsToCurrentThread());
84 return video_decoder_config_;
87 // TODO(xhwang): Support audio if needed.
88 DemuxerStream::Type FakeDemuxerStream::type() const {
89 DCHECK(task_runner_->BelongsToCurrentThread());
90 return VIDEO;
93 bool FakeDemuxerStream::SupportsConfigChanges() {
94 return config_changes_;
97 VideoRotation FakeDemuxerStream::video_rotation() {
98 return VIDEO_ROTATION_0;
101 void FakeDemuxerStream::HoldNextRead() {
102 DCHECK(task_runner_->BelongsToCurrentThread());
103 read_to_hold_ = next_read_num_;
106 void FakeDemuxerStream::HoldNextConfigChangeRead() {
107 DCHECK(task_runner_->BelongsToCurrentThread());
108 // Set |read_to_hold_| to be the next config change read.
109 read_to_hold_ = next_read_num_ + num_buffers_in_one_config_ -
110 next_read_num_ % (num_buffers_in_one_config_ + 1);
113 void FakeDemuxerStream::SatisfyRead() {
114 DCHECK(task_runner_->BelongsToCurrentThread());
115 DCHECK_EQ(read_to_hold_, next_read_num_);
116 DCHECK(!read_cb_.is_null());
118 read_to_hold_ = -1;
119 DoRead();
122 void FakeDemuxerStream::SatisfyReadAndHoldNext() {
123 DCHECK(task_runner_->BelongsToCurrentThread());
124 DCHECK_EQ(read_to_hold_, next_read_num_);
125 DCHECK(!read_cb_.is_null());
127 ++read_to_hold_;
128 DoRead();
131 void FakeDemuxerStream::Reset() {
132 read_to_hold_ = -1;
134 if (!read_cb_.is_null())
135 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
138 void FakeDemuxerStream::SeekToStart() {
139 Reset();
140 Initialize();
143 void FakeDemuxerStream::UpdateVideoDecoderConfig() {
144 const gfx::Rect kVisibleRect(kStartWidth, kStartHeight);
145 video_decoder_config_.Initialize(
146 kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, VideoFrame::YV12,
147 next_coded_size_, kVisibleRect, next_coded_size_,
148 NULL, 0, is_encrypted_, false);
149 next_coded_size_.Enlarge(kWidthDelta, kHeightDelta);
152 void FakeDemuxerStream::DoRead() {
153 DCHECK(task_runner_->BelongsToCurrentThread());
154 DCHECK(!read_cb_.is_null());
156 next_read_num_++;
158 if (num_buffers_left_in_current_config_ == 0) {
159 // End of stream.
160 if (num_configs_left_ == 0) {
161 base::ResetAndReturn(&read_cb_).Run(kOk,
162 DecoderBuffer::CreateEOSBuffer());
163 return;
166 // Config change.
167 num_buffers_left_in_current_config_ = num_buffers_in_one_config_;
168 UpdateVideoDecoderConfig();
169 base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL);
170 return;
173 scoped_refptr<DecoderBuffer> buffer = CreateFakeVideoBufferForTest(
174 video_decoder_config_, current_timestamp_, duration_);
176 // TODO(xhwang): Output out-of-order buffers if needed.
177 if (is_encrypted_) {
178 buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(
179 new DecryptConfig(std::string(kKeyId, kKeyId + arraysize(kKeyId)),
180 std::string(kIv, kIv + arraysize(kIv)),
181 std::vector<SubsampleEntry>())));
183 buffer->set_timestamp(current_timestamp_);
184 buffer->set_duration(duration_);
185 buffer->set_splice_timestamp(splice_timestamp_);
186 current_timestamp_ += duration_;
188 num_buffers_left_in_current_config_--;
189 if (num_buffers_left_in_current_config_ == 0)
190 num_configs_left_--;
192 num_buffers_returned_++;
193 base::ResetAndReturn(&read_cb_).Run(kOk, buffer);
196 } // namespace media