Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(977)

Side by Side Diff: media/filters/fake_video_decoder.cc

Issue 16274005: Separate DemuxerStream and VideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win64 Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/fake_video_decoder.h ('k') | media/filters/fake_video_decoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "media/base/bind_to_loop.h" 11 #include "media/base/bind_to_loop.h"
12 #include "media/base/demuxer_stream.h" 12 #include "media/base/test_helpers.h"
13 13
14 namespace media { 14 namespace media {
15 15
16 FakeVideoDecoder::FakeVideoDecoder(int decoding_delay) 16 FakeVideoDecoder::FakeVideoDecoder(int decoding_delay)
17 : message_loop_(base::MessageLoopProxy::current()), 17 : message_loop_(base::MessageLoopProxy::current()),
18 weak_factory_(this), 18 weak_factory_(this),
19 decoding_delay_(decoding_delay), 19 decoding_delay_(decoding_delay),
20 state_(UNINITIALIZED), 20 state_(UNINITIALIZED) {
21 demuxer_stream_(NULL) {
22 DCHECK_GE(decoding_delay, 0); 21 DCHECK_GE(decoding_delay, 0);
23 } 22 }
24 23
25 FakeVideoDecoder::~FakeVideoDecoder() { 24 FakeVideoDecoder::~FakeVideoDecoder() {
26 DCHECK_EQ(state_, UNINITIALIZED); 25 DCHECK_EQ(state_, UNINITIALIZED);
27 } 26 }
28 27
29 void FakeVideoDecoder::Initialize(DemuxerStream* stream, 28 void FakeVideoDecoder::Initialize(const VideoDecoderConfig& config,
30 const PipelineStatusCB& status_cb, 29 const PipelineStatusCB& status_cb,
31 const StatisticsCB& statistics_cb) { 30 const StatisticsCB& statistics_cb) {
32 DCHECK(message_loop_->BelongsToCurrentThread()); 31 DCHECK(message_loop_->BelongsToCurrentThread());
33 DCHECK(stream); 32 DCHECK(config.IsValidConfig());
34 DCHECK(stream->video_decoder_config().IsValidConfig());
35 DCHECK(read_cb_.IsNull()) << "No reinitialization during pending read."; 33 DCHECK(read_cb_.IsNull()) << "No reinitialization during pending read.";
36 DCHECK(reset_cb_.IsNull()) << "No reinitialization during pending reset."; 34 DCHECK(reset_cb_.IsNull()) << "No reinitialization during pending reset.";
37 35
38 weak_this_ = weak_factory_.GetWeakPtr(); 36 weak_this_ = weak_factory_.GetWeakPtr();
39 37
40 demuxer_stream_ = stream;
41 statistics_cb_ = statistics_cb; 38 statistics_cb_ = statistics_cb;
42 current_config_ = stream->video_decoder_config(); 39 current_config_ = config;
43 init_cb_.SetCallback(BindToCurrentLoop(status_cb)); 40 init_cb_.SetCallback(BindToCurrentLoop(status_cb));
44 41
45 if (!decoded_frames_.empty()) { 42 if (!decoded_frames_.empty()) {
46 DVLOG(1) << "Decoded frames dropped during reinitialization."; 43 DVLOG(1) << "Decoded frames dropped during reinitialization.";
47 decoded_frames_.clear(); 44 decoded_frames_.clear();
48 } 45 }
49 46
50 state_ = NORMAL; 47 state_ = NORMAL;
51 init_cb_.RunOrHold(PIPELINE_OK); 48 init_cb_.RunOrHold(PIPELINE_OK);
52 } 49 }
53 50
54 void FakeVideoDecoder::Read(const ReadCB& read_cb) { 51 void FakeVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
52 const ReadCB& read_cb) {
55 DCHECK(message_loop_->BelongsToCurrentThread()); 53 DCHECK(message_loop_->BelongsToCurrentThread());
56 DCHECK(read_cb_.IsNull()) << "Overlapping decodes are not supported."; 54 DCHECK(read_cb_.IsNull()) << "Overlapping decodes are not supported.";
57 DCHECK(reset_cb_.IsNull()); 55 DCHECK(reset_cb_.IsNull());
58 DCHECK_LE(decoded_frames_.size(), static_cast<size_t>(decoding_delay_)); 56 DCHECK_LE(decoded_frames_.size(), static_cast<size_t>(decoding_delay_));
59 57
60 read_cb_.SetCallback(BindToCurrentLoop(read_cb)); 58 read_cb_.SetCallback(BindToCurrentLoop(read_cb));
61 ReadFromDemuxerStream(); 59
60 if (buffer->IsEndOfStream() && decoded_frames_.empty()) {
61 read_cb_.RunOrHold(kOk, VideoFrame::CreateEmptyFrame());
62 return;
63 }
64
65 if (!buffer->IsEndOfStream()) {
66 DCHECK(VerifyFakeVideoBufferForTest(buffer, current_config_));
67 scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateColorFrame(
68 current_config_.coded_size(), 0, 0, 0, buffer->GetTimestamp());
69 decoded_frames_.push_back(video_frame);
70
71 if (decoded_frames_.size() <= static_cast<size_t>(decoding_delay_)) {
72 read_cb_.RunOrHold(kNotEnoughData, scoped_refptr<VideoFrame>());
73 return;
74 }
75 }
76
77 scoped_refptr<VideoFrame> frame = decoded_frames_.front();
78 decoded_frames_.pop_front();
79 read_cb_.RunOrHold(kOk, frame);
62 } 80 }
63 81
64 void FakeVideoDecoder::Reset(const base::Closure& closure) { 82 void FakeVideoDecoder::Reset(const base::Closure& closure) {
65 DCHECK(message_loop_->BelongsToCurrentThread()); 83 DCHECK(message_loop_->BelongsToCurrentThread());
66 DCHECK(reset_cb_.IsNull()); 84 DCHECK(reset_cb_.IsNull());
67 reset_cb_.SetCallback(BindToCurrentLoop(closure)); 85 reset_cb_.SetCallback(BindToCurrentLoop(closure));
68 86
69 // Defer the reset if a read is pending. 87 // Defer the reset if a read is pending.
70 if (!read_cb_.IsNull()) 88 if (!read_cb_.IsNull())
71 return; 89 return;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 DoStop(); 153 DoStop();
136 } 154 }
137 155
138 void FakeVideoDecoder::SatisfyStop() { 156 void FakeVideoDecoder::SatisfyStop() {
139 DCHECK(message_loop_->BelongsToCurrentThread()); 157 DCHECK(message_loop_->BelongsToCurrentThread());
140 DCHECK(read_cb_.IsNull()); 158 DCHECK(read_cb_.IsNull());
141 DCHECK(reset_cb_.IsNull()); 159 DCHECK(reset_cb_.IsNull());
142 stop_cb_.RunHeldCallback(); 160 stop_cb_.RunHeldCallback();
143 } 161 }
144 162
145 void FakeVideoDecoder::ReadFromDemuxerStream() {
146 DCHECK_EQ(state_, NORMAL);
147 DCHECK(!read_cb_.IsNull());
148 demuxer_stream_->Read(base::Bind(&FakeVideoDecoder::BufferReady, weak_this_));
149 }
150
151 void FakeVideoDecoder::BufferReady(DemuxerStream::Status status,
152 const scoped_refptr<DecoderBuffer>& buffer) {
153 DCHECK(message_loop_->BelongsToCurrentThread());
154 DCHECK_EQ(state_, NORMAL);
155 DCHECK(!read_cb_.IsNull());
156 DCHECK_EQ(status != DemuxerStream::kOk, !buffer.get()) << status;
157
158 if (!stop_cb_.IsNull()) {
159 read_cb_.RunOrHold(kOk, scoped_refptr<VideoFrame>());
160 if (!reset_cb_.IsNull()) {
161 DoReset();
162 }
163 DoStop();
164 return;
165 }
166
167 if (status == DemuxerStream::kConfigChanged) {
168 DCHECK(demuxer_stream_->video_decoder_config().IsValidConfig());
169 current_config_ = demuxer_stream_->video_decoder_config();
170
171 if (reset_cb_.IsNull()) {
172 ReadFromDemuxerStream();
173 return;
174 }
175 }
176
177 if (!reset_cb_.IsNull()) {
178 read_cb_.RunOrHold(kOk, scoped_refptr<VideoFrame>());
179 DoReset();
180 return;
181 }
182
183 if (status == DemuxerStream::kAborted) {
184 read_cb_.RunOrHold(kOk, scoped_refptr<VideoFrame>());
185 return;
186 }
187
188 DCHECK_EQ(status, DemuxerStream::kOk);
189
190 if (buffer->IsEndOfStream() && decoded_frames_.empty()) {
191 read_cb_.RunOrHold(kOk, VideoFrame::CreateEmptyFrame());
192 return;
193 }
194
195 if (!buffer->IsEndOfStream()) {
196 // Make sure the decoder is always configured with the latest config.
197 DCHECK(current_config_.Matches(demuxer_stream_->video_decoder_config()))
198 << "Decoder's Current Config: "
199 << current_config_.AsHumanReadableString()
200 << "DemuxerStream's Current Config: "
201 << demuxer_stream_->video_decoder_config().AsHumanReadableString();
202
203 scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateColorFrame(
204 current_config_.coded_size(), 0, 0, 0, buffer->GetTimestamp());
205 decoded_frames_.push_back(video_frame);
206
207 if (decoded_frames_.size() <= static_cast<size_t>(decoding_delay_)) {
208 ReadFromDemuxerStream();
209 return;
210 }
211 }
212
213 scoped_refptr<VideoFrame> frame = decoded_frames_.front();
214 decoded_frames_.pop_front();
215 read_cb_.RunOrHold(kOk, frame);
216 }
217
218 void FakeVideoDecoder::DoReset() { 163 void FakeVideoDecoder::DoReset() {
219 DCHECK(message_loop_->BelongsToCurrentThread()); 164 DCHECK(message_loop_->BelongsToCurrentThread());
220 DCHECK(read_cb_.IsNull()); 165 DCHECK(read_cb_.IsNull());
221 DCHECK(!reset_cb_.IsNull()); 166 DCHECK(!reset_cb_.IsNull());
222 167
223 decoded_frames_.clear(); 168 decoded_frames_.clear();
224 reset_cb_.RunOrHold(); 169 reset_cb_.RunOrHold();
225 } 170 }
226 171
227 void FakeVideoDecoder::DoStop() { 172 void FakeVideoDecoder::DoStop() {
228 DCHECK(message_loop_->BelongsToCurrentThread()); 173 DCHECK(message_loop_->BelongsToCurrentThread());
229 DCHECK(read_cb_.IsNull()); 174 DCHECK(read_cb_.IsNull());
230 DCHECK(reset_cb_.IsNull()); 175 DCHECK(reset_cb_.IsNull());
231 DCHECK(!stop_cb_.IsNull()); 176 DCHECK(!stop_cb_.IsNull());
232 177
233 state_ = UNINITIALIZED; 178 state_ = UNINITIALIZED;
234 demuxer_stream_ = NULL;
235 decoded_frames_.clear(); 179 decoded_frames_.clear();
236 stop_cb_.RunOrHold(); 180 stop_cb_.RunOrHold();
237 } 181 }
238 182
239 } // namespace media 183 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/fake_video_decoder.h ('k') | media/filters/fake_video_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698