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

Side by Side Diff: media/audio/win/audio_output_win_unittest.cc

Issue 2517503003: Reland: Make more media APIs aware of |delay| and |delay_timestamp| (Closed)
Patch Set: Updated audio_output_win_unittest Created 4 years 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <windows.h> 5 #include <windows.h>
6 #include <mmsystem.h> 6 #include <mmsystem.h>
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 oas->Close(); 525 oas->Close();
526 } 526 }
527 527
528 // Simple source that uses a SyncSocket to retrieve the audio data 528 // Simple source that uses a SyncSocket to retrieve the audio data
529 // from a potentially remote thread. 529 // from a potentially remote thread.
530 class SyncSocketSource : public AudioOutputStream::AudioSourceCallback { 530 class SyncSocketSource : public AudioOutputStream::AudioSourceCallback {
531 public: 531 public:
532 SyncSocketSource(base::SyncSocket* socket, const AudioParameters& params) 532 SyncSocketSource(base::SyncSocket* socket, const AudioParameters& params)
533 : socket_(socket), params_(params) { 533 : socket_(socket), params_(params) {
534 // Setup AudioBus wrapping data we'll receive over the sync socket. 534 // Setup AudioBus wrapping data we'll receive over the sync socket.
535 data_size_ = AudioBus::CalculateMemorySize(params); 535 packet_size_ = AudioBus::CalculateMemorySize(params);
536 data_.reset(static_cast<float*>( 536 data_.reset(static_cast<float*>(
537 base::AlignedAlloc(data_size_, AudioBus::kChannelAlignment))); 537 base::AlignedAlloc(packet_size_ + sizeof(AudioOutputBufferParameters),
538 audio_bus_ = AudioBus::WrapMemory(params, data_.get()); 538 AudioBus::kChannelAlignment)));
539 audio_bus_ = AudioBus::WrapMemory(params, output_buffer()->audio);
539 } 540 }
540 ~SyncSocketSource() override {} 541 ~SyncSocketSource() override {}
541 542
542 // AudioSourceCallback::OnMoreData implementation: 543 // AudioSourceCallback::OnMoreData implementation:
543 int OnMoreData(base::TimeDelta delay, 544 int OnMoreData(base::TimeDelta delay,
544 base::TimeTicks /* delay_timestamp */, 545 base::TimeTicks /* delay_timestamp */,
545 int /* prior_frames_skipped */, 546 int /* prior_frames_skipped */,
546 AudioBus* dest) override { 547 AudioBus* dest) override {
547 uint32_t total_bytes_delay = 548 uint32_t control_signal = 0;
548 delay.InSecondsF() * params_.GetBytesPerSecond(); 549 socket_->Send(&control_signal, sizeof(control_signal));
549 socket_->Send(&total_bytes_delay, sizeof(total_bytes_delay)); 550 output_buffer()->params.delay = delay.InMicroseconds();
550 uint32_t size = socket_->Receive(data_.get(), data_size_); 551 uint32_t size = socket_->Receive(data_.get(), packet_size_);
552
551 DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U); 553 DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U);
552 audio_bus_->CopyTo(dest); 554 audio_bus_->CopyTo(dest);
553 return audio_bus_->frames(); 555 return audio_bus_->frames();
554 } 556 }
557 int packet_size() const { return packet_size_; }
558 AudioOutputBuffer* output_buffer() const {
559 return reinterpret_cast<AudioOutputBuffer*>(data_.get());
560 }
555 561
556 // AudioSourceCallback::OnError implementation: 562 // AudioSourceCallback::OnError implementation:
557 void OnError(AudioOutputStream* stream) override {} 563 void OnError(AudioOutputStream* stream) override {}
558 564
559 private: 565 private:
560 base::SyncSocket* socket_; 566 base::SyncSocket* socket_;
561 const AudioParameters params_; 567 const AudioParameters params_;
562 int data_size_; 568 int packet_size_;
563 std::unique_ptr<float, base::AlignedFreeDeleter> data_; 569 std::unique_ptr<float, base::AlignedFreeDeleter> data_;
564 std::unique_ptr<AudioBus> audio_bus_; 570 std::unique_ptr<AudioBus> audio_bus_;
565 }; 571 };
566 572
567 struct SyncThreadContext { 573 struct SyncThreadContext {
568 base::SyncSocket* socket; 574 base::SyncSocket* socket;
569 int sample_rate; 575 int sample_rate;
570 int channels; 576 int channels;
571 int frames; 577 int frames;
572 double sine_freq; 578 double sine_freq;
573 uint32_t packet_size_bytes; 579 uint32_t packet_size_bytes;
574 int bytes_per_second; 580 AudioOutputBuffer* buffer;
575 }; 581 };
576 582
577 // This thread provides the data that the SyncSocketSource above needs 583 // This thread provides the data that the SyncSocketSource above needs
578 // using the other end of a SyncSocket. The protocol is as follows: 584 // using the other end of a SyncSocket. The protocol is as follows:
579 // 585 //
580 // SyncSocketSource ---send 4 bytes ------------> SyncSocketThread 586 // SyncSocketSource ---send 4 bytes ------------> SyncSocketThread
581 // <--- audio packet ---------- 587 // <--- audio packet ----------
582 // 588 //
583 DWORD __stdcall SyncSocketThread(void* context) { 589 DWORD __stdcall SyncSocketThread(void* context) {
584 SyncThreadContext& ctx = *(reinterpret_cast<SyncThreadContext*>(context)); 590 SyncThreadContext& ctx = *(reinterpret_cast<SyncThreadContext*>(context));
585 591
586 // Setup AudioBus wrapping data we'll pass over the sync socket. 592 // Setup AudioBus wrapping data we'll pass over the sync socket.
587 std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>( 593 std::unique_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>(
588 base::AlignedAlloc(ctx.packet_size_bytes, AudioBus::kChannelAlignment))); 594 base::AlignedAlloc(ctx.packet_size_bytes, AudioBus::kChannelAlignment)));
589 std::unique_ptr<AudioBus> audio_bus = 595 std::unique_ptr<AudioBus> audio_bus =
590 AudioBus::WrapMemory(ctx.channels, ctx.frames, data.get()); 596 AudioBus::WrapMemory(ctx.channels, ctx.frames, data.get());
591 597
592 SineWaveAudioSource sine(1, ctx.sine_freq, ctx.sample_rate); 598 SineWaveAudioSource sine(1, ctx.sine_freq, ctx.sample_rate);
593 const int kTwoSecFrames = ctx.sample_rate * 2; 599 const int kTwoSecFrames = ctx.sample_rate * 2;
594 600
595 uint32_t total_bytes_delay = 0; 601 uint32_t control_signal = 0;
596 int times = 0;
597 for (int ix = 0; ix < kTwoSecFrames; ix += ctx.frames) { 602 for (int ix = 0; ix < kTwoSecFrames; ix += ctx.frames) {
598 if (ctx.socket->Receive(&total_bytes_delay, sizeof(total_bytes_delay)) == 0) 603 if (ctx.socket->Receive(&control_signal, sizeof(control_signal)) == 0)
599 break; 604 break;
600 if ((times > 0) && (total_bytes_delay < 1000)) __debugbreak(); 605 base::TimeDelta delay =
601 base::TimeDelta delay = base::TimeDelta::FromSecondsD( 606 base::TimeDelta::FromMicroseconds(ctx.buffer->params.delay);
602 static_cast<double>(total_bytes_delay) / ctx.bytes_per_second);
603 sine.OnMoreData(delay, base::TimeTicks::Now(), 0, audio_bus.get()); 607 sine.OnMoreData(delay, base::TimeTicks::Now(), 0, audio_bus.get());
chcunningham 2016/11/30 20:54:28 I'd send in the delay_timestamp as well.
Mikhail 2016/12/01 12:22:29 Done.
604 ctx.socket->Send(data.get(), ctx.packet_size_bytes); 608 ctx.socket->Send(data.get(), ctx.packet_size_bytes);
605 ++times;
606 } 609 }
607 610
608 return 0; 611 return 0;
609 } 612 }
610 613
611 // Test the basic operation of AudioOutputStream used with a SyncSocket. 614 // Test the basic operation of AudioOutputStream used with a SyncSocket.
612 // The emphasis is to verify that it is possible to feed data to the audio 615 // The emphasis is to verify that it is possible to feed data to the audio
613 // layer using a source based on SyncSocket. In a real situation we would 616 // layer using a source based on SyncSocket. In a real situation we would
614 // go for the low-latency version in combination with SyncSocket, but to keep 617 // go for the low-latency version in combination with SyncSocket, but to keep
615 // the test more simple, AUDIO_PCM_LINEAR is utilized instead. The main 618 // the test more simple, AUDIO_PCM_LINEAR is utilized instead. The main
(...skipping 15 matching lines...) Expand all
631 ASSERT_TRUE(oas->Open()); 634 ASSERT_TRUE(oas->Open());
632 635
633 base::SyncSocket sockets[2]; 636 base::SyncSocket sockets[2];
634 ASSERT_TRUE(base::SyncSocket::CreatePair(&sockets[0], &sockets[1])); 637 ASSERT_TRUE(base::SyncSocket::CreatePair(&sockets[0], &sockets[1]));
635 638
636 SyncSocketSource source(&sockets[0], params); 639 SyncSocketSource source(&sockets[0], params);
637 640
638 SyncThreadContext thread_context; 641 SyncThreadContext thread_context;
639 thread_context.sample_rate = params.sample_rate(); 642 thread_context.sample_rate = params.sample_rate();
640 thread_context.sine_freq = 200.0; 643 thread_context.sine_freq = 200.0;
641 thread_context.packet_size_bytes = AudioBus::CalculateMemorySize(params); 644 thread_context.packet_size_bytes = source.packet_size();
642 thread_context.frames = params.frames_per_buffer(); 645 thread_context.frames = params.frames_per_buffer();
643 thread_context.channels = params.channels(); 646 thread_context.channels = params.channels();
644 thread_context.socket = &sockets[1]; 647 thread_context.socket = &sockets[1];
645 thread_context.bytes_per_second = params.GetBytesPerSecond(); 648 thread_context.buffer = source.output_buffer();
646 649
647 HANDLE thread = ::CreateThread(NULL, 0, SyncSocketThread, 650 HANDLE thread = ::CreateThread(NULL, 0, SyncSocketThread,
648 &thread_context, 0, NULL); 651 &thread_context, 0, NULL);
649 652
650 oas->Start(&source); 653 oas->Start(&source);
651 654
652 ::WaitForSingleObject(thread, INFINITE); 655 ::WaitForSingleObject(thread, INFINITE);
653 ::CloseHandle(thread); 656 ::CloseHandle(thread);
654 657
655 oas->Stop(); 658 oas->Stop();
656 oas->Close(); 659 oas->Close();
657 } 660 }
658 661
659 } // namespace media 662 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698