OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/filters/fake_video_decoder.h" | 5 #include "media/filters/fake_video_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 } | 23 } |
24 | 24 |
25 FakeVideoDecoder::~FakeVideoDecoder() { | 25 FakeVideoDecoder::~FakeVideoDecoder() { |
26 DCHECK_EQ(state_, UNINITIALIZED); | 26 DCHECK_EQ(state_, UNINITIALIZED); |
27 } | 27 } |
28 | 28 |
29 void FakeVideoDecoder::Initialize(const VideoDecoderConfig& config, | 29 void FakeVideoDecoder::Initialize(const VideoDecoderConfig& config, |
30 const PipelineStatusCB& status_cb) { | 30 const PipelineStatusCB& status_cb) { |
31 DCHECK(message_loop_->BelongsToCurrentThread()); | 31 DCHECK(message_loop_->BelongsToCurrentThread()); |
32 DCHECK(config.IsValidConfig()); | 32 DCHECK(config.IsValidConfig()); |
33 DCHECK(read_cb_.IsNull()) << "No reinitialization during pending read."; | 33 DCHECK(decode_cb_.IsNull()) << "No reinitialization during pending decode."; |
34 DCHECK(reset_cb_.IsNull()) << "No reinitialization during pending reset."; | 34 DCHECK(reset_cb_.IsNull()) << "No reinitialization during pending reset."; |
35 | 35 |
36 weak_this_ = weak_factory_.GetWeakPtr(); | 36 weak_this_ = weak_factory_.GetWeakPtr(); |
37 | 37 |
38 current_config_ = config; | 38 current_config_ = config; |
39 init_cb_.SetCallback(BindToCurrentLoop(status_cb)); | 39 init_cb_.SetCallback(BindToCurrentLoop(status_cb)); |
40 | 40 |
41 if (!decoded_frames_.empty()) { | 41 if (!decoded_frames_.empty()) { |
42 DVLOG(1) << "Decoded frames dropped during reinitialization."; | 42 DVLOG(1) << "Decoded frames dropped during reinitialization."; |
43 decoded_frames_.clear(); | 43 decoded_frames_.clear(); |
44 } | 44 } |
45 | 45 |
46 state_ = NORMAL; | 46 state_ = NORMAL; |
47 init_cb_.RunOrHold(PIPELINE_OK); | 47 init_cb_.RunOrHold(PIPELINE_OK); |
48 } | 48 } |
49 | 49 |
50 void FakeVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, | 50 void FakeVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
51 const ReadCB& read_cb) { | 51 const DecodeCB& decode_cb) { |
52 DCHECK(message_loop_->BelongsToCurrentThread()); | 52 DCHECK(message_loop_->BelongsToCurrentThread()); |
53 DCHECK(read_cb_.IsNull()) << "Overlapping decodes are not supported."; | 53 DCHECK(decode_cb_.IsNull()) << "Overlapping decodes are not supported."; |
54 DCHECK(reset_cb_.IsNull()); | 54 DCHECK(reset_cb_.IsNull()); |
55 DCHECK_LE(decoded_frames_.size(), static_cast<size_t>(decoding_delay_)); | 55 DCHECK_LE(decoded_frames_.size(), static_cast<size_t>(decoding_delay_)); |
56 | 56 |
57 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); | 57 int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); |
58 read_cb_.SetCallback(BindToCurrentLoop(base::Bind( | 58 decode_cb_.SetCallback(BindToCurrentLoop(base::Bind( |
59 &FakeVideoDecoder::OnFrameDecoded, weak_this_, buffer_size, read_cb))); | 59 &FakeVideoDecoder::OnFrameDecoded, weak_this_, buffer_size, decode_cb))); |
60 | 60 |
61 if (buffer->end_of_stream() && decoded_frames_.empty()) { | 61 if (buffer->end_of_stream() && decoded_frames_.empty()) { |
62 read_cb_.RunOrHold(kOk, VideoFrame::CreateEmptyFrame()); | 62 decode_cb_.RunOrHold(kOk, VideoFrame::CreateEmptyFrame()); |
63 return; | 63 return; |
64 } | 64 } |
65 | 65 |
66 if (!buffer->end_of_stream()) { | 66 if (!buffer->end_of_stream()) { |
67 DCHECK(VerifyFakeVideoBufferForTest(buffer, current_config_)); | 67 DCHECK(VerifyFakeVideoBufferForTest(buffer, current_config_)); |
68 scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateColorFrame( | 68 scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateColorFrame( |
69 current_config_.coded_size(), 0, 0, 0, buffer->timestamp()); | 69 current_config_.coded_size(), 0, 0, 0, buffer->timestamp()); |
70 decoded_frames_.push_back(video_frame); | 70 decoded_frames_.push_back(video_frame); |
71 | 71 |
72 if (decoded_frames_.size() <= static_cast<size_t>(decoding_delay_)) { | 72 if (decoded_frames_.size() <= static_cast<size_t>(decoding_delay_)) { |
73 read_cb_.RunOrHold(kNotEnoughData, scoped_refptr<VideoFrame>()); | 73 decode_cb_.RunOrHold(kNotEnoughData, scoped_refptr<VideoFrame>()); |
74 return; | 74 return; |
75 } | 75 } |
76 } | 76 } |
77 | 77 |
78 scoped_refptr<VideoFrame> frame = decoded_frames_.front(); | 78 scoped_refptr<VideoFrame> frame = decoded_frames_.front(); |
79 decoded_frames_.pop_front(); | 79 decoded_frames_.pop_front(); |
80 read_cb_.RunOrHold(kOk, frame); | 80 decode_cb_.RunOrHold(kOk, frame); |
81 } | 81 } |
82 | 82 |
83 void FakeVideoDecoder::Reset(const base::Closure& closure) { | 83 void FakeVideoDecoder::Reset(const base::Closure& closure) { |
84 DCHECK(message_loop_->BelongsToCurrentThread()); | 84 DCHECK(message_loop_->BelongsToCurrentThread()); |
85 DCHECK(reset_cb_.IsNull()); | 85 DCHECK(reset_cb_.IsNull()); |
86 reset_cb_.SetCallback(BindToCurrentLoop(closure)); | 86 reset_cb_.SetCallback(BindToCurrentLoop(closure)); |
87 | 87 |
88 // Defer the reset if a read is pending. | 88 // Defer the reset if a decode is pending. |
89 if (!read_cb_.IsNull()) | 89 if (!decode_cb_.IsNull()) |
90 return; | 90 return; |
91 | 91 |
92 DoReset(); | 92 DoReset(); |
93 } | 93 } |
94 | 94 |
95 void FakeVideoDecoder::Stop(const base::Closure& closure) { | 95 void FakeVideoDecoder::Stop(const base::Closure& closure) { |
96 DCHECK(message_loop_->BelongsToCurrentThread()); | 96 DCHECK(message_loop_->BelongsToCurrentThread()); |
97 stop_cb_.SetCallback(BindToCurrentLoop(closure)); | 97 stop_cb_.SetCallback(BindToCurrentLoop(closure)); |
98 | 98 |
99 // Defer the stop if an init, a read or a reset is pending. | 99 // Defer the stop if an init, a decode or a reset is pending. |
100 if (!init_cb_.IsNull() || !read_cb_.IsNull() || !reset_cb_.IsNull()) | 100 if (!init_cb_.IsNull() || !decode_cb_.IsNull() || !reset_cb_.IsNull()) |
101 return; | 101 return; |
102 | 102 |
103 DoStop(); | 103 DoStop(); |
104 } | 104 } |
105 | 105 |
106 void FakeVideoDecoder::HoldNextInit() { | 106 void FakeVideoDecoder::HoldNextInit() { |
107 DCHECK(message_loop_->BelongsToCurrentThread()); | 107 DCHECK(message_loop_->BelongsToCurrentThread()); |
108 init_cb_.HoldCallback(); | 108 init_cb_.HoldCallback(); |
109 } | 109 } |
110 | 110 |
111 void FakeVideoDecoder::HoldNextRead() { | 111 void FakeVideoDecoder::HoldNextRead() { |
112 DCHECK(message_loop_->BelongsToCurrentThread()); | 112 DCHECK(message_loop_->BelongsToCurrentThread()); |
113 read_cb_.HoldCallback(); | 113 decode_cb_.HoldCallback(); |
114 } | 114 } |
115 | 115 |
116 void FakeVideoDecoder::HoldNextReset() { | 116 void FakeVideoDecoder::HoldNextReset() { |
117 DCHECK(message_loop_->BelongsToCurrentThread()); | 117 DCHECK(message_loop_->BelongsToCurrentThread()); |
118 reset_cb_.HoldCallback(); | 118 reset_cb_.HoldCallback(); |
119 } | 119 } |
120 | 120 |
121 void FakeVideoDecoder::HoldNextStop() { | 121 void FakeVideoDecoder::HoldNextStop() { |
122 DCHECK(message_loop_->BelongsToCurrentThread()); | 122 DCHECK(message_loop_->BelongsToCurrentThread()); |
123 stop_cb_.HoldCallback(); | 123 stop_cb_.HoldCallback(); |
124 } | 124 } |
125 | 125 |
126 void FakeVideoDecoder::SatisfyInit() { | 126 void FakeVideoDecoder::SatisfyInit() { |
127 DCHECK(message_loop_->BelongsToCurrentThread()); | 127 DCHECK(message_loop_->BelongsToCurrentThread()); |
128 DCHECK(read_cb_.IsNull()); | 128 DCHECK(decode_cb_.IsNull()); |
129 DCHECK(reset_cb_.IsNull()); | 129 DCHECK(reset_cb_.IsNull()); |
130 | 130 |
131 init_cb_.RunHeldCallback(); | 131 init_cb_.RunHeldCallback(); |
132 | 132 |
133 if (!stop_cb_.IsNull()) | 133 if (!stop_cb_.IsNull()) |
134 DoStop(); | 134 DoStop(); |
135 } | 135 } |
136 | 136 |
137 void FakeVideoDecoder::SatisfyRead() { | 137 void FakeVideoDecoder::SatisfyRead() { |
138 DCHECK(message_loop_->BelongsToCurrentThread()); | 138 DCHECK(message_loop_->BelongsToCurrentThread()); |
139 read_cb_.RunHeldCallback(); | 139 decode_cb_.RunHeldCallback(); |
140 | 140 |
141 if (!reset_cb_.IsNull()) | 141 if (!reset_cb_.IsNull()) |
142 DoReset(); | 142 DoReset(); |
143 | 143 |
144 if (reset_cb_.IsNull() && !stop_cb_.IsNull()) | 144 if (reset_cb_.IsNull() && !stop_cb_.IsNull()) |
145 DoStop(); | 145 DoStop(); |
146 } | 146 } |
147 | 147 |
148 void FakeVideoDecoder::SatisfyReset() { | 148 void FakeVideoDecoder::SatisfyReset() { |
149 DCHECK(message_loop_->BelongsToCurrentThread()); | 149 DCHECK(message_loop_->BelongsToCurrentThread()); |
150 DCHECK(read_cb_.IsNull()); | 150 DCHECK(decode_cb_.IsNull()); |
151 reset_cb_.RunHeldCallback(); | 151 reset_cb_.RunHeldCallback(); |
152 | 152 |
153 if (!stop_cb_.IsNull()) | 153 if (!stop_cb_.IsNull()) |
154 DoStop(); | 154 DoStop(); |
155 } | 155 } |
156 | 156 |
157 void FakeVideoDecoder::SatisfyStop() { | 157 void FakeVideoDecoder::SatisfyStop() { |
158 DCHECK(message_loop_->BelongsToCurrentThread()); | 158 DCHECK(message_loop_->BelongsToCurrentThread()); |
159 DCHECK(read_cb_.IsNull()); | 159 DCHECK(decode_cb_.IsNull()); |
160 DCHECK(reset_cb_.IsNull()); | 160 DCHECK(reset_cb_.IsNull()); |
161 stop_cb_.RunHeldCallback(); | 161 stop_cb_.RunHeldCallback(); |
162 } | 162 } |
163 | 163 |
164 void FakeVideoDecoder::DoReset() { | 164 void FakeVideoDecoder::DoReset() { |
165 DCHECK(message_loop_->BelongsToCurrentThread()); | 165 DCHECK(message_loop_->BelongsToCurrentThread()); |
166 DCHECK(read_cb_.IsNull()); | 166 DCHECK(decode_cb_.IsNull()); |
167 DCHECK(!reset_cb_.IsNull()); | 167 DCHECK(!reset_cb_.IsNull()); |
168 | 168 |
169 decoded_frames_.clear(); | 169 decoded_frames_.clear(); |
170 reset_cb_.RunOrHold(); | 170 reset_cb_.RunOrHold(); |
171 } | 171 } |
172 | 172 |
173 void FakeVideoDecoder::DoStop() { | 173 void FakeVideoDecoder::DoStop() { |
174 DCHECK(message_loop_->BelongsToCurrentThread()); | 174 DCHECK(message_loop_->BelongsToCurrentThread()); |
175 DCHECK(read_cb_.IsNull()); | 175 DCHECK(decode_cb_.IsNull()); |
176 DCHECK(reset_cb_.IsNull()); | 176 DCHECK(reset_cb_.IsNull()); |
177 DCHECK(!stop_cb_.IsNull()); | 177 DCHECK(!stop_cb_.IsNull()); |
178 | 178 |
179 state_ = UNINITIALIZED; | 179 state_ = UNINITIALIZED; |
180 decoded_frames_.clear(); | 180 decoded_frames_.clear(); |
181 stop_cb_.RunOrHold(); | 181 stop_cb_.RunOrHold(); |
182 } | 182 } |
183 | 183 |
184 void FakeVideoDecoder::OnFrameDecoded( | 184 void FakeVideoDecoder::OnFrameDecoded( |
185 int buffer_size, | 185 int buffer_size, |
186 const ReadCB& read_cb, | 186 const DecodeCB& decode_cb, |
187 Status status, | 187 Status status, |
188 const scoped_refptr<VideoFrame>& video_frame) { | 188 const scoped_refptr<VideoFrame>& video_frame) { |
189 if (status == kOk || status == kNotEnoughData) | 189 if (status == kOk || status == kNotEnoughData) |
190 total_bytes_decoded_ += buffer_size; | 190 total_bytes_decoded_ += buffer_size; |
191 read_cb.Run(status, video_frame); | 191 decode_cb.Run(status, video_frame); |
192 } | 192 } |
193 | 193 |
194 } // namespace media | 194 } // namespace media |
OLD | NEW |