Chromium Code Reviews| 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 // 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |