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_proxy.h"
12 #include "media/base/bind_to_current_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 const int kStartTimestampMs = 0;
22 const int kDurationMs = 30;
23 const int kStartWidth = 320;
24 const int kStartHeight = 240;
25 const int kWidthDelta = 4;
26 const int kHeightDelta = 3;
27 const uint8 kKeyId[] = { 0x00, 0x01, 0x02, 0x03 };
29 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
33 FakeDemuxerStream::FakeDemuxerStream(int num_configs,
34 int num_buffers_in_one_config,
36 : task_runner_(base::MessageLoopProxy::current()),
37 num_configs_left_(num_configs),
38 num_buffers_in_one_config_(num_buffers_in_one_config),
39 config_changes_(num_configs > 1),
40 is_encrypted_(is_encrypted),
41 num_buffers_left_in_current_config_(num_buffers_in_one_config),
42 num_buffers_returned_(0),
43 current_timestamp_(base::TimeDelta::FromMilliseconds(kStartTimestampMs)),
44 duration_(base::TimeDelta::FromMilliseconds(kDurationMs)),
45 next_coded_size_(kStartWidth, kStartHeight),
48 DCHECK_GT(num_configs_left_, 0);
49 DCHECK_GT(num_buffers_in_one_config_, 0);
50 UpdateVideoDecoderConfig();
53 FakeDemuxerStream::~FakeDemuxerStream() {}
55 void FakeDemuxerStream::Read(const ReadCB& read_cb) {
56 DCHECK(task_runner_->BelongsToCurrentThread());
57 DCHECK(read_cb_.is_null());
59 read_cb_ = BindToCurrentLoop(read_cb);
61 if (read_to_hold_ == next_read_num_)
64 DCHECK(read_to_hold_ == -1 || read_to_hold_ > next_read_num_);
68 AudioDecoderConfig FakeDemuxerStream::audio_decoder_config() {
69 DCHECK(task_runner_->BelongsToCurrentThread());
71 return AudioDecoderConfig();
74 VideoDecoderConfig FakeDemuxerStream::video_decoder_config() {
75 DCHECK(task_runner_->BelongsToCurrentThread());
76 return video_decoder_config_;
79 // TODO(xhwang): Support audio if needed.
80 DemuxerStream::Type FakeDemuxerStream::type() {
81 DCHECK(task_runner_->BelongsToCurrentThread());
85 void FakeDemuxerStream::EnableBitstreamConverter() {
86 DCHECK(task_runner_->BelongsToCurrentThread());
89 bool FakeDemuxerStream::SupportsConfigChanges() {
90 return config_changes_;
93 void FakeDemuxerStream::HoldNextRead() {
94 DCHECK(task_runner_->BelongsToCurrentThread());
95 read_to_hold_ = next_read_num_;
98 void FakeDemuxerStream::HoldNextConfigChangeRead() {
99 DCHECK(task_runner_->BelongsToCurrentThread());
100 // Set |read_to_hold_| to be the next config change read.
101 read_to_hold_ = next_read_num_ + num_buffers_in_one_config_ -
102 next_read_num_ % (num_buffers_in_one_config_ + 1);
105 void FakeDemuxerStream::SatisfyRead() {
106 DCHECK(task_runner_->BelongsToCurrentThread());
107 DCHECK_EQ(read_to_hold_, next_read_num_);
108 DCHECK(!read_cb_.is_null());
114 void FakeDemuxerStream::SatisfyReadAndHoldNext() {
115 DCHECK(task_runner_->BelongsToCurrentThread());
116 DCHECK_EQ(read_to_hold_, next_read_num_);
117 DCHECK(!read_cb_.is_null());
123 void FakeDemuxerStream::Reset() {
126 if (!read_cb_.is_null())
127 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
130 void FakeDemuxerStream::UpdateVideoDecoderConfig() {
131 const gfx::Rect kVisibleRect(kStartWidth, kStartHeight);
132 video_decoder_config_.Initialize(
133 kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, VideoFrame::YV12,
134 next_coded_size_, kVisibleRect, next_coded_size_,
135 NULL, 0, is_encrypted_, false);
136 next_coded_size_.Enlarge(kWidthDelta, kHeightDelta);
139 void FakeDemuxerStream::DoRead() {
140 DCHECK(task_runner_->BelongsToCurrentThread());
141 DCHECK(!read_cb_.is_null());
145 if (num_buffers_left_in_current_config_ == 0) {
147 if (num_configs_left_ == 0) {
148 base::ResetAndReturn(&read_cb_).Run(kOk,
149 DecoderBuffer::CreateEOSBuffer());
154 num_buffers_left_in_current_config_ = num_buffers_in_one_config_;
155 UpdateVideoDecoderConfig();
156 base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL);
160 scoped_refptr<DecoderBuffer> buffer = CreateFakeVideoBufferForTest(
161 video_decoder_config_, current_timestamp_, duration_);
163 // TODO(xhwang): Output out-of-order buffers if needed.
165 buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(
166 new DecryptConfig(std::string(kKeyId, kKeyId + arraysize(kKeyId)),
167 std::string(kIv, kIv + arraysize(kIv)),
168 std::vector<SubsampleEntry>())));
170 buffer->set_timestamp(current_timestamp_);
171 buffer->set_duration(duration_);
172 current_timestamp_ += duration_;
174 num_buffers_left_in_current_config_--;
175 if (num_buffers_left_in_current_config_ == 0)
178 num_buffers_returned_++;
179 base::ResetAndReturn(&read_cb_).Run(kOk, buffer);