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

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

Issue 255473005: Cast: improve AV sync in sender application (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 6 years, 8 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 | « no previous file | no next file » | 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 // Test application that simulates a cast sender - Data can be either generated 5 // Test application that simulates a cast sender - Data can be either generated
6 // or read from a file. 6 // or read from a file.
7 7
8 #include <queue> 8 #include <queue>
9 9
10 #include "base/at_exit.h" 10 #include "base/at_exit.h"
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 synthetic_count_(0), 148 synthetic_count_(0),
149 clock_(clock), 149 clock_(clock),
150 audio_frame_count_(0), 150 audio_frame_count_(0),
151 video_frame_count_(0), 151 video_frame_count_(0),
152 weak_factory_(this), 152 weak_factory_(this),
153 av_format_context_(NULL), 153 av_format_context_(NULL),
154 audio_stream_index_(-1), 154 audio_stream_index_(-1),
155 playback_rate_(1.0), 155 playback_rate_(1.0),
156 video_stream_index_(-1), 156 video_stream_index_(-1),
157 video_frame_rate_numerator_(video_config.max_frame_rate), 157 video_frame_rate_numerator_(video_config.max_frame_rate),
158 video_frame_rate_denominator_(1) { 158 video_frame_rate_denominator_(1),
159 video_first_pts_(0),
160 video_first_pts_set_(false) {
159 audio_bus_factory_.reset(new TestAudioBusFactory(kAudioChannels, 161 audio_bus_factory_.reset(new TestAudioBusFactory(kAudioChannels,
160 kAudioSamplingFrequency, 162 kAudioSamplingFrequency,
161 kSoundFrequency, 163 kSoundFrequency,
162 kSoundVolume)); 164 kSoundVolume));
163 const CommandLine* cmd = CommandLine::ForCurrentProcess(); 165 const CommandLine* cmd = CommandLine::ForCurrentProcess();
164 int override_fps = 0; 166 int override_fps = 0;
165 if (base::StringToInt(cmd->GetSwitchValueASCII(kSwitchFps), 167 if (base::StringToInt(cmd->GetSwitchValueASCII(kSwitchFps),
166 &override_fps)) { 168 &override_fps)) {
167 video_config_.max_frame_rate = override_fps; 169 video_config_.max_frame_rate = override_fps;
168 video_frame_rate_numerator_ = override_fps; 170 video_frame_rate_numerator_ = override_fps;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 void Start(scoped_refptr<AudioFrameInput> audio_frame_input, 283 void Start(scoped_refptr<AudioFrameInput> audio_frame_input,
282 scoped_refptr<VideoFrameInput> video_frame_input) { 284 scoped_refptr<VideoFrameInput> video_frame_input) {
283 audio_frame_input_ = audio_frame_input; 285 audio_frame_input_ = audio_frame_input;
284 video_frame_input_ = video_frame_input; 286 video_frame_input_ = video_frame_input;
285 287
286 LOG(INFO) << "Max Frame rate: " << video_config_.max_frame_rate; 288 LOG(INFO) << "Max Frame rate: " << video_config_.max_frame_rate;
287 LOG(INFO) << "Real Frame rate: " 289 LOG(INFO) << "Real Frame rate: "
288 << video_frame_rate_numerator_ << "/" 290 << video_frame_rate_numerator_ << "/"
289 << video_frame_rate_denominator_ << " fps."; 291 << video_frame_rate_denominator_ << " fps.";
290 LOG(INFO) << "Audio playback rate: " << playback_rate_; 292 LOG(INFO) << "Audio playback rate: " << playback_rate_;
293
294 if (!is_transcoding_audio() && !is_transcoding_video()) {
295 // Send fake patterns.
296 test_app_thread_proxy_->PostTask(
297 FROM_HERE,
298 base::Bind(
299 &SendProcess::SendNextFakeFrame,
300 base::Unretained(this)));
301 return;
302 }
303
304 // Send transcoding streams.
291 audio_algo_.Initialize(playback_rate_, audio_params_); 305 audio_algo_.Initialize(playback_rate_, audio_params_);
292 audio_algo_.FlushBuffers(); 306 audio_algo_.FlushBuffers();
293 audio_fifo_input_bus_ = 307 audio_fifo_input_bus_ =
294 AudioBus::Create( 308 AudioBus::Create(
295 audio_params_.channels(), audio_params_.frames_per_buffer()); 309 audio_params_.channels(), audio_params_.frames_per_buffer());
296 // Audio FIFO can carry all data fron AudioRendererAlgorithm. 310 // Audio FIFO can carry all data fron AudioRendererAlgorithm.
297 audio_fifo_.reset( 311 audio_fifo_.reset(
298 new AudioFifo(audio_params_.channels(), 312 new AudioFifo(audio_params_.channels(),
299 audio_algo_.QueueCapacity())); 313 audio_algo_.QueueCapacity()));
300 audio_resampler_.reset(new media::MultiChannelResampler( 314 audio_resampler_.reset(new media::MultiChannelResampler(
301 audio_params_.channels(), 315 audio_params_.channels(),
302 static_cast<double>(audio_params_.sample_rate()) / 316 static_cast<double>(audio_params_.sample_rate()) /
303 kAudioSamplingFrequency, 317 kAudioSamplingFrequency,
304 audio_params_.frames_per_buffer(), 318 audio_params_.frames_per_buffer(),
305 base::Bind(&SendProcess::ProvideData, base::Unretained(this)))); 319 base::Bind(&SendProcess::ProvideData, base::Unretained(this))));
306 audio_decoded_ts_.reset(
307 new AudioTimestampHelper(audio_params_.sample_rate()));
308 audio_decoded_ts_->SetBaseTimestamp(base::TimeDelta());
309 audio_scaled_ts_.reset(
310 new AudioTimestampHelper(audio_params_.sample_rate()));
311 audio_scaled_ts_->SetBaseTimestamp(base::TimeDelta());
312 audio_resampled_ts_.reset(
313 new AudioTimestampHelper(kAudioSamplingFrequency));
314 audio_resampled_ts_->SetBaseTimestamp(base::TimeDelta());
315 test_app_thread_proxy_->PostTask( 320 test_app_thread_proxy_->PostTask(
316 FROM_HERE, 321 FROM_HERE,
317 base::Bind(&SendProcess::SendNextFrame, base::Unretained(this))); 322 base::Bind(
323 &SendProcess::SendNextFrame,
324 base::Unretained(this)));
318 } 325 }
319 326
320 void SendNextFrame() { 327 void SendNextFakeFrame() {
321 gfx::Size size(video_config_.width, video_config_.height); 328 gfx::Size size(video_config_.width, video_config_.height);
322 scoped_refptr<VideoFrame> video_frame = 329 scoped_refptr<VideoFrame> video_frame =
323 VideoFrame::CreateBlackFrame(size); 330 VideoFrame::CreateBlackFrame(size);
324 if (is_transcoding_video()) { 331 PopulateVideoFrame(video_frame, synthetic_count_);
325 Decode(false);
326 CHECK(!video_frame_queue_.empty()) << "No video frame.";
327 scoped_refptr<VideoFrame> decoded_frame =
328 video_frame_queue_.front();
329 video_frame->set_timestamp(decoded_frame->timestamp());
330 video_frame_queue_.pop();
331 media::CopyPlane(VideoFrame::kYPlane,
332 decoded_frame->data(VideoFrame::kYPlane),
333 decoded_frame->stride(VideoFrame::kYPlane),
334 decoded_frame->rows(VideoFrame::kYPlane),
335 video_frame);
336 media::CopyPlane(VideoFrame::kUPlane,
337 decoded_frame->data(VideoFrame::kUPlane),
338 decoded_frame->stride(VideoFrame::kUPlane),
339 decoded_frame->rows(VideoFrame::kUPlane),
340 video_frame);
341 media::CopyPlane(VideoFrame::kVPlane,
342 decoded_frame->data(VideoFrame::kVPlane),
343 decoded_frame->stride(VideoFrame::kVPlane),
344 decoded_frame->rows(VideoFrame::kVPlane),
345 video_frame);
346 } else {
347 PopulateVideoFrame(video_frame, synthetic_count_);
348 }
349 ++synthetic_count_; 332 ++synthetic_count_;
350 333
351 base::TimeTicks now = clock_->NowTicks(); 334 base::TimeTicks now = clock_->NowTicks();
352 if (start_time_.is_null()) 335 if (start_time_.is_null())
353 start_time_ = now; 336 start_time_ = now;
354 337
355 base::TimeDelta video_time; 338 base::TimeDelta video_time = VideoFrameTime(video_frame_count_);
356 if (is_transcoding_video()) {
357 // Use the timestamp from the file if we're transcoding and
358 // playback rate is 1.0.
359 video_time = ScaleTimestamp(video_frame->timestamp());
360 } else {
361 VideoFrameTime(video_frame_count_);
362 }
363
364 video_frame->set_timestamp(video_time); 339 video_frame->set_timestamp(video_time);
365 video_frame_input_->InsertRawVideoFrame(video_frame, 340 video_frame_input_->InsertRawVideoFrame(video_frame,
366 start_time_ + video_time); 341 start_time_ + video_time);
367 342
368 if (is_transcoding_video()) {
369 // Decode next video frame to get the next frame's timestamp.
370 Decode(false);
371 CHECK(!video_frame_queue_.empty()) << "No video frame.";
372 video_time = ScaleTimestamp(video_frame_queue_.front()->timestamp());
373 } else {
374 video_time = VideoFrameTime(++video_frame_count_);
375 }
376
377 // Send just enough audio data to match next video frame's time. 343 // Send just enough audio data to match next video frame's time.
378 base::TimeDelta audio_time = AudioFrameTime(audio_frame_count_); 344 base::TimeDelta audio_time = AudioFrameTime(audio_frame_count_);
379 while (audio_time < video_time) { 345 while (audio_time < video_time) {
380 if (is_transcoding_audio()) { 346 if (is_transcoding_audio()) {
381 Decode(true); 347 Decode(true);
382 CHECK(!audio_bus_queue_.empty()) << "No audio decoded."; 348 CHECK(!audio_bus_queue_.empty()) << "No audio decoded.";
383 scoped_ptr<AudioBus> bus(audio_bus_queue_.front()); 349 scoped_ptr<AudioBus> bus(audio_bus_queue_.front());
384 audio_bus_queue_.pop(); 350 audio_bus_queue_.pop();
385 audio_frame_input_->InsertAudio( 351 audio_frame_input_->InsertAudio(
386 bus.Pass(), start_time_ + audio_time); 352 bus.Pass(), start_time_ + audio_time);
387 } else { 353 } else {
388 audio_frame_input_->InsertAudio( 354 audio_frame_input_->InsertAudio(
389 audio_bus_factory_->NextAudioBus( 355 audio_bus_factory_->NextAudioBus(
390 base::TimeDelta::FromMilliseconds(kAudioFrameMs)), 356 base::TimeDelta::FromMilliseconds(kAudioFrameMs)),
391 start_time_ + audio_time); 357 start_time_ + audio_time);
392 } 358 }
393 audio_time = AudioFrameTime(++audio_frame_count_); 359 audio_time = AudioFrameTime(++audio_frame_count_);
394 } 360 }
395 361
396 // This is the time since the stream started. 362 // This is the time since the stream started.
397 const base::TimeDelta elapsed_time = now - start_time_; 363 const base::TimeDelta elapsed_time = now - start_time_;
398 364
399 // Handle the case when decoding or frame generation cannot keep up. 365 // Handle the case when frame generation cannot keep up.
400 // Move the time ahead to match the next frame. 366 // Move the time ahead to match the next frame.
401 while (video_time < elapsed_time) { 367 while (video_time < elapsed_time) {
402 LOG(WARNING) << "Skipping one frame."; 368 LOG(WARNING) << "Skipping one frame.";
403 video_time = VideoFrameTime(++video_frame_count_); 369 video_time = VideoFrameTime(++video_frame_count_);
404 } 370 }
405 371
406 test_app_thread_proxy_->PostDelayedTask( 372 test_app_thread_proxy_->PostDelayedTask(
407 FROM_HERE, 373 FROM_HERE,
408 base::Bind(&SendProcess::SendNextFrame, 374 base::Bind(&SendProcess::SendNextFakeFrame,
409 weak_factory_.GetWeakPtr()), 375 weak_factory_.GetWeakPtr()),
410 video_time - elapsed_time); 376 video_time - elapsed_time);
411 } 377 }
412 378
379 // Return true if a frame was sent.
380 bool SendNextTranscodedVideo(base::TimeDelta elapsed_time) {
381 if (!is_transcoding_video())
382 return false;
383
384 Decode(false);
385 if (video_frame_queue_.empty())
386 return false;
387
388 scoped_refptr<VideoFrame> decoded_frame =
389 video_frame_queue_.front();
390 if (elapsed_time < decoded_frame->timestamp())
391 return false;
392
393 gfx::Size size(video_config_.width, video_config_.height);
394 scoped_refptr<VideoFrame> video_frame =
395 VideoFrame::CreateBlackFrame(size);
396 video_frame_queue_.pop();
397 media::CopyPlane(VideoFrame::kYPlane,
398 decoded_frame->data(VideoFrame::kYPlane),
399 decoded_frame->stride(VideoFrame::kYPlane),
400 decoded_frame->rows(VideoFrame::kYPlane),
401 video_frame);
402 media::CopyPlane(VideoFrame::kUPlane,
403 decoded_frame->data(VideoFrame::kUPlane),
404 decoded_frame->stride(VideoFrame::kUPlane),
405 decoded_frame->rows(VideoFrame::kUPlane),
406 video_frame);
407 media::CopyPlane(VideoFrame::kVPlane,
408 decoded_frame->data(VideoFrame::kVPlane),
409 decoded_frame->stride(VideoFrame::kVPlane),
410 decoded_frame->rows(VideoFrame::kVPlane),
411 video_frame);
412
413 base::TimeDelta video_time;
414 // Use the timestamp from the file if we're transcoding and
415 // playback rate is 1.0.
hubbe 2014/04/24 22:32:51 Odd comment, what do we use if playback rate is no
416 video_time = ScaleTimestamp(decoded_frame->timestamp());
417 video_frame_input_->InsertRawVideoFrame(
418 video_frame, start_time_ + video_time);
419
420 // Make sure queue is not empty.
421 Decode(false);
422 return true;
423 }
424
425 // Return true if a frame was sent.
426 bool SendNextTranscodedAudio(base::TimeDelta elapsed_time) {
427 if (!is_transcoding_audio())
428 return false;
429
430 Decode(true);
431 if (audio_bus_queue_.empty())
432 return false;
433
434 base::TimeDelta audio_time = audio_sent_ts_->GetTimestamp();
435 if (elapsed_time < audio_time)
436 return false;
437 scoped_ptr<AudioBus> bus(audio_bus_queue_.front());
438 audio_bus_queue_.pop();
439 audio_sent_ts_->AddFrames(bus->frames());
440 audio_frame_input_->InsertAudio(
441 bus.Pass(), start_time_ + audio_time);
442
443 // Make sure queue is not empty.
444 Decode(true);
445 return true;
446 }
447
448 void SendNextFrame() {
449 if (start_time_.is_null())
450 start_time_ = clock_->NowTicks();
451 if (start_time_.is_null())
452 start_time_ = clock_->NowTicks();
453
454 // Send as much as possible. Audio is sent according to
455 // system time.
456 while (SendNextTranscodedAudio(
457 clock_->NowTicks() - start_time_));
hubbe 2014/04/24 22:32:51 weird indentation.
458 // Video is sync'ed to audio.
459 while (SendNextTranscodedVideo(
460 audio_sent_ts_->GetTimestamp()));
hubbe 2014/04/24 22:32:51 weird indentation
461
462 if (audio_bus_queue_.empty() && video_frame_queue_.empty()) {
463 // Both queues are empty can only mean that we have reached
464 // the end of the stream.
465 LOG(INFO) << "Rewind.";
466 Rewind();
467 start_time_ = base::TimeTicks();
468 audio_sent_ts_.reset();
469 video_first_pts_set_ = false;
470 }
471
472 // Send next send.
473 test_app_thread_proxy_->PostDelayedTask(
474 FROM_HERE,
475 base::Bind(
476 &SendProcess::SendNextFrame,
477 base::Unretained(this)),
478 base::TimeDelta::FromMilliseconds(kAudioFrameMs));
479 }
480
413 const VideoSenderConfig& get_video_config() const { return video_config_; } 481 const VideoSenderConfig& get_video_config() const { return video_config_; }
414 482
415 private: 483 private:
416 bool is_transcoding_audio() { return audio_stream_index_ >= 0; } 484 bool is_transcoding_audio() { return audio_stream_index_ >= 0; }
417 bool is_transcoding_video() { return video_stream_index_ >= 0; } 485 bool is_transcoding_video() { return video_stream_index_ >= 0; }
418 486
419 // Helper methods to compute timestamps for the frame number specified. 487 // Helper methods to compute timestamps for the frame number specified.
420 base::TimeDelta VideoFrameTime(int frame_number) { 488 base::TimeDelta VideoFrameTime(int frame_number) {
421 return frame_number * base::TimeDelta::FromSeconds(1) * 489 return frame_number * base::TimeDelta::FromSeconds(1) *
422 video_frame_rate_denominator_ / video_frame_rate_numerator_; 490 video_frame_rate_denominator_ / video_frame_rate_numerator_;
(...skipping 11 matching lines...) Expand all
434 // Go to the beginning of the stream. 502 // Go to the beginning of the stream.
435 void Rewind() { 503 void Rewind() {
436 CHECK(av_seek_frame(av_format_context_, -1, 0, AVSEEK_FLAG_BACKWARD) >= 0) 504 CHECK(av_seek_frame(av_format_context_, -1, 0, AVSEEK_FLAG_BACKWARD) >= 0)
437 << "Failed to rewind to the beginning."; 505 << "Failed to rewind to the beginning.";
438 } 506 }
439 507
440 // Call FFmpeg to fetch one packet. 508 // Call FFmpeg to fetch one packet.
441 ScopedAVPacket DemuxOnePacket(bool* audio) { 509 ScopedAVPacket DemuxOnePacket(bool* audio) {
442 ScopedAVPacket packet(new AVPacket()); 510 ScopedAVPacket packet(new AVPacket());
443 if (av_read_frame(av_format_context_, packet.get()) < 0) { 511 if (av_read_frame(av_format_context_, packet.get()) < 0) {
444 LOG(ERROR) << "Failed to read one AVPacket"; 512 LOG(ERROR) << "Failed to read one AVPacket.";
445 packet.reset(); 513 packet.reset();
446 return packet.Pass(); 514 return packet.Pass();
447 } 515 }
448 516
449 int stream_index = static_cast<int>(packet->stream_index); 517 int stream_index = static_cast<int>(packet->stream_index);
450 if (stream_index == audio_stream_index_) { 518 if (stream_index == audio_stream_index_) {
451 *audio = true; 519 *audio = true;
452 } else if (stream_index == video_stream_index_) { 520 } else if (stream_index == video_stream_index_) {
453 *audio = false; 521 *audio = false;
454 } else { 522 } else {
(...skipping 19 matching lines...) Expand all
474 CHECK(result >= 0) << "Failed to decode audio."; 542 CHECK(result >= 0) << "Failed to decode audio.";
475 packet_temp.size -= result; 543 packet_temp.size -= result;
476 packet_temp.data += result; 544 packet_temp.data += result;
477 if (!frame_decoded) 545 if (!frame_decoded)
478 continue; 546 continue;
479 547
480 int frames_read = avframe->nb_samples; 548 int frames_read = avframe->nb_samples;
481 if (frames_read < 0) 549 if (frames_read < 0)
482 break; 550 break;
483 551
552 if (!audio_sent_ts_) {
553 // Initialize the base time to the first packet in the file.
554 // This is set to the frequency we send to the receiver.
555 // Not the frequency of the source file. This is because we
556 // increment the frame count by samples we sent.
557 audio_sent_ts_.reset(
558 new AudioTimestampHelper(kAudioSamplingFrequency));
559 // For some files this is an invalid value.
560 base::TimeDelta base_ts;
561 audio_sent_ts_->SetBaseTimestamp(base_ts);
562 }
563
484 scoped_refptr<AudioBuffer> buffer = 564 scoped_refptr<AudioBuffer> buffer =
485 AudioBuffer::CopyFrom( 565 AudioBuffer::CopyFrom(
486 AVSampleFormatToSampleFormat( 566 AVSampleFormatToSampleFormat(
487 av_audio_context()->sample_fmt), 567 av_audio_context()->sample_fmt),
488 ChannelLayoutToChromeChannelLayout( 568 ChannelLayoutToChromeChannelLayout(
489 av_audio_context()->channel_layout, 569 av_audio_context()->channel_layout,
490 av_audio_context()->channels), 570 av_audio_context()->channels),
491 av_audio_context()->channels, 571 av_audio_context()->channels,
492 av_audio_context()->sample_rate, 572 av_audio_context()->sample_rate,
493 frames_read, 573 frames_read,
494 &avframe->data[0], 574 &avframe->data[0],
495 audio_decoded_ts_->GetTimestamp(), 575 // Note: Not all files have correct values for pkt_pts.
496 audio_decoded_ts_->GetFrameDuration(frames_read)); 576 base::TimeDelta::FromMilliseconds(avframe->pkt_pts),
577 // TODO(hclam): Give accurate duration based on samples.
578 base::TimeDelta());
497 audio_algo_.EnqueueBuffer(buffer); 579 audio_algo_.EnqueueBuffer(buffer);
498 audio_decoded_ts_->AddFrames(frames_read);
499 } while (packet_temp.size > 0); 580 } while (packet_temp.size > 0);
500 avcodec_free_frame(&avframe); 581 avcodec_free_frame(&avframe);
501 582
502 const int frames_needed_to_scale = 583 const int frames_needed_to_scale =
503 playback_rate_ * av_audio_context()->sample_rate / 584 playback_rate_ * av_audio_context()->sample_rate /
504 kAudioPacketsPerSecond; 585 kAudioPacketsPerSecond;
505 while (frames_needed_to_scale <= audio_algo_.frames_buffered()) { 586 while (frames_needed_to_scale <= audio_algo_.frames_buffered()) {
506 if (!audio_algo_.FillBuffer(audio_fifo_input_bus_.get(), 587 if (!audio_algo_.FillBuffer(audio_fifo_input_bus_.get(),
507 audio_fifo_input_bus_->frames())) { 588 audio_fifo_input_bus_->frames())) {
508 // Nothing can be scaled. Decode some more. 589 // Nothing can be scaled. Decode some more.
509 return; 590 return;
510 } 591 }
511 audio_scaled_ts_->AddFrames(audio_fifo_input_bus_->frames());
512 592
513 // Prevent overflow of audio data in the FIFO. 593 // Prevent overflow of audio data in the FIFO.
514 if (audio_fifo_input_bus_->frames() + audio_fifo_->frames() 594 if (audio_fifo_input_bus_->frames() + audio_fifo_->frames()
515 <= audio_fifo_->max_frames()) { 595 <= audio_fifo_->max_frames()) {
516 audio_fifo_->Push(audio_fifo_input_bus_.get()); 596 audio_fifo_->Push(audio_fifo_input_bus_.get());
517 } else { 597 } else {
518 LOG(WARNING) << "Audio FIFO full; dropping samples."; 598 LOG(WARNING) << "Audio FIFO full; dropping samples.";
519 } 599 }
520 600
521 // Make sure there's enough data to resample audio. 601 // Make sure there's enough data to resample audio.
522 if (audio_fifo_->frames() < 602 if (audio_fifo_->frames() <
523 2 * audio_params_.sample_rate() / kAudioPacketsPerSecond) { 603 2 * audio_params_.sample_rate() / kAudioPacketsPerSecond) {
524 continue; 604 continue;
525 } 605 }
526 606
527 scoped_ptr<media::AudioBus> resampled_bus( 607 scoped_ptr<media::AudioBus> resampled_bus(
528 media::AudioBus::Create( 608 media::AudioBus::Create(
529 audio_params_.channels(), 609 audio_params_.channels(),
530 kAudioSamplingFrequency / kAudioPacketsPerSecond)); 610 kAudioSamplingFrequency / kAudioPacketsPerSecond));
531 audio_resampler_->Resample(resampled_bus->frames(), 611 audio_resampler_->Resample(resampled_bus->frames(),
532 resampled_bus.get()); 612 resampled_bus.get());
533 audio_resampled_ts_->AddFrames(resampled_bus->frames());
534 audio_bus_queue_.push(resampled_bus.release()); 613 audio_bus_queue_.push(resampled_bus.release());
535 } 614 }
536 } 615 }
537 616
538 void DecodeVideo(ScopedAVPacket packet) { 617 void DecodeVideo(ScopedAVPacket packet) {
539 // Video. 618 // Video.
540 int got_picture; 619 int got_picture;
541 AVFrame* avframe = av_frame_alloc(); 620 AVFrame* avframe = av_frame_alloc();
542 avcodec_get_frame_defaults(avframe); 621 avcodec_get_frame_defaults(avframe);
543 // Tell the decoder to reorder for us. 622 // Tell the decoder to reorder for us.
544 avframe->reordered_opaque = 623 avframe->reordered_opaque =
545 av_video_context()->reordered_opaque = packet->pts; 624 av_video_context()->reordered_opaque = packet->pts;
546 CHECK(avcodec_decode_video2( 625 CHECK(avcodec_decode_video2(
547 av_video_context(), avframe, &got_picture, packet.get()) >= 0) 626 av_video_context(), avframe, &got_picture, packet.get()) >= 0)
548 << "Video decode error."; 627 << "Video decode error.";
549 if (!got_picture) 628 if (!got_picture)
550 return; 629 return;
551 gfx::Size size(av_video_context()->width, av_video_context()->height); 630 gfx::Size size(av_video_context()->width, av_video_context()->height);
631 if (!video_first_pts_set_ ||
632 avframe->reordered_opaque < video_first_pts_) {
633 video_first_pts_set_ = true;
634 video_first_pts_ = avframe->reordered_opaque;
635 }
636 int64 pts = avframe->reordered_opaque - video_first_pts_;
552 video_frame_queue_.push( 637 video_frame_queue_.push(
553 VideoFrame::WrapExternalYuvData( 638 VideoFrame::WrapExternalYuvData(
554 media::VideoFrame::YV12, 639 media::VideoFrame::YV12,
555 size, 640 size,
556 gfx::Rect(size), 641 gfx::Rect(size),
557 size, 642 size,
558 avframe->linesize[0], 643 avframe->linesize[0],
559 avframe->linesize[1], 644 avframe->linesize[1],
560 avframe->linesize[2], 645 avframe->linesize[2],
561 avframe->data[0], 646 avframe->data[0],
562 avframe->data[1], 647 avframe->data[1],
563 avframe->data[2], 648 avframe->data[2],
564 base::TimeDelta::FromMilliseconds(avframe->reordered_opaque), 649 base::TimeDelta::FromMilliseconds(pts),
565 base::Bind(&AVFreeFrame, avframe))); 650 base::Bind(&AVFreeFrame, avframe)));
566 } 651 }
567 652
568 void Decode(bool decode_audio) { 653 void Decode(bool decode_audio) {
569 // Read the stream until one video frame can be decoded. 654 // Read the stream until one video frame can be decoded.
570 while (true) { 655 while (true) {
571 if (decode_audio && !audio_bus_queue_.empty()) 656 if (decode_audio && !audio_bus_queue_.empty())
572 return; 657 return;
573 if (!decode_audio && !video_frame_queue_.empty()) 658 if (!decode_audio && !video_frame_queue_.empty())
574 return; 659 return;
575 660
576 bool audio_packet = false; 661 bool audio_packet = false;
577 ScopedAVPacket packet = DemuxOnePacket(&audio_packet); 662 ScopedAVPacket packet = DemuxOnePacket(&audio_packet);
578 if (!packet) { 663 if (!packet) {
579 LOG(INFO) << "End of stream; Rewind."; 664 LOG(INFO) << "End of stream.";
580 Rewind(); 665 return;
581 continue;
582 } 666 }
583 667
584 if (audio_packet) 668 if (audio_packet)
585 DecodeAudio(packet.Pass()); 669 DecodeAudio(packet.Pass());
586 else 670 else
587 DecodeVideo(packet.Pass()); 671 DecodeVideo(packet.Pass());
588 } 672 }
589 } 673 }
590 674
591 void ProvideData(int frame_delay, media::AudioBus* output_bus) { 675 void ProvideData(int frame_delay, media::AudioBus* output_bus) {
(...skipping 13 matching lines...) Expand all
605 } 689 }
606 AVCodecContext* av_audio_context() { return av_audio_stream()->codec; } 690 AVCodecContext* av_audio_context() { return av_audio_stream()->codec; }
607 AVCodecContext* av_video_context() { return av_video_stream()->codec; } 691 AVCodecContext* av_video_context() { return av_video_stream()->codec; }
608 692
609 scoped_refptr<base::SingleThreadTaskRunner> test_app_thread_proxy_; 693 scoped_refptr<base::SingleThreadTaskRunner> test_app_thread_proxy_;
610 VideoSenderConfig video_config_; 694 VideoSenderConfig video_config_;
611 scoped_refptr<AudioFrameInput> audio_frame_input_; 695 scoped_refptr<AudioFrameInput> audio_frame_input_;
612 scoped_refptr<VideoFrameInput> video_frame_input_; 696 scoped_refptr<VideoFrameInput> video_frame_input_;
613 uint8 synthetic_count_; 697 uint8 synthetic_count_;
614 base::TickClock* const clock_; // Not owned by this class. 698 base::TickClock* const clock_; // Not owned by this class.
699
700 // Time when the stream starts.
615 base::TimeTicks start_time_; 701 base::TimeTicks start_time_;
702
703 // The following three members are used only for fake frames.
616 int audio_frame_count_; // Each audio frame is exactly 10ms. 704 int audio_frame_count_; // Each audio frame is exactly 10ms.
617 int video_frame_count_; 705 int video_frame_count_;
618 scoped_ptr<TestAudioBusFactory> audio_bus_factory_; 706 scoped_ptr<TestAudioBusFactory> audio_bus_factory_;
619 707
620 // NOTE: Weak pointers must be invalidated before all other member variables. 708 // NOTE: Weak pointers must be invalidated before all other member variables.
621 base::WeakPtrFactory<SendProcess> weak_factory_; 709 base::WeakPtrFactory<SendProcess> weak_factory_;
622 710
623 base::MemoryMappedFile file_data_; 711 base::MemoryMappedFile file_data_;
624 scoped_ptr<InMemoryUrlProtocol> protocol_; 712 scoped_ptr<InMemoryUrlProtocol> protocol_;
625 scoped_ptr<FFmpegGlue> glue_; 713 scoped_ptr<FFmpegGlue> glue_;
626 AVFormatContext* av_format_context_; 714 AVFormatContext* av_format_context_;
627 715
628 int audio_stream_index_; 716 int audio_stream_index_;
629 AudioParameters audio_params_; 717 AudioParameters audio_params_;
630 double playback_rate_; 718 double playback_rate_;
631 719
632 int video_stream_index_; 720 int video_stream_index_;
633 int video_frame_rate_numerator_; 721 int video_frame_rate_numerator_;
634 int video_frame_rate_denominator_; 722 int video_frame_rate_denominator_;
635 723
636 // These are used for audio resampling. 724 // These are used for audio resampling.
637 scoped_ptr<media::MultiChannelResampler> audio_resampler_; 725 scoped_ptr<media::MultiChannelResampler> audio_resampler_;
638 scoped_ptr<media::AudioFifo> audio_fifo_; 726 scoped_ptr<media::AudioFifo> audio_fifo_;
639 scoped_ptr<media::AudioBus> audio_fifo_input_bus_; 727 scoped_ptr<media::AudioBus> audio_fifo_input_bus_;
640 media::AudioRendererAlgorithm audio_algo_; 728 media::AudioRendererAlgorithm audio_algo_;
641 729
642 // These helpers are used to track frames generated. 730 // Track the timestamp of audio sent to the receiver.
643 // They are: 731 scoped_ptr<media::AudioTimestampHelper> audio_sent_ts_;
644 // * Frames decoded from the file.
645 // * Frames scaled according to playback rate.
646 // * Frames resampled to output frequency.
647 scoped_ptr<media::AudioTimestampHelper> audio_decoded_ts_;
648 scoped_ptr<media::AudioTimestampHelper> audio_scaled_ts_;
649 scoped_ptr<media::AudioTimestampHelper> audio_resampled_ts_;
650 732
651 std::queue<scoped_refptr<VideoFrame> > video_frame_queue_; 733 std::queue<scoped_refptr<VideoFrame> > video_frame_queue_;
734 int64 video_first_pts_;
735 bool video_first_pts_set_;
736
652 std::queue<AudioBus*> audio_bus_queue_; 737 std::queue<AudioBus*> audio_bus_queue_;
653 738
654 DISALLOW_COPY_AND_ASSIGN(SendProcess); 739 DISALLOW_COPY_AND_ASSIGN(SendProcess);
655 }; 740 };
656 741
657 } // namespace cast 742 } // namespace cast
658 } // namespace media 743 } // namespace media
659 744
660 namespace { 745 namespace {
661 void UpdateCastTransportStatus( 746 void UpdateCastTransportStatus(
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 base::Passed(&video_event_subscriber), 964 base::Passed(&video_event_subscriber),
880 base::Passed(&audio_event_subscriber), 965 base::Passed(&audio_event_subscriber),
881 base::Passed(&video_log_file), 966 base::Passed(&video_log_file),
882 base::Passed(&audio_log_file)), 967 base::Passed(&audio_log_file)),
883 base::TimeDelta::FromSeconds(logging_duration_seconds)); 968 base::TimeDelta::FromSeconds(logging_duration_seconds));
884 send_process->Start(cast_sender->audio_frame_input(), 969 send_process->Start(cast_sender->audio_frame_input(),
885 cast_sender->video_frame_input()); 970 cast_sender->video_frame_input());
886 io_message_loop.Run(); 971 io_message_loop.Run();
887 return 0; 972 return 0;
888 } 973 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698