- add sources.
[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.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"
18
19 namespace media {
20
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;
27
28 FakeDemuxerStream::FakeDemuxerStream(int num_configs,
29                                      int num_buffers_in_one_config,
30                                      bool is_encrypted)
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),
40       next_read_num_(0),
41       read_to_hold_(-1) {
42   DCHECK_GT(num_configs_left_, 0);
43   DCHECK_GT(num_buffers_in_one_config_, 0);
44   UpdateVideoDecoderConfig();
45 }
46
47 FakeDemuxerStream::~FakeDemuxerStream() {}
48
49 void FakeDemuxerStream::Read(const ReadCB& read_cb) {
50   DCHECK(message_loop_->BelongsToCurrentThread());
51   DCHECK(read_cb_.is_null());
52
53   read_cb_ = BindToCurrentLoop(read_cb);
54
55   if (read_to_hold_ == next_read_num_)
56     return;
57
58   DCHECK(read_to_hold_ == -1 || read_to_hold_ > next_read_num_);
59   DoRead();
60 }
61
62 AudioDecoderConfig FakeDemuxerStream::audio_decoder_config() {
63   DCHECK(message_loop_->BelongsToCurrentThread());
64   NOTREACHED();
65   return AudioDecoderConfig();
66 }
67
68 VideoDecoderConfig FakeDemuxerStream::video_decoder_config() {
69   DCHECK(message_loop_->BelongsToCurrentThread());
70   return video_decoder_config_;
71 }
72
73 // TODO(xhwang): Support audio if needed.
74 DemuxerStream::Type FakeDemuxerStream::type() {
75   DCHECK(message_loop_->BelongsToCurrentThread());
76   return VIDEO;
77 }
78
79 void FakeDemuxerStream::EnableBitstreamConverter() {
80   DCHECK(message_loop_->BelongsToCurrentThread());
81 }
82
83 void FakeDemuxerStream::HoldNextRead() {
84   DCHECK(message_loop_->BelongsToCurrentThread());
85   read_to_hold_ = next_read_num_;
86 }
87
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);
93 }
94
95 void FakeDemuxerStream::SatisfyRead() {
96   DCHECK(message_loop_->BelongsToCurrentThread());
97   DCHECK_EQ(read_to_hold_, next_read_num_);
98   DCHECK(!read_cb_.is_null());
99
100   read_to_hold_ = -1;
101   DoRead();
102 }
103
104 void FakeDemuxerStream::Reset() {
105   read_to_hold_ = -1;
106
107   if (!read_cb_.is_null())
108     base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
109 }
110
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);
118 }
119
120 void FakeDemuxerStream::DoRead() {
121   DCHECK(message_loop_->BelongsToCurrentThread());
122   DCHECK(!read_cb_.is_null());
123
124   next_read_num_++;
125
126   if (num_buffers_left_in_current_config_ == 0) {
127     // End of stream.
128     if (num_configs_left_ == 0) {
129       base::ResetAndReturn(&read_cb_).Run(kOk,
130                                           DecoderBuffer::CreateEOSBuffer());
131       return;
132     }
133
134     // Config change.
135     num_buffers_left_in_current_config_ = num_buffers_in_one_config_;
136     UpdateVideoDecoderConfig();
137     base::ResetAndReturn(&read_cb_).Run(kConfigChanged, NULL);
138     return;
139   }
140
141   scoped_refptr<DecoderBuffer> buffer = CreateFakeVideoBufferForTest(
142       video_decoder_config_, current_timestamp_, duration_);
143
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_;
148
149   num_buffers_left_in_current_config_--;
150   if (num_buffers_left_in_current_config_ == 0)
151     num_configs_left_--;
152
153   num_buffers_returned_++;
154   base::ResetAndReturn(&read_cb_).Run(kOk, buffer);
155 }
156
157 }  // namespace media