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 is_encrypted_(is_encrypted
),
40 num_buffers_left_in_current_config_(num_buffers_in_one_config
),
41 num_buffers_returned_(0),
42 current_timestamp_(base::TimeDelta::FromMilliseconds(kStartTimestampMs
)),
43 duration_(base::TimeDelta::FromMilliseconds(kDurationMs
)),
44 next_coded_size_(kStartWidth
, kStartHeight
),
47 DCHECK_GT(num_configs_left_
, 0);
48 DCHECK_GT(num_buffers_in_one_config_
, 0);
49 UpdateVideoDecoderConfig();
52 FakeDemuxerStream::~FakeDemuxerStream() {}
54 void FakeDemuxerStream::Read(const ReadCB
& read_cb
) {
55 DCHECK(task_runner_
->BelongsToCurrentThread());
56 DCHECK(read_cb_
.is_null());
58 read_cb_
= BindToCurrentLoop(read_cb
);
60 if (read_to_hold_
== next_read_num_
)
63 DCHECK(read_to_hold_
== -1 || read_to_hold_
> next_read_num_
);
67 AudioDecoderConfig
FakeDemuxerStream::audio_decoder_config() {
68 DCHECK(task_runner_
->BelongsToCurrentThread());
70 return AudioDecoderConfig();
73 VideoDecoderConfig
FakeDemuxerStream::video_decoder_config() {
74 DCHECK(task_runner_
->BelongsToCurrentThread());
75 return video_decoder_config_
;
78 // TODO(xhwang): Support audio if needed.
79 DemuxerStream::Type
FakeDemuxerStream::type() {
80 DCHECK(task_runner_
->BelongsToCurrentThread());
84 void FakeDemuxerStream::EnableBitstreamConverter() {
85 DCHECK(task_runner_
->BelongsToCurrentThread());
88 void FakeDemuxerStream::HoldNextRead() {
89 DCHECK(task_runner_
->BelongsToCurrentThread());
90 read_to_hold_
= next_read_num_
;
93 void FakeDemuxerStream::HoldNextConfigChangeRead() {
94 DCHECK(task_runner_
->BelongsToCurrentThread());
95 // Set |read_to_hold_| to be the next config change read.
96 read_to_hold_
= next_read_num_
+ num_buffers_in_one_config_
-
97 next_read_num_
% (num_buffers_in_one_config_
+ 1);
100 void FakeDemuxerStream::SatisfyRead() {
101 DCHECK(task_runner_
->BelongsToCurrentThread());
102 DCHECK_EQ(read_to_hold_
, next_read_num_
);
103 DCHECK(!read_cb_
.is_null());
109 void FakeDemuxerStream::Reset() {
112 if (!read_cb_
.is_null())
113 base::ResetAndReturn(&read_cb_
).Run(kAborted
, NULL
);
116 void FakeDemuxerStream::UpdateVideoDecoderConfig() {
117 const gfx::Rect
kVisibleRect(kStartWidth
, kStartHeight
);
118 video_decoder_config_
.Initialize(
119 kCodecVP8
, VIDEO_CODEC_PROFILE_UNKNOWN
, VideoFrame::YV12
,
120 next_coded_size_
, kVisibleRect
, next_coded_size_
,
121 NULL
, 0, is_encrypted_
, false);
122 next_coded_size_
.Enlarge(kWidthDelta
, kHeightDelta
);
125 void FakeDemuxerStream::DoRead() {
126 DCHECK(task_runner_
->BelongsToCurrentThread());
127 DCHECK(!read_cb_
.is_null());
131 if (num_buffers_left_in_current_config_
== 0) {
133 if (num_configs_left_
== 0) {
134 base::ResetAndReturn(&read_cb_
).Run(kOk
,
135 DecoderBuffer::CreateEOSBuffer());
140 num_buffers_left_in_current_config_
= num_buffers_in_one_config_
;
141 UpdateVideoDecoderConfig();
142 base::ResetAndReturn(&read_cb_
).Run(kConfigChanged
, NULL
);
146 scoped_refptr
<DecoderBuffer
> buffer
= CreateFakeVideoBufferForTest(
147 video_decoder_config_
, current_timestamp_
, duration_
);
149 // TODO(xhwang): Output out-of-order buffers if needed.
151 buffer
->set_decrypt_config(scoped_ptr
<DecryptConfig
>(
152 new DecryptConfig(std::string(kKeyId
, kKeyId
+ arraysize(kKeyId
)),
153 std::string(kIv
, kIv
+ arraysize(kIv
)),
154 std::vector
<SubsampleEntry
>())));
156 buffer
->set_timestamp(current_timestamp_
);
157 buffer
->set_duration(duration_
);
158 current_timestamp_
+= duration_
;
160 num_buffers_left_in_current_config_
--;
161 if (num_buffers_left_in_current_config_
== 0)
164 num_buffers_returned_
++;
165 base::ResetAndReturn(&read_cb_
).Run(kOk
, buffer
);