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

Side by Side Diff: media/cast/test/fake_media_source.cc

Issue 892383002: RELAND: [Cast] Software encoder support for varying video frame sizes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix for 'access to uninitialized memory' error. Created 5 years, 10 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
« no previous file with comments | « media/cast/test/fake_media_source.h ('k') | media/cast/test/linux_output_window.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/cast/test/fake_media_source.h" 5 #include "media/cast/test/fake_media_source.h"
6 6
7 #include "base/files/memory_mapped_file.h" 7 #include "base/files/memory_mapped_file.h"
8 #include "base/files/scoped_file.h" 8 #include "base/files/scoped_file.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/rand_util.h"
10 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
11 #include "media/audio/audio_parameters.h" 12 #include "media/audio/audio_parameters.h"
12 #include "media/base/audio_buffer.h" 13 #include "media/base/audio_buffer.h"
13 #include "media/base/audio_bus.h" 14 #include "media/base/audio_bus.h"
14 #include "media/base/audio_fifo.h" 15 #include "media/base/audio_fifo.h"
15 #include "media/base/audio_timestamp_helper.h" 16 #include "media/base/audio_timestamp_helper.h"
16 #include "media/base/media.h" 17 #include "media/base/media.h"
17 #include "media/base/multi_channel_resampler.h" 18 #include "media/base/multi_channel_resampler.h"
18 #include "media/base/video_frame.h" 19 #include "media/base/video_frame.h"
19 #include "media/base/video_util.h" 20 #include "media/base/video_util.h"
20 #include "media/cast/cast_sender.h" 21 #include "media/cast/cast_sender.h"
21 #include "media/cast/test/utility/audio_utility.h" 22 #include "media/cast/test/utility/audio_utility.h"
22 #include "media/cast/test/utility/video_utility.h" 23 #include "media/cast/test/utility/video_utility.h"
23 #include "media/ffmpeg/ffmpeg_common.h" 24 #include "media/ffmpeg/ffmpeg_common.h"
24 #include "media/ffmpeg/ffmpeg_deleters.h" 25 #include "media/ffmpeg/ffmpeg_deleters.h"
25 #include "media/filters/audio_renderer_algorithm.h" 26 #include "media/filters/audio_renderer_algorithm.h"
26 #include "media/filters/ffmpeg_demuxer.h" 27 #include "media/filters/ffmpeg_demuxer.h"
27 #include "media/filters/ffmpeg_glue.h" 28 #include "media/filters/ffmpeg_glue.h"
28 #include "media/filters/in_memory_url_protocol.h" 29 #include "media/filters/in_memory_url_protocol.h"
29 #include "ui/gfx/geometry/size.h" 30 #include "ui/gfx/geometry/size.h"
30 31
31 namespace { 32 namespace {
32 33
33 static const int kAudioChannels = 2; 34 static const int kAudioChannels = 2;
34 static const int kAudioSamplingFrequency = 48000; 35 static const int kAudioSamplingFrequency = 48000;
35 static const int kSoundFrequency = 1234; // Frequency of sinusoid wave. 36 static const int kSoundFrequency = 440; // Frequency of sinusoid wave.
36 static const float kSoundVolume = 0.5f; 37 static const float kSoundVolume = 0.10f;
37 static const int kAudioFrameMs = 10; // Each audio frame is exactly 10ms. 38 static const int kAudioFrameMs = 10; // Each audio frame is exactly 10ms.
38 static const int kAudioPacketsPerSecond = 1000 / kAudioFrameMs; 39 static const int kAudioPacketsPerSecond = 1000 / kAudioFrameMs;
39 40
41 // Bounds for variable frame size mode.
42 static const int kMinFakeFrameWidth = 60;
43 static const int kMinFakeFrameHeight = 34;
44 static const int kStartingFakeFrameWidth = 854;
45 static const int kStartingFakeFrameHeight = 480;
46 static const int kMaxFakeFrameWidth = 1280;
47 static const int kMaxFakeFrameHeight = 720;
48 static const int kMaxFrameSizeChangeMillis = 5000;
49
40 void AVFreeFrame(AVFrame* frame) { 50 void AVFreeFrame(AVFrame* frame) {
41 av_frame_free(&frame); 51 av_frame_free(&frame);
42 } 52 }
43 53
44 base::TimeDelta PtsToTimeDelta(int64 pts, const AVRational& time_base) { 54 base::TimeDelta PtsToTimeDelta(int64 pts, const AVRational& time_base) {
45 return pts * base::TimeDelta::FromSeconds(1) * time_base.num / time_base.den; 55 return pts * base::TimeDelta::FromSeconds(1) * time_base.num / time_base.den;
46 } 56 }
47 57
48 int64 TimeDeltaToPts(base::TimeDelta delta, const AVRational& time_base) { 58 int64 TimeDeltaToPts(base::TimeDelta delta, const AVRational& time_base) {
49 return static_cast<int64>( 59 return static_cast<int64>(
50 delta.InSecondsF() * time_base.den / time_base.num + 60 delta.InSecondsF() * time_base.den / time_base.num +
51 0.5 /* rounding */); 61 0.5 /* rounding */);
52 } 62 }
53 63
54 } // namespace 64 } // namespace
55 65
56 namespace media { 66 namespace media {
57 namespace cast { 67 namespace cast {
58 68
59 FakeMediaSource::FakeMediaSource( 69 FakeMediaSource::FakeMediaSource(
60 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 70 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
61 base::TickClock* clock, 71 base::TickClock* clock,
62 const VideoSenderConfig& video_config, 72 const VideoSenderConfig& video_config,
63 bool keep_frames) 73 bool keep_frames)
64 : task_runner_(task_runner), 74 : task_runner_(task_runner),
65 video_config_(video_config), 75 video_config_(video_config),
66 keep_frames_(keep_frames), 76 keep_frames_(keep_frames),
77 variable_frame_size_mode_(false),
67 synthetic_count_(0), 78 synthetic_count_(0),
68 clock_(clock), 79 clock_(clock),
69 audio_frame_count_(0), 80 audio_frame_count_(0),
70 video_frame_count_(0), 81 video_frame_count_(0),
71 av_format_context_(NULL), 82 av_format_context_(NULL),
72 audio_stream_index_(-1), 83 audio_stream_index_(-1),
73 playback_rate_(1.0), 84 playback_rate_(1.0),
74 video_stream_index_(-1), 85 video_stream_index_(-1),
75 video_frame_rate_numerator_(video_config.max_frame_rate), 86 video_frame_rate_numerator_(video_config.max_frame_rate),
76 video_frame_rate_denominator_(1), 87 video_frame_rate_denominator_(1),
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 193 }
183 LOG(INFO) << "Source file has video."; 194 LOG(INFO) << "Source file has video.";
184 } else { 195 } else {
185 LOG(ERROR) << "Unknown stream type; ignore."; 196 LOG(ERROR) << "Unknown stream type; ignore.";
186 } 197 }
187 } 198 }
188 199
189 Rewind(); 200 Rewind();
190 } 201 }
191 202
203 void FakeMediaSource::SetVariableFrameSizeMode(bool enabled) {
204 variable_frame_size_mode_ = enabled;
205 }
206
192 void FakeMediaSource::Start(scoped_refptr<AudioFrameInput> audio_frame_input, 207 void FakeMediaSource::Start(scoped_refptr<AudioFrameInput> audio_frame_input,
193 scoped_refptr<VideoFrameInput> video_frame_input) { 208 scoped_refptr<VideoFrameInput> video_frame_input) {
194 audio_frame_input_ = audio_frame_input; 209 audio_frame_input_ = audio_frame_input;
195 video_frame_input_ = video_frame_input; 210 video_frame_input_ = video_frame_input;
196 211
197 LOG(INFO) << "Max Frame rate: " << video_config_.max_frame_rate; 212 LOG(INFO) << "Max Frame rate: " << video_config_.max_frame_rate;
198 LOG(INFO) << "Source Frame rate: " 213 LOG(INFO) << "Source Frame rate: "
199 << video_frame_rate_numerator_ << "/" 214 << video_frame_rate_numerator_ << "/"
200 << video_frame_rate_denominator_ << " fps."; 215 << video_frame_rate_denominator_ << " fps.";
201 LOG(INFO) << "Audio playback rate: " << playback_rate_; 216 LOG(INFO) << "Audio playback rate: " << playback_rate_;
202 217
203 if (start_time_.is_null()) 218 if (start_time_.is_null())
204 start_time_ = clock_->NowTicks(); 219 start_time_ = clock_->NowTicks();
205 220
206 if (!is_transcoding_audio() && !is_transcoding_video()) { 221 if (!is_transcoding_audio() && !is_transcoding_video()) {
207 // Send fake patterns. 222 // Send fake patterns.
208 task_runner_->PostTask( 223 task_runner_->PostTask(
209 FROM_HERE, 224 FROM_HERE,
210 base::Bind( 225 base::Bind(&FakeMediaSource::SendNextFakeFrame,
211 &FakeMediaSource::SendNextFakeFrame, 226 weak_factory_.GetWeakPtr()));
212 base::Unretained(this)));
213 return; 227 return;
214 } 228 }
215 229
216 // Send transcoding streams. 230 // Send transcoding streams.
217 audio_algo_.Initialize(audio_params_); 231 audio_algo_.Initialize(audio_params_);
218 audio_algo_.FlushBuffers(); 232 audio_algo_.FlushBuffers();
219 audio_fifo_input_bus_ = 233 audio_fifo_input_bus_ =
220 AudioBus::Create( 234 AudioBus::Create(
221 audio_params_.channels(), audio_params_.frames_per_buffer()); 235 audio_params_.channels(), audio_params_.frames_per_buffer());
222 // Audio FIFO can carry all data fron AudioRendererAlgorithm. 236 // Audio FIFO can carry all data fron AudioRendererAlgorithm.
223 audio_fifo_.reset( 237 audio_fifo_.reset(
224 new AudioFifo(audio_params_.channels(), 238 new AudioFifo(audio_params_.channels(),
225 audio_algo_.QueueCapacity())); 239 audio_algo_.QueueCapacity()));
226 audio_resampler_.reset(new media::MultiChannelResampler( 240 audio_resampler_.reset(new media::MultiChannelResampler(
227 audio_params_.channels(), 241 audio_params_.channels(),
228 static_cast<double>(audio_params_.sample_rate()) / 242 static_cast<double>(audio_params_.sample_rate()) /
229 kAudioSamplingFrequency, 243 kAudioSamplingFrequency,
230 audio_params_.frames_per_buffer(), 244 audio_params_.frames_per_buffer(),
231 base::Bind(&FakeMediaSource::ProvideData, base::Unretained(this)))); 245 base::Bind(&FakeMediaSource::ProvideData, weak_factory_.GetWeakPtr())));
232 task_runner_->PostTask( 246 task_runner_->PostTask(
233 FROM_HERE, 247 FROM_HERE,
234 base::Bind( 248 base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr()));
235 &FakeMediaSource::SendNextFrame,
236 base::Unretained(this)));
237 } 249 }
238 250
239 void FakeMediaSource::SendNextFakeFrame() { 251 void FakeMediaSource::SendNextFakeFrame() {
240 gfx::Size size(video_config_.width, video_config_.height); 252 UpdateNextFrameSize();
241 scoped_refptr<VideoFrame> video_frame = 253 scoped_refptr<VideoFrame> video_frame =
242 VideoFrame::CreateBlackFrame(size); 254 VideoFrame::CreateBlackFrame(current_frame_size_);
243 PopulateVideoFrame(video_frame.get(), synthetic_count_); 255 PopulateVideoFrame(video_frame.get(), synthetic_count_);
244 ++synthetic_count_; 256 ++synthetic_count_;
245 257
246 const base::TimeTicks now = clock_->NowTicks(); 258 const base::TimeTicks now = clock_->NowTicks();
247 259
248 base::TimeDelta video_time = VideoFrameTime(++video_frame_count_); 260 base::TimeDelta video_time = VideoFrameTime(++video_frame_count_);
249 video_frame->set_timestamp(video_time); 261 video_frame->set_timestamp(video_time);
250 if (keep_frames_) 262 if (keep_frames_)
251 inserted_video_frame_queue_.push(video_frame); 263 inserted_video_frame_queue_.push(video_frame);
252 video_frame_input_->InsertRawVideoFrame(video_frame, 264 video_frame_input_->InsertRawVideoFrame(video_frame,
(...skipping 28 matching lines...) Expand all
281 video_time = VideoFrameTime(++video_frame_count_); 293 video_time = VideoFrameTime(++video_frame_count_);
282 } 294 }
283 295
284 task_runner_->PostDelayedTask( 296 task_runner_->PostDelayedTask(
285 FROM_HERE, 297 FROM_HERE,
286 base::Bind(&FakeMediaSource::SendNextFakeFrame, 298 base::Bind(&FakeMediaSource::SendNextFakeFrame,
287 weak_factory_.GetWeakPtr()), 299 weak_factory_.GetWeakPtr()),
288 video_time - elapsed_time); 300 video_time - elapsed_time);
289 } 301 }
290 302
303 void FakeMediaSource::UpdateNextFrameSize() {
304 if (variable_frame_size_mode_) {
305 bool update_size_change_time = false;
306 if (current_frame_size_.IsEmpty()) {
307 current_frame_size_ = gfx::Size(kStartingFakeFrameWidth,
308 kStartingFakeFrameHeight);
309 update_size_change_time = true;
310 } else if (clock_->NowTicks() >= next_frame_size_change_time_) {
311 current_frame_size_ = gfx::Size(
312 base::RandInt(kMinFakeFrameWidth, kMaxFakeFrameWidth),
313 base::RandInt(kMinFakeFrameHeight, kMaxFakeFrameHeight));
314 update_size_change_time = true;
315 }
316
317 if (update_size_change_time) {
318 next_frame_size_change_time_ = clock_->NowTicks() +
319 base::TimeDelta::FromMillisecondsD(
320 base::RandDouble() * kMaxFrameSizeChangeMillis);
321 }
322 } else {
323 current_frame_size_ = gfx::Size(kStartingFakeFrameWidth,
324 kStartingFakeFrameHeight);
325 next_frame_size_change_time_ = base::TimeTicks();
326 }
327 }
328
291 bool FakeMediaSource::SendNextTranscodedVideo(base::TimeDelta elapsed_time) { 329 bool FakeMediaSource::SendNextTranscodedVideo(base::TimeDelta elapsed_time) {
292 if (!is_transcoding_video()) 330 if (!is_transcoding_video())
293 return false; 331 return false;
294 332
295 Decode(false); 333 Decode(false);
296 if (video_frame_queue_.empty()) 334 if (video_frame_queue_.empty())
297 return false; 335 return false;
298 336
299 scoped_refptr<VideoFrame> decoded_frame = 337 const scoped_refptr<VideoFrame> video_frame = video_frame_queue_.front();
300 video_frame_queue_.front(); 338 if (elapsed_time < video_frame->timestamp())
301 if (elapsed_time < decoded_frame->timestamp())
302 return false; 339 return false;
303
304 gfx::Size size(video_config_.width, video_config_.height);
305 scoped_refptr<VideoFrame> video_frame =
306 VideoFrame::CreateBlackFrame(size);
307 video_frame_queue_.pop(); 340 video_frame_queue_.pop();
308 media::CopyPlane(VideoFrame::kYPlane,
309 decoded_frame->data(VideoFrame::kYPlane),
310 decoded_frame->stride(VideoFrame::kYPlane),
311 decoded_frame->rows(VideoFrame::kYPlane),
312 video_frame.get());
313 media::CopyPlane(VideoFrame::kUPlane,
314 decoded_frame->data(VideoFrame::kUPlane),
315 decoded_frame->stride(VideoFrame::kUPlane),
316 decoded_frame->rows(VideoFrame::kUPlane),
317 video_frame.get());
318 media::CopyPlane(VideoFrame::kVPlane,
319 decoded_frame->data(VideoFrame::kVPlane),
320 decoded_frame->stride(VideoFrame::kVPlane),
321 decoded_frame->rows(VideoFrame::kVPlane),
322 video_frame.get());
323 341
324 // Use the timestamp from the file if we're transcoding. 342 // Use the timestamp from the file if we're transcoding.
325 video_frame->set_timestamp(ScaleTimestamp(decoded_frame->timestamp())); 343 video_frame->set_timestamp(ScaleTimestamp(video_frame->timestamp()));
326 if (keep_frames_) 344 if (keep_frames_)
327 inserted_video_frame_queue_.push(video_frame); 345 inserted_video_frame_queue_.push(video_frame);
328 video_frame_input_->InsertRawVideoFrame( 346 video_frame_input_->InsertRawVideoFrame(
329 video_frame, start_time_ + video_frame->timestamp()); 347 video_frame, start_time_ + video_frame->timestamp());
330 348
331 // Make sure queue is not empty. 349 // Make sure queue is not empty.
332 Decode(false); 350 Decode(false);
333 return true; 351 return true;
334 } 352 }
335 353
(...skipping 30 matching lines...) Expand all
366 if (audio_bus_queue_.empty() && video_frame_queue_.empty()) { 384 if (audio_bus_queue_.empty() && video_frame_queue_.empty()) {
367 // Both queues are empty can only mean that we have reached 385 // Both queues are empty can only mean that we have reached
368 // the end of the stream. 386 // the end of the stream.
369 LOG(INFO) << "Rewind."; 387 LOG(INFO) << "Rewind.";
370 Rewind(); 388 Rewind();
371 } 389 }
372 390
373 // Send next send. 391 // Send next send.
374 task_runner_->PostDelayedTask( 392 task_runner_->PostDelayedTask(
375 FROM_HERE, 393 FROM_HERE,
376 base::Bind( 394 base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr()),
377 &FakeMediaSource::SendNextFrame,
378 base::Unretained(this)),
379 base::TimeDelta::FromMilliseconds(kAudioFrameMs)); 395 base::TimeDelta::FromMilliseconds(kAudioFrameMs));
380 } 396 }
381 397
382 base::TimeDelta FakeMediaSource::VideoFrameTime(int frame_number) { 398 base::TimeDelta FakeMediaSource::VideoFrameTime(int frame_number) {
383 return frame_number * base::TimeDelta::FromSeconds(1) * 399 return frame_number * base::TimeDelta::FromSeconds(1) *
384 video_frame_rate_denominator_ / video_frame_rate_numerator_; 400 video_frame_rate_denominator_ / video_frame_rate_numerator_;
385 } 401 }
386 402
387 base::TimeDelta FakeMediaSource::ScaleTimestamp(base::TimeDelta timestamp) { 403 base::TimeDelta FakeMediaSource::ScaleTimestamp(base::TimeDelta timestamp) {
388 return base::TimeDelta::FromSecondsD(timestamp.InSecondsF() / playback_rate_); 404 return base::TimeDelta::FromSecondsD(timestamp.InSecondsF() / playback_rate_);
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 AVCodecContext* FakeMediaSource::av_audio_context() { 618 AVCodecContext* FakeMediaSource::av_audio_context() {
603 return av_audio_stream()->codec; 619 return av_audio_stream()->codec;
604 } 620 }
605 621
606 AVCodecContext* FakeMediaSource::av_video_context() { 622 AVCodecContext* FakeMediaSource::av_video_context() {
607 return av_video_stream()->codec; 623 return av_video_stream()->codec;
608 } 624 }
609 625
610 } // namespace cast 626 } // namespace cast
611 } // namespace media 627 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/test/fake_media_source.h ('k') | media/cast/test/linux_output_window.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698