Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / media / filters / fake_demuxer_stream.cc
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.
4
5 #include "media/filters/fake_demuxer_stream.h"
6
7 #include "base/bind.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"
18
19 namespace media {
20
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 };
28 const uint8 kIv[] = {
29   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
30   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
31 };
32
33 FakeDemuxerStream::FakeDemuxerStream(int num_configs,
34                                      int num_buffers_in_one_config,
35                                      bool is_encrypted)
36     : task_runner_(base::MessageLoopProxy::current()),
37       num_configs_(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       read_to_hold_(-1) {
42   DCHECK_GT(num_configs, 0);
43   DCHECK_GT(num_buffers_in_one_config, 0);
44   Initialize();
45   UpdateVideoDecoderConfig();
46 }
47
48 FakeDemuxerStream::~FakeDemuxerStream() {}
49
50 void FakeDemuxerStream::Initialize() {
51   DCHECK_EQ(-1, read_to_hold_);
52   num_configs_left_ = num_configs_;
53   num_buffers_left_in_current_config_ = num_buffers_in_one_config_;
54   num_buffers_returned_ = 0;
55   current_timestamp_ = base::TimeDelta::FromMilliseconds(kStartTimestampMs);
56   duration_ = base::TimeDelta::FromMilliseconds(kDurationMs);
57   splice_timestamp_ = kNoTimestamp();
58   next_coded_size_ = gfx::Size(kStartWidth, kStartHeight);
59   next_read_num_ = 0;
60 }
61
62 void FakeDemuxerStream::Read(const ReadCB& read_cb) {
63   DCHECK(task_runner_->BelongsToCurrentThread());
64   DCHECK(read_cb_.is_null());
65
66   read_cb_ = BindToCurrentLoop(read_cb);
67
68   if (read_to_hold_ == next_read_num_)
69     return;
70
71   DCHECK(read_to_hold_ == -1 || read_to_hold_ > next_read_num_);
72   DoRead();
73 }
74
75 AudioDecoderConfig FakeDemuxerStream::audio_decoder_config() {
76   DCHECK(task_runner_->BelongsToCurrentThread());
77   NOTREACHED();
78   return AudioDecoderConfig();
79 }
80
81 VideoDecoderConfig FakeDemuxerStream::video_decoder_config() {
82   DCHECK(task_runner_->BelongsToCurrentThread());
83   return video_decoder_config_;
84 }
85
86 // TODO(xhwang): Support audio if needed.
87 DemuxerStream::Type FakeDemuxerStream::type() {
88   DCHECK(task_runner_->BelongsToCurrentThread());
89   return VIDEO;
90 }
91
92 bool FakeDemuxerStream::SupportsConfigChanges() {
93   return config_changes_;
94 }
95
96 VideoRotation FakeDemuxerStream::video_rotation() {
97   return VIDEO_ROTATION_0;
98 }
99
100 void FakeDemuxerStream::HoldNextRead() {
101   DCHECK(task_runner_->BelongsToCurrentThread());
102   read_to_hold_ = next_read_num_;
103 }
104
105 void FakeDemuxerStream::HoldNextConfigChangeRead() {
106   DCHECK(task_runner_->BelongsToCurrentThread());
107   // Set |read_to_hold_| to be the next config change read.
108   read_to_hold_ = next_read_num_ + num_buffers_in_one_config_ -
109                   next_read_num_ % (num_buffers_in_one_config_ + 1);
110 }
111
112 void FakeDemuxerStream::SatisfyRead() {
113   DCHECK(task_runner_->BelongsToCurrentThread());
114   DCHECK_EQ(read_to_hold_, next_read_num_);
115   DCHECK(!read_cb_.is_null());
116
117   read_to_hold_ = -1;
118   DoRead();
119 }
120
121 void FakeDemuxerStream::SatisfyReadAndHoldNext() {
122   DCHECK(task_runner_->BelongsToCurrentThread());
123   DCHECK_EQ(read_to_hold_, next_read_num_);
124   DCHECK(!read_cb_.is_null());
125
126   ++read_to_hold_;
127   DoRead();
128 }
129
130 void FakeDemuxerStream::Reset() {
131   read_to_hold_ = -1;
132
133   if (!read_cb_.is_null())
134     base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
135 }
136
137 void FakeDemuxerStream::SeekToStart() {
138   Reset();
139   Initialize();
140 }
141
142 void FakeDemuxerStream::UpdateVideoDecoderConfig() {
143   const gfx::Rect kVisibleRect(kStartWidth, kStartHeight);
144   video_decoder_config_.Initialize(
145       kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, VideoFrame::YV12,
146       next_coded_size_, kVisibleRect, next_coded_size_,
147       NULL, 0, is_encrypted_, false);
148   next_coded_size_.Enlarge(kWidthDelta, kHeightDelta);
149 }
150
151 void FakeDemuxerStream::DoRead() {
152   DCHECK(task_runner_->BelongsToCurrentThread());
153   DCHECK(!read_cb_.is_null());
154
155   next_read_num_++;
156
157   if (num_buffers_left_in_current_config_ == 0) {
158     // End of stream.
159     if (num_configs_left_ == 0) {
160       base::ResetAndReturn(&read_cb_).Run(kOk,
161                                           DecoderBuffer::CreateEOSBuffer());
162       return;
163     }
164
165     // Config change.
166     num_buffers_left_in_current_config_ = num_buffers_in_one_config_;
167     UpdateVideoDecoderConfig();
168     base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL);
169     return;
170   }
171
172   scoped_refptr<DecoderBuffer> buffer = CreateFakeVideoBufferForTest(
173       video_decoder_config_, current_timestamp_, duration_);
174
175   // TODO(xhwang): Output out-of-order buffers if needed.
176   if (is_encrypted_) {
177     buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(
178         new DecryptConfig(std::string(kKeyId, kKeyId + arraysize(kKeyId)),
179                           std::string(kIv, kIv + arraysize(kIv)),
180                           std::vector<SubsampleEntry>())));
181   }
182   buffer->set_timestamp(current_timestamp_);
183   buffer->set_duration(duration_);
184   buffer->set_splice_timestamp(splice_timestamp_);
185   current_timestamp_ += duration_;
186
187   num_buffers_left_in_current_config_--;
188   if (num_buffers_left_in_current_config_ == 0)
189     num_configs_left_--;
190
191   num_buffers_returned_++;
192   base::ResetAndReturn(&read_cb_).Run(kOk, buffer);
193 }
194
195 }  // namespace media