diff options
author | miu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-09 01:41:55 +0000 |
---|---|---|
committer | miu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-09 01:41:55 +0000 |
commit | e81fe1a173230947493bdfd885c8e518a343a90f (patch) | |
tree | e6f0d9dad174fbe82f1e0d7b55022a159939c721 /media/cast | |
parent | 963a91b1fda682b844b9ece88d2070862f51893f (diff) | |
download | chromium_src-e81fe1a173230947493bdfd885c8e518a343a90f.zip chromium_src-e81fe1a173230947493bdfd885c8e518a343a90f.tar.gz chromium_src-e81fe1a173230947493bdfd885c8e518a343a90f.tar.bz2 |
Cast Streaming API end-to-end browser_test.
Similar to the TabCaptureApi.EndToEnd test: An extension is run that generates a rotating cycle of colors and audio tones, and the result is captured and streamed to an in-process Cast receiver. In addition:
1. Refactored existing code out of the cast_receiver_app into a shared InProcessReceiver class.
2. Added a convenient StandaloneCastEnvironment for test apps.
3. Got rid of the cast_receiver_app prompts since the defaults are used >99% of the time. Using the --enable-prompts command line arg will show them again.
4. Minor clean-ups in files touched.
NOTE: The new EndToEnd test is being submitted as disabled while outstanding bugs are worked by the team. Will re-enable once the implementation is sufficiently stable for the bots.
R=hubbe@chromium.org, kalman@chromium.org
Review URL: https://codereview.chromium.org/184813009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255805 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/cast')
-rw-r--r-- | media/cast/cast_environment.cc | 55 | ||||
-rw-r--r-- | media/cast/cast_environment.h | 23 | ||||
-rw-r--r-- | media/cast/cast_receiver_impl.cc | 3 | ||||
-rw-r--r-- | media/cast/logging/logging_impl.cc | 35 | ||||
-rw-r--r-- | media/cast/logging/logging_impl.h | 12 | ||||
-rw-r--r-- | media/cast/logging/logging_impl_unittest.cc | 5 | ||||
-rw-r--r-- | media/cast/test/linux_output_window.cc | 9 | ||||
-rw-r--r-- | media/cast/test/linux_output_window.h | 1 | ||||
-rw-r--r-- | media/cast/test/receiver.cc | 144 | ||||
-rw-r--r-- | media/cast/test/utility/default_config.cc | 37 | ||||
-rw-r--r-- | media/cast/test/utility/default_config.h | 26 | ||||
-rw-r--r-- | media/cast/test/utility/in_process_receiver.cc | 126 | ||||
-rw-r--r-- | media/cast/test/utility/in_process_receiver.h | 113 | ||||
-rw-r--r-- | media/cast/test/utility/input_builder.cc | 6 | ||||
-rw-r--r-- | media/cast/test/utility/standalone_cast_environment.cc | 59 | ||||
-rw-r--r-- | media/cast/test/utility/standalone_cast_environment.h | 42 | ||||
-rw-r--r-- | media/cast/test/utility/utility.gyp | 14 | ||||
-rw-r--r-- | media/cast/transport/cast_transport_sender_impl.cc | 2 |
18 files changed, 527 insertions, 185 deletions
diff --git a/media/cast/cast_environment.cc b/media/cast/cast_environment.cc index 9b1a569..9077b52 100644 --- a/media/cast/cast_environment.cc +++ b/media/cast/cast_environment.cc @@ -29,23 +29,19 @@ CastEnvironment::CastEnvironment( scoped_refptr<SingleThreadTaskRunner> video_encode_thread_proxy, scoped_refptr<SingleThreadTaskRunner> video_decode_thread_proxy, scoped_refptr<SingleThreadTaskRunner> transport_thread_proxy, - const CastLoggingConfig& config) - : clock_(clock.Pass()), - main_thread_proxy_(main_thread_proxy), + const CastLoggingConfig& logging_config) + : main_thread_proxy_(main_thread_proxy), audio_encode_thread_proxy_(audio_encode_thread_proxy), audio_decode_thread_proxy_(audio_decode_thread_proxy), video_encode_thread_proxy_(video_encode_thread_proxy), video_decode_thread_proxy_(video_decode_thread_proxy), transport_thread_proxy_(transport_thread_proxy), - logging_(new LoggingImpl(main_thread_proxy, config)) { - DCHECK(main_thread_proxy); -} + clock_(clock.Pass()), + logging_(new LoggingImpl(logging_config)) {} CastEnvironment::~CastEnvironment() { // Logging must be deleted on the main thread. - if (main_thread_proxy_->RunsTasksOnCurrentThread()) { - logging_.reset(); - } else { + if (main_thread_proxy_ && !main_thread_proxy_->RunsTasksOnCurrentThread()) { main_thread_proxy_->PostTask( FROM_HERE, base::Bind(&DeleteLoggingOnMainThread, base::Passed(&logging_))); @@ -55,10 +51,7 @@ CastEnvironment::~CastEnvironment() { bool CastEnvironment::PostTask(ThreadId identifier, const tracked_objects::Location& from_here, const base::Closure& task) { - scoped_refptr<SingleThreadTaskRunner> task_runner = - GetMessageSingleThreadTaskRunnerForThread(identifier); - - return task_runner->PostTask(from_here, task); + return GetTaskRunner(identifier)->PostTask(from_here, task); } bool CastEnvironment::PostDelayedTask( @@ -66,15 +59,11 @@ bool CastEnvironment::PostDelayedTask( const tracked_objects::Location& from_here, const base::Closure& task, base::TimeDelta delay) { - scoped_refptr<SingleThreadTaskRunner> task_runner = - GetMessageSingleThreadTaskRunnerForThread(identifier); - - return task_runner->PostDelayedTask(from_here, task, delay); + return GetTaskRunner(identifier)->PostDelayedTask(from_here, task, delay); } -scoped_refptr<SingleThreadTaskRunner> -CastEnvironment::GetMessageSingleThreadTaskRunnerForThread( - ThreadId identifier) { +scoped_refptr<SingleThreadTaskRunner> CastEnvironment::GetTaskRunner( + ThreadId identifier) const { switch (identifier) { case CastEnvironment::MAIN: return main_thread_proxy_; @@ -97,30 +86,28 @@ CastEnvironment::GetMessageSingleThreadTaskRunnerForThread( bool CastEnvironment::CurrentlyOn(ThreadId identifier) { switch (identifier) { case CastEnvironment::MAIN: - return main_thread_proxy_->RunsTasksOnCurrentThread(); + return main_thread_proxy_ && + main_thread_proxy_->RunsTasksOnCurrentThread(); case CastEnvironment::AUDIO_ENCODER: - return audio_encode_thread_proxy_->RunsTasksOnCurrentThread(); + return audio_encode_thread_proxy_ && + audio_encode_thread_proxy_->RunsTasksOnCurrentThread(); case CastEnvironment::AUDIO_DECODER: - return audio_decode_thread_proxy_->RunsTasksOnCurrentThread(); + return audio_decode_thread_proxy_ && + audio_decode_thread_proxy_->RunsTasksOnCurrentThread(); case CastEnvironment::VIDEO_ENCODER: - return video_encode_thread_proxy_->RunsTasksOnCurrentThread(); + return video_encode_thread_proxy_ && + video_encode_thread_proxy_->RunsTasksOnCurrentThread(); case CastEnvironment::VIDEO_DECODER: - return video_decode_thread_proxy_->RunsTasksOnCurrentThread(); + return video_decode_thread_proxy_ && + video_decode_thread_proxy_->RunsTasksOnCurrentThread(); case CastEnvironment::TRANSPORT: - return transport_thread_proxy_->RunsTasksOnCurrentThread(); + return transport_thread_proxy_ && + transport_thread_proxy_->RunsTasksOnCurrentThread(); default: NOTREACHED() << "Invalid thread identifier"; return false; } } -base::TickClock* CastEnvironment::Clock() const { return clock_.get(); } - -LoggingImpl* CastEnvironment::Logging() { - DCHECK(CurrentlyOn(CastEnvironment::MAIN)) - << "Must be called from main thread"; - return logging_.get(); -} - } // namespace cast } // namespace media diff --git a/media/cast/cast_environment.h b/media/cast/cast_environment.h index 5abb5c7..95d4ccb 100644 --- a/media/cast/cast_environment.h +++ b/media/cast/cast_environment.h @@ -46,7 +46,7 @@ class CastEnvironment : public base::RefCountedThreadSafe<CastEnvironment> { scoped_refptr<base::SingleThreadTaskRunner> video_encode_thread_proxy, scoped_refptr<base::SingleThreadTaskRunner> video_decode_thread_proxy, scoped_refptr<base::SingleThreadTaskRunner> transport_thread_proxy, - const CastLoggingConfig& config); + const CastLoggingConfig& logging_config); // These are the same methods in message_loop.h, but are guaranteed to either // get posted to the MessageLoop if it's still alive, or be deleted otherwise. @@ -64,13 +64,15 @@ class CastEnvironment : public base::RefCountedThreadSafe<CastEnvironment> { bool CurrentlyOn(ThreadId identifier); - base::TickClock* Clock() const; + // All of the media::cast implementation must use this TickClock. + base::TickClock* Clock() const { return clock_.get(); } - // Logging is not thread safe. Should always be called from the main thread. - LoggingImpl* Logging(); + // Logging is not thread safe. Its methods should always be called from the + // main thread. + LoggingImpl* Logging() const { return logging_.get(); } - scoped_refptr<base::SingleThreadTaskRunner> - GetMessageSingleThreadTaskRunnerForThread(ThreadId identifier); + scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner( + ThreadId identifier) const; bool HasAudioEncoderThread() { return audio_encode_thread_proxy_ ? true : false; @@ -83,10 +85,7 @@ class CastEnvironment : public base::RefCountedThreadSafe<CastEnvironment> { protected: virtual ~CastEnvironment(); - private: - friend class base::RefCountedThreadSafe<CastEnvironment>; - - scoped_ptr<base::TickClock> clock_; + // Subclasses may override these. scoped_refptr<base::SingleThreadTaskRunner> main_thread_proxy_; scoped_refptr<base::SingleThreadTaskRunner> audio_encode_thread_proxy_; scoped_refptr<base::SingleThreadTaskRunner> audio_decode_thread_proxy_; @@ -94,6 +93,10 @@ class CastEnvironment : public base::RefCountedThreadSafe<CastEnvironment> { scoped_refptr<base::SingleThreadTaskRunner> video_decode_thread_proxy_; scoped_refptr<base::SingleThreadTaskRunner> transport_thread_proxy_; + private: + friend class base::RefCountedThreadSafe<CastEnvironment>; + + scoped_ptr<base::TickClock> clock_; scoped_ptr<LoggingImpl> logging_; DISALLOW_COPY_AND_ASSIGN(CastEnvironment); diff --git a/media/cast/cast_receiver_impl.cc b/media/cast/cast_receiver_impl.cc index cca6492..f9fc5a6 100644 --- a/media/cast/cast_receiver_impl.cc +++ b/media/cast/cast_receiver_impl.cc @@ -98,8 +98,7 @@ CastReceiverImpl::CastReceiverImpl( transport::PacketSender* const packet_sender) : pacer_(cast_environment->Clock(), packet_sender, - cast_environment->GetMessageSingleThreadTaskRunnerForThread( - CastEnvironment::TRANSPORT)), + cast_environment->GetTaskRunner(CastEnvironment::TRANSPORT)), audio_receiver_(cast_environment, audio_config, &pacer_), video_receiver_(cast_environment, video_config, &pacer_), frame_receiver_(new LocalFrameReceiver(cast_environment, diff --git a/media/cast/logging/logging_impl.cc b/media/cast/logging/logging_impl.cc index ec0099c..7bfc474 100644 --- a/media/cast/logging/logging_impl.cc +++ b/media/cast/logging/logging_impl.cc @@ -9,20 +9,19 @@ namespace media { namespace cast { -LoggingImpl::LoggingImpl( - scoped_refptr<base::SingleThreadTaskRunner> main_thread_proxy, - const CastLoggingConfig& config) - : main_thread_proxy_(main_thread_proxy), - config_(config), - raw_(), - stats_() {} +LoggingImpl::LoggingImpl(const CastLoggingConfig& config) + : config_(config), raw_(), stats_() { + // LoggingImpl can be constructed on any thread, but its methods should all be + // called on the same thread. + thread_checker_.DetachFromThread(); +} LoggingImpl::~LoggingImpl() {} void LoggingImpl::InsertFrameEvent(const base::TimeTicks& time_of_event, CastLoggingEvent event, uint32 rtp_timestamp, uint32 frame_id) { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); if (config_.enable_raw_data_collection) { raw_.InsertFrameEvent(time_of_event, event, rtp_timestamp, frame_id); } @@ -40,7 +39,7 @@ void LoggingImpl::InsertFrameEventWithSize(const base::TimeTicks& time_of_event, CastLoggingEvent event, uint32 rtp_timestamp, uint32 frame_id, int frame_size) { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); if (config_.enable_raw_data_collection) { raw_.InsertFrameEventWithSize(time_of_event, event, rtp_timestamp, frame_id, frame_size); @@ -61,7 +60,7 @@ void LoggingImpl::InsertFrameEventWithSize(const base::TimeTicks& time_of_event, void LoggingImpl::InsertFrameEventWithDelay( const base::TimeTicks& time_of_event, CastLoggingEvent event, uint32 rtp_timestamp, uint32 frame_id, base::TimeDelta delay) { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); if (config_.enable_raw_data_collection) { raw_.InsertFrameEventWithDelay(time_of_event, event, rtp_timestamp, frame_id, delay); @@ -82,7 +81,7 @@ void LoggingImpl::InsertFrameEventWithDelay( void LoggingImpl::InsertPacketListEvent(const base::TimeTicks& time_of_event, CastLoggingEvent event, const PacketList& packets) { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); for (unsigned int i = 0; i < packets.size(); ++i) { const Packet& packet = packets[i]; // Parse basic properties. @@ -107,7 +106,7 @@ void LoggingImpl::InsertPacketEvent(const base::TimeTicks& time_of_event, uint32 rtp_timestamp, uint32 frame_id, uint16 packet_id, uint16 max_packet_id, size_t size) { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); if (config_.enable_raw_data_collection) { raw_.InsertPacketEvent(time_of_event, event, rtp_timestamp, frame_id, packet_id, max_packet_id, size); @@ -126,7 +125,7 @@ void LoggingImpl::InsertPacketEvent(const base::TimeTicks& time_of_event, void LoggingImpl::InsertGenericEvent(const base::TimeTicks& time_of_event, CastLoggingEvent event, int value) { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); if (config_.enable_raw_data_collection) { raw_.InsertGenericEvent(time_of_event, event, value); } @@ -142,31 +141,33 @@ void LoggingImpl::InsertGenericEvent(const base::TimeTicks& time_of_event, } void LoggingImpl::AddRawEventSubscriber(RawEventSubscriber* subscriber) { + DCHECK(thread_checker_.CalledOnValidThread()); raw_.AddSubscriber(subscriber); } void LoggingImpl::RemoveRawEventSubscriber(RawEventSubscriber* subscriber) { + DCHECK(thread_checker_.CalledOnValidThread()); raw_.RemoveSubscriber(subscriber); } FrameStatsMap LoggingImpl::GetFrameStatsData(EventMediaType media_type) const { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); return stats_.GetFrameStatsData(media_type); } PacketStatsMap LoggingImpl::GetPacketStatsData( EventMediaType media_type) const { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); return stats_.GetPacketStatsData(media_type); } GenericStatsMap LoggingImpl::GetGenericStatsData() const { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); return stats_.GetGenericStatsData(); } void LoggingImpl::ResetStats() { - DCHECK(main_thread_proxy_->RunsTasksOnCurrentThread()); + DCHECK(thread_checker_.CalledOnValidThread()); stats_.Reset(); } diff --git a/media/cast/logging/logging_impl.h b/media/cast/logging/logging_impl.h index e51b114..d8fb292 100644 --- a/media/cast/logging/logging_impl.h +++ b/media/cast/logging/logging_impl.h @@ -10,7 +10,7 @@ // 2. Tracing of raw events. #include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" +#include "base/threading/thread_checker.h" #include "media/cast/cast_config.h" #include "media/cast/logging/logging_defines.h" #include "media/cast/logging/logging_raw.h" @@ -19,14 +19,14 @@ namespace media { namespace cast { -// Should only be called from the main thread. -class LoggingImpl : public base::NonThreadSafe { +class LoggingImpl { public: - LoggingImpl(scoped_refptr<base::SingleThreadTaskRunner> main_thread_proxy, - const CastLoggingConfig& config); + explicit LoggingImpl(const CastLoggingConfig& config); ~LoggingImpl(); + // Note: All methods below should be called from the same thread. + void InsertFrameEvent(const base::TimeTicks& time_of_event, CastLoggingEvent event, uint32 rtp_timestamp, uint32 frame_id); @@ -66,7 +66,7 @@ class LoggingImpl : public base::NonThreadSafe { void ResetStats(); private: - scoped_refptr<base::SingleThreadTaskRunner> main_thread_proxy_; + base::ThreadChecker thread_checker_; const CastLoggingConfig config_; LoggingRaw raw_; LoggingStats stats_; diff --git a/media/cast/logging/logging_impl_unittest.cc b/media/cast/logging/logging_impl_unittest.cc index 05d7056..92da7c1 100644 --- a/media/cast/logging/logging_impl_unittest.cc +++ b/media/cast/logging/logging_impl_unittest.cc @@ -11,7 +11,6 @@ #include "media/cast/logging/logging_defines.h" #include "media/cast/logging/logging_impl.h" #include "media/cast/logging/simple_event_subscriber.h" -#include "media/cast/test/fake_single_thread_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" namespace media { @@ -34,8 +33,7 @@ class LoggingImplTest : public ::testing::Test { testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kStartMillisecond)); - task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); - logging_.reset(new LoggingImpl(task_runner_, config_)); + logging_.reset(new LoggingImpl(config_)); logging_->AddRawEventSubscriber(&event_subscriber_); } @@ -44,7 +42,6 @@ class LoggingImplTest : public ::testing::Test { } CastLoggingConfig config_; - scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; scoped_ptr<LoggingImpl> logging_; base::SimpleTestTickClock testing_clock_; SimpleEventSubscriber event_subscriber_; diff --git a/media/cast/test/linux_output_window.cc b/media/cast/test/linux_output_window.cc index 735e0dd..389bb0f 100644 --- a/media/cast/test/linux_output_window.cc +++ b/media/cast/test/linux_output_window.cc @@ -106,7 +106,6 @@ void LinuxOutputWindow::CreateWindow(int x_pos, VLOG(1) << "XShmCreateImage failed"; NOTREACHED(); } - render_buffer_ = reinterpret_cast<uint8_t*>(image_->data); shminfo_.readOnly = false; // Attach image to display. @@ -119,14 +118,16 @@ void LinuxOutputWindow::CreateWindow(int x_pos, void LinuxOutputWindow::RenderFrame( const scoped_refptr<media::VideoFrame>& video_frame) { + CHECK_LE(video_frame->coded_size().width(), image_->width); + CHECK_LE(video_frame->coded_size().height(), image_->height); libyuv::I420ToARGB(video_frame->data(VideoFrame::kYPlane), video_frame->stride(VideoFrame::kYPlane), video_frame->data(VideoFrame::kUPlane), video_frame->stride(VideoFrame::kUPlane), video_frame->data(VideoFrame::kVPlane), video_frame->stride(VideoFrame::kVPlane), - render_buffer_, - video_frame->stride(VideoFrame::kYPlane) * 4, + reinterpret_cast<uint8_t*>(image_->data), + image_->bytes_per_line, video_frame->coded_size().width(), video_frame->coded_size().height()); @@ -149,4 +150,4 @@ void LinuxOutputWindow::RenderFrame( } // namespace test } // namespace cast -} // namespace media
\ No newline at end of file +} // namespace media diff --git a/media/cast/test/linux_output_window.h b/media/cast/test/linux_output_window.h index 9a68bff8..5907da20 100644 --- a/media/cast/test/linux_output_window.h +++ b/media/cast/test/linux_output_window.h @@ -41,7 +41,6 @@ class LinuxOutputWindow { int width, int height, const std::string& name); - uint8* render_buffer_; Display* display_; Window window_; XShmSegmentInfo shminfo_; diff --git a/media/cast/test/receiver.cc b/media/cast/test/receiver.cc index 6c3097f..213d8aa 100644 --- a/media/cast/test/receiver.cc +++ b/media/cast/test/receiver.cc @@ -21,7 +21,10 @@ #include "media/cast/cast_environment.h" #include "media/cast/cast_receiver.h" #include "media/cast/logging/logging_defines.h" +#include "media/cast/test/utility/default_config.h" +#include "media/cast/test/utility/in_process_receiver.h" #include "media/cast/test/utility/input_builder.h" +#include "media/cast/test/utility/standalone_cast_environment.h" #include "media/cast/transport/transport/udp_transport.h" #include "net/base/net_util.h" @@ -31,6 +34,7 @@ namespace media { namespace cast { + // Settings chosen to match default sender settings. #define DEFAULT_SEND_PORT "0" #define DEFAULT_RECEIVE_PORT "2344" @@ -46,12 +50,10 @@ namespace cast { #define DEFAULT_VIDEO_CODEC_HEIGHT "480" #define DEFAULT_VIDEO_CODEC_BITRATE "2000" -static const int kAudioSamplingFrequency = 48000; #if defined(OS_LINUX) const int kVideoWindowWidth = 1280; const int kVideoWindowHeight = 720; #endif // OS_LINUX -static const int kFrameTimerMs = 33; void GetPorts(int* tx_port, int* rx_port) { test::InputBuilder tx_input( @@ -103,18 +105,9 @@ void GetPayloadtype(AudioReceiverConfig* audio_config) { } AudioReceiverConfig GetAudioReceiverConfig() { - AudioReceiverConfig audio_config; - + AudioReceiverConfig audio_config = GetDefaultAudioReceiverConfig(); GetSsrcs(&audio_config); GetPayloadtype(&audio_config); - - audio_config.rtcp_c_name = "audio_receiver@a.b.c.d"; - - VLOG(1) << "Using OPUS 48Khz stereo"; - audio_config.use_external_decoder = false; - audio_config.frequency = 48000; - audio_config.channels = 2; - audio_config.codec = transport::kOpus; return audio_config; } @@ -127,28 +120,26 @@ void GetPayloadtype(VideoReceiverConfig* video_config) { } VideoReceiverConfig GetVideoReceiverConfig() { - VideoReceiverConfig video_config; - + VideoReceiverConfig video_config = GetDefaultVideoReceiverConfig(); GetSsrcs(&video_config); GetPayloadtype(&video_config); - - video_config.rtcp_c_name = "video_receiver@a.b.c.d"; - - video_config.use_external_decoder = false; - - VLOG(1) << "Using VP8"; - video_config.codec = transport::kVp8; return video_config; } -static void UpdateCastTransportStatus(transport::CastTransportStatus status) { - VLOG(1) << "CastTransportStatus = " << status; -} - -class ReceiveProcess : public base::RefCountedThreadSafe<ReceiveProcess> { +// An InProcessReceiver that renders video frames to a LinuxOutputWindow. While +// it does receive audio frames, it does not play them. +class ReceiverDisplay : public InProcessReceiver { public: - explicit ReceiveProcess(scoped_refptr<FrameReceiver> frame_receiver) - : frame_receiver_(frame_receiver), + ReceiverDisplay(const scoped_refptr<CastEnvironment>& cast_environment, + const net::IPEndPoint& local_end_point, + const net::IPEndPoint& remote_end_point, + const AudioReceiverConfig& audio_config, + const VideoReceiverConfig& video_config) + : InProcessReceiver(cast_environment, + local_end_point, + remote_end_point, + audio_config, + video_config), #if defined(OS_LINUX) render_(0, 0, kVideoWindowWidth, kVideoWindowHeight, "Cast_receiver"), #endif // OS_LINUX @@ -156,62 +147,34 @@ class ReceiveProcess : public base::RefCountedThreadSafe<ReceiveProcess> { last_render_time_() { } - void Start() { - GetAudioFrame(base::TimeDelta::FromMilliseconds(kFrameTimerMs)); - GetVideoFrame(); - } + virtual ~ReceiverDisplay() {} protected: - virtual ~ReceiveProcess() {} - - private: - friend class base::RefCountedThreadSafe<ReceiveProcess>; - - void DisplayFrame(const scoped_refptr<media::VideoFrame>& video_frame, - const base::TimeTicks& render_time) { + virtual void OnVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame, + const base::TimeTicks& render_time) OVERRIDE { #ifdef OS_LINUX render_.RenderFrame(video_frame); #endif // OS_LINUX // Print out the delta between frames. if (!last_render_time_.is_null()) { base::TimeDelta time_diff = render_time - last_render_time_; - VLOG(1) << " RenderDelay[mS] = " << time_diff.InMilliseconds(); + VLOG(1) << "Size = " << video_frame->coded_size().ToString() + << "; RenderDelay[mS] = " << time_diff.InMilliseconds(); } last_render_time_ = render_time; - GetVideoFrame(); } - void ReceiveAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, - const base::TimeTicks& playout_time) { + virtual void OnAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, + const base::TimeTicks& playout_time) OVERRIDE { // For audio just print the playout delta between audio frames. - // Default diff time is kFrameTimerMs. - base::TimeDelta time_diff = - base::TimeDelta::FromMilliseconds(kFrameTimerMs); if (!last_playout_time_.is_null()) { - time_diff = playout_time - last_playout_time_; - VLOG(1) << " ***PlayoutDelay[mS] = " << time_diff.InMilliseconds(); + base::TimeDelta time_diff = playout_time - last_playout_time_; + VLOG(1) << "SampleRate = " << audio_frame->frequency + << "; PlayoutDelay[mS] = " << time_diff.InMilliseconds(); } last_playout_time_ = playout_time; } - void GetAudioFrame(base::TimeDelta playout_diff) { - int num_10ms_blocks = playout_diff.InMilliseconds() / 10; - frame_receiver_->GetRawAudioFrame( - num_10ms_blocks, - kAudioSamplingFrequency, - base::Bind(&ReceiveProcess::ReceiveAudioFrame, this)); - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&ReceiveProcess::GetAudioFrame, this, playout_diff), - playout_diff); - } - - void GetVideoFrame() { - frame_receiver_->GetRawVideoFrame( - base::Bind(&ReceiveProcess::DisplayFrame, this)); - } - - scoped_refptr<FrameReceiver> frame_receiver_; #ifdef OS_LINUX test::LinuxOutputWindow render_; #endif // OS_LINUX @@ -224,32 +187,15 @@ class ReceiveProcess : public base::RefCountedThreadSafe<ReceiveProcess> { int main(int argc, char** argv) { base::AtExitManager at_exit; - base::MessageLoopForIO main_message_loop; CommandLine::Init(argc, argv); InitLogging(logging::LoggingSettings()); - VLOG(1) << "Cast Receiver"; - base::Thread audio_thread("Cast audio decoder thread"); - base::Thread video_thread("Cast video decoder thread"); - audio_thread.Start(); - video_thread.Start(); - - scoped_ptr<base::TickClock> clock(new base::DefaultTickClock()); - - // Enable main and receiver side threads only. Enable raw event logging. - // Running transport on the main thread. + // Enable raw event logging only. media::cast::CastLoggingConfig logging_config; logging_config.enable_raw_data_collection = true; scoped_refptr<media::cast::CastEnvironment> cast_environment( - new media::cast::CastEnvironment(clock.Pass(), - main_message_loop.message_loop_proxy(), - NULL, - audio_thread.message_loop_proxy(), - NULL, - video_thread.message_loop_proxy(), - main_message_loop.message_loop_proxy(), - logging_config)); + new media::cast::StandaloneCastEnvironment(logging_config)); media::cast::AudioReceiverConfig audio_config = media::cast::GetAudioReceiverConfig(); @@ -281,23 +227,15 @@ int main(int argc, char** argv) { net::IPEndPoint remote_end_point(remote_ip_number, remote_port); net::IPEndPoint local_end_point(local_ip_number, local_port); - scoped_ptr<media::cast::transport::UdpTransport> transport( - new media::cast::transport::UdpTransport( - NULL, - main_message_loop.message_loop_proxy(), - local_end_point, - remote_end_point, - base::Bind(&media::cast::UpdateCastTransportStatus))); - scoped_ptr<media::cast::CastReceiver> cast_receiver( - media::cast::CastReceiver::CreateCastReceiver( - cast_environment, audio_config, video_config, transport.get())); - - // TODO(hubbe): Make the cast receiver do this automatically. - transport->StartReceiving(cast_receiver->packet_receiver()); - - scoped_refptr<media::cast::ReceiveProcess> receive_process( - new media::cast::ReceiveProcess(cast_receiver->frame_receiver())); - receive_process->Start(); - main_message_loop.Run(); + media::cast::ReceiverDisplay* const receiver_display = + new media::cast::ReceiverDisplay(cast_environment, + local_end_point, + remote_end_point, + audio_config, + video_config); + receiver_display->Start(); + + base::MessageLoop().Run(); // Run forever (i.e., until SIGTERM). + NOTREACHED(); return 0; } diff --git a/media/cast/test/utility/default_config.cc b/media/cast/test/utility/default_config.cc new file mode 100644 index 0000000..350bd517 --- /dev/null +++ b/media/cast/test/utility/default_config.cc @@ -0,0 +1,37 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/cast/test/utility/default_config.h" + +#include "media/cast/transport/cast_transport_config.h" + +namespace media { +namespace cast { + +AudioReceiverConfig GetDefaultAudioReceiverConfig() { + AudioReceiverConfig config; + config.feedback_ssrc = 1; + config.incoming_ssrc = 2; + config.rtp_payload_type = 127; + config.rtcp_c_name = "audio_receiver@a.b.c.d"; + config.use_external_decoder = false; + config.frequency = 48000; + config.channels = 2; + config.codec = media::cast::transport::kOpus; + return config; +} + +VideoReceiverConfig GetDefaultVideoReceiverConfig() { + VideoReceiverConfig config; + config.feedback_ssrc = 12; + config.incoming_ssrc = 11; + config.rtp_payload_type = 96; + config.rtcp_c_name = "video_receiver@a.b.c.d"; + config.use_external_decoder = false; + config.codec = media::cast::transport::kVp8; + return config; +} + +} // namespace cast +} // namespace media diff --git a/media/cast/test/utility/default_config.h b/media/cast/test/utility/default_config.h new file mode 100644 index 0000000..ef7c79a --- /dev/null +++ b/media/cast/test/utility/default_config.h @@ -0,0 +1,26 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CAST_TEST_UTILITY_DEFAULT_CONFIG_H_ +#define MEDIA_CAST_TEST_UTILITY_DEFAULT_CONFIG_H_ + +#include "media/cast/cast_config.h" + +namespace media { +namespace cast { + +// Returns an AudioReceiverConfig initialized to "good-to-go" values. This +// specifies 48 kHz, 2-channel Opus-coded audio, with standard ssrc's, payload +// type, and a dummy name. +AudioReceiverConfig GetDefaultAudioReceiverConfig(); + +// Returns a VideoReceiverConfig initialized to "good-to-go" values. This +// specifies VP8-coded video, with standard ssrc's, payload type, and a dummy +// name. +VideoReceiverConfig GetDefaultVideoReceiverConfig(); + +} // namespace cast +} // namespace media + +#endif // MEDIA_CAST_TEST_UTILITY_DEFAULT_CONFIG_H_ diff --git a/media/cast/test/utility/in_process_receiver.cc b/media/cast/test/utility/in_process_receiver.cc new file mode 100644 index 0000000..f916dbb --- /dev/null +++ b/media/cast/test/utility/in_process_receiver.cc @@ -0,0 +1,126 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/cast/test/utility/in_process_receiver.h" + +#include "base/bind_helpers.h" +#include "base/time/time.h" +#include "media/base/video_frame.h" +#include "media/cast/cast_config.h" +#include "media/cast/cast_environment.h" +#include "media/cast/cast_receiver.h" +#include "media/cast/transport/cast_transport_config.h" +#include "media/cast/transport/transport/udp_transport.h" + +using media::cast::transport::CastTransportStatus; +using media::cast::transport::UdpTransport; + +namespace media { +namespace cast { + +InProcessReceiver::InProcessReceiver( + const scoped_refptr<CastEnvironment>& cast_environment, + const net::IPEndPoint& local_end_point, + const net::IPEndPoint& remote_end_point, + const AudioReceiverConfig& audio_config, + const VideoReceiverConfig& video_config) + : cast_environment_(cast_environment), + local_end_point_(local_end_point), + remote_end_point_(remote_end_point), + audio_config_(audio_config), + video_config_(video_config), + weak_factory_(this) {} + +InProcessReceiver::~InProcessReceiver() { + DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); +} + +void InProcessReceiver::Start() { + cast_environment_->PostTask(CastEnvironment::MAIN, + FROM_HERE, + base::Bind(&InProcessReceiver::StartOnMainThread, + base::Unretained(this))); +} + +void InProcessReceiver::DestroySoon() { + cast_environment_->PostTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(&InProcessReceiver::WillDestroyReceiver, base::Owned(this))); +} + +void InProcessReceiver::UpdateCastTransportStatus(CastTransportStatus status) { + LOG_IF(ERROR, status == media::cast::transport::TRANSPORT_SOCKET_ERROR) + << "Transport socket error occurred. InProcessReceiver is likely dead."; + VLOG(1) << "CastTransportStatus is now " << status; +} + +void InProcessReceiver::StartOnMainThread() { + DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); + + DCHECK(!transport_ && !cast_receiver_); + transport_.reset( + new UdpTransport(NULL, + cast_environment_->GetTaskRunner(CastEnvironment::MAIN), + local_end_point_, + remote_end_point_, + base::Bind(&InProcessReceiver::UpdateCastTransportStatus, + base::Unretained(this)))); + cast_receiver_.reset(CastReceiver::CreateCastReceiver( + cast_environment_, audio_config_, video_config_, transport_.get())); + + // TODO(hubbe): Make the cast receiver do this automatically. + transport_->StartReceiving(cast_receiver_->packet_receiver()); + + PullNextAudioFrame(); + PullNextVideoFrame(); +} + +void InProcessReceiver::GotAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, + const base::TimeTicks& playout_time) { + DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); + OnAudioFrame(audio_frame.Pass(), playout_time); + // TODO(miu): Put this back here: PullNextAudioFrame(); +} + +void InProcessReceiver::GotVideoFrame( + const scoped_refptr<VideoFrame>& video_frame, + const base::TimeTicks& render_time) { + DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); + OnVideoFrame(video_frame, render_time); + PullNextVideoFrame(); +} + +void InProcessReceiver::PullNextAudioFrame() { + DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); + cast_receiver_->frame_receiver()->GetRawAudioFrame( + 1 /* 10 ms of samples */, + audio_config_.frequency, + base::Bind(&InProcessReceiver::GotAudioFrame, + weak_factory_.GetWeakPtr())); + // TODO(miu): Fix audio decoder so that it never drops a request for the next + // frame of audio. Once fixed, remove this, and add PullNextAudioFrame() to + // the end of GotAudioFrame(), so that it behaves just like GotVideoFrame(). + // http://crbug.com/347361 + cast_environment_->PostDelayedTask( + CastEnvironment::MAIN, + FROM_HERE, + base::Bind(&InProcessReceiver::PullNextAudioFrame, + weak_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(10)); +} + +void InProcessReceiver::PullNextVideoFrame() { + DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); + cast_receiver_->frame_receiver()->GetRawVideoFrame(base::Bind( + &InProcessReceiver::GotVideoFrame, weak_factory_.GetWeakPtr())); +} + +// static +void InProcessReceiver::WillDestroyReceiver(InProcessReceiver* receiver) { + DCHECK(receiver->cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); +} + +} // namespace cast +} // namespace media diff --git a/media/cast/test/utility/in_process_receiver.h b/media/cast/test/utility/in_process_receiver.h new file mode 100644 index 0000000..57d8a86 --- /dev/null +++ b/media/cast/test/utility/in_process_receiver.h @@ -0,0 +1,113 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CAST_TEST_IN_PROCESS_RECEIVER_H_ +#define MEDIA_CAST_TEST_IN_PROCESS_RECEIVER_H_ + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "media/cast/cast_config.h" +#include "media/cast/transport/cast_transport_config.h" + +namespace base { +class TimeTicks; +} // namespace base + +namespace net { +class IPEndPoint; +} // namespace net + +namespace media { + +class VideoFrame; + +namespace cast { + +class CastEnvironment; +class CastReceiver; + +namespace transport { +class UdpTransport; +} // namespace transport + +// Common base functionality for an in-process Cast receiver. This is meant to +// be subclassed with the OnAudioFrame() and OnVideoFrame() methods implemented, +// so that the implementor can focus on what is to be done with the frames, +// rather than on the boilerplate "glue" code. +class InProcessReceiver { + public: + // Construct a receiver with the given configuration. |remote_end_point| can + // be left empty, if the transport should automatically mate with the first + // remote sender it encounters. + InProcessReceiver(const scoped_refptr<CastEnvironment>& cast_environment, + const net::IPEndPoint& local_end_point, + const net::IPEndPoint& remote_end_point, + const AudioReceiverConfig& audio_config, + const VideoReceiverConfig& video_config); + + // Must be destroyed on the cast MAIN thread. See DestroySoon(). + virtual ~InProcessReceiver(); + + // Convenience accessor to CastEnvironment. + scoped_refptr<CastEnvironment> cast_env() const { return cast_environment_; } + + // Begin delivering any received audio/video frames to the OnXXXFrame() + // methods. + void Start(); + + // Schedules destruction on the cast MAIN thread. Any external references to + // the InProcessReceiver instance become invalid. + void DestroySoon(); + + protected: + // To be implemented by subclasses. These are called on the Cast MAIN thread + // as each frame is received. + virtual void OnAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, + const base::TimeTicks& playout_time) = 0; + virtual void OnVideoFrame(const scoped_refptr<VideoFrame>& video_frame, + const base::TimeTicks& render_time) = 0; + + // Helper method that creates |transport_| and |cast_receiver_|, starts + // |transport_| receiving, and requests the first audio/video frame. + // Subclasses may override to provide additional start-up functionality. + virtual void StartOnMainThread(); + + // Callback for the transport to notify of status changes. A default + // implementation is provided here that simply logs socket errors. + virtual void UpdateCastTransportStatus(transport::CastTransportStatus status); + + private: + friend class base::RefCountedThreadSafe<InProcessReceiver>; + + // CastReceiver callbacks that receive a frame and then request another. + void GotAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, + const base::TimeTicks& playout_time); + void GotVideoFrame(const scoped_refptr<VideoFrame>& video_frame, + const base::TimeTicks& render_time); + void PullNextAudioFrame(); + void PullNextVideoFrame(); + + // Invoked just before the destruction of |receiver| on the cast MAIN thread. + static void WillDestroyReceiver(InProcessReceiver* receiver); + + const scoped_refptr<CastEnvironment> cast_environment_; + const net::IPEndPoint local_end_point_; + const net::IPEndPoint remote_end_point_; + const AudioReceiverConfig audio_config_; + const VideoReceiverConfig video_config_; + + scoped_ptr<transport::UdpTransport> transport_; + scoped_ptr<CastReceiver> cast_receiver_; + + // For shutdown safety, this member must be last: + base::WeakPtrFactory<InProcessReceiver> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(InProcessReceiver); +}; + +} // namespace cast +} // namespace media + +#endif // MEDIA_CAST_TEST_IN_PROCESS_RECEIVER_H_ diff --git a/media/cast/test/utility/input_builder.cc b/media/cast/test/utility/input_builder.cc index 08b7405..73dfb3f 100644 --- a/media/cast/test/utility/input_builder.cc +++ b/media/cast/test/utility/input_builder.cc @@ -7,6 +7,7 @@ #include <stdlib.h> #include <cstdio> +#include "base/command_line.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" @@ -14,6 +15,8 @@ namespace media { namespace cast { namespace test { +static const char kEnablePromptsSwitch[] = "enable-prompts"; + InputBuilder::InputBuilder(const std::string& title, const std::string& default_value, int low_range, @@ -26,6 +29,9 @@ InputBuilder::InputBuilder(const std::string& title, InputBuilder::~InputBuilder() {} std::string InputBuilder::GetStringInput() const { + if (!CommandLine::ForCurrentProcess()->HasSwitch(kEnablePromptsSwitch)) + return default_value_; + printf("\n%s\n", title_.c_str()); if (!default_value_.empty()) printf("Hit enter for default (%s):\n", default_value_.c_str()); diff --git a/media/cast/test/utility/standalone_cast_environment.cc b/media/cast/test/utility/standalone_cast_environment.cc new file mode 100644 index 0000000..7e82620 --- /dev/null +++ b/media/cast/test/utility/standalone_cast_environment.cc @@ -0,0 +1,59 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/cast/test/utility/standalone_cast_environment.h" + +#include "base/time/default_tick_clock.h" + +namespace media { +namespace cast { + +StandaloneCastEnvironment::StandaloneCastEnvironment( + const CastLoggingConfig& logging_config) + : CastEnvironment( + make_scoped_ptr<base::TickClock>(new base::DefaultTickClock()), + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + logging_config), + main_thread_("StandaloneCastEnvironment Main"), + audio_encode_thread_("StandaloneCastEnvironment Audio Encode"), + audio_decode_thread_("StandaloneCastEnvironment Audio Decode"), + video_encode_thread_("StandaloneCastEnvironment Video Encode"), + video_decode_thread_("StandaloneCastEnvironment Video Decode"), + transport_thread_("StandaloneCastEnvironment Transport") { +#define CREATE_TASK_RUNNER(name, options) \ + name##_thread_.StartWithOptions(options); \ + CastEnvironment::name##_thread_proxy_ = name##_thread_.message_loop_proxy() + + CREATE_TASK_RUNNER(main, + base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + CREATE_TASK_RUNNER(audio_encode, base::Thread::Options()); + CREATE_TASK_RUNNER(audio_decode, base::Thread::Options()); + CREATE_TASK_RUNNER(video_encode, base::Thread::Options()); + CREATE_TASK_RUNNER(video_decode, base::Thread::Options()); + CREATE_TASK_RUNNER(transport, base::Thread::Options()); + +#undef CREATE_TASK_RUNNER +} + +StandaloneCastEnvironment::~StandaloneCastEnvironment() { + DCHECK(CalledOnValidThread()); +} + +void StandaloneCastEnvironment::Shutdown() { + DCHECK(CalledOnValidThread()); + main_thread_.Stop(); + audio_encode_thread_.Stop(); + audio_decode_thread_.Stop(); + video_encode_thread_.Stop(); + video_decode_thread_.Stop(); + transport_thread_.Stop(); +} + +} // namespace cast +} // namespace media diff --git a/media/cast/test/utility/standalone_cast_environment.h b/media/cast/test/utility/standalone_cast_environment.h new file mode 100644 index 0000000..39c6e7c --- /dev/null +++ b/media/cast/test/utility/standalone_cast_environment.h @@ -0,0 +1,42 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CAST_TEST_UTILITY_STANDALONE_CAST_ENVIRONMENT_H_ +#define MEDIA_CAST_TEST_UTILITY_STANDALONE_CAST_ENVIRONMENT_H_ + +#include "base/threading/thread.h" +#include "base/threading/thread_checker.h" +#include "media/cast/cast_environment.h" + +namespace media { +namespace cast { + +// A complete CastEnvironment where all task runners are spurned from +// internally-owned threads. Uses base::DefaultTickClock as a clock. +class StandaloneCastEnvironment : public CastEnvironment, + public base::ThreadChecker { + public: + explicit StandaloneCastEnvironment(const CastLoggingConfig& logging_config); + + // Stops all threads backing the task runners, blocking the caller until + // complete. + void Shutdown(); + + private: + virtual ~StandaloneCastEnvironment(); + + base::Thread main_thread_; + base::Thread audio_encode_thread_; + base::Thread audio_decode_thread_; + base::Thread video_encode_thread_; + base::Thread video_decode_thread_; + base::Thread transport_thread_; + + DISALLOW_COPY_AND_ASSIGN(StandaloneCastEnvironment); +}; + +} // namespace cast +} // namespace media + +#endif // MEDIA_CAST_TEST_UTILITY_STANDALONE_CAST_ENVIRONMENT_H_ diff --git a/media/cast/test/utility/utility.gyp b/media/cast/test/utility/utility.gyp index 93e2f14..c1dc644 100644 --- a/media/cast/test/utility/utility.gyp +++ b/media/cast/test/utility/utility.gyp @@ -11,6 +11,8 @@ '<(DEPTH)/', ], 'dependencies': [ + '../../cast_receiver.gyp:cast_receiver', + '../../transport/cast_transport.gyp:cast_transport', '<(DEPTH)/ui/gfx/gfx.gyp:gfx', '<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry', '<(DEPTH)/testing/gtest.gyp:gtest', @@ -20,13 +22,19 @@ 'sources': [ '<(DEPTH)/media/cast/test/fake_single_thread_task_runner.cc', '<(DEPTH)/media/cast/test/fake_single_thread_task_runner.h', - 'input_builder.cc', - 'input_builder.h', 'audio_utility.cc', 'audio_utility.h', + 'default_config.cc', + 'default_config.h', + 'in_process_receiver.cc', + 'in_process_receiver.h', + 'input_builder.cc', + 'input_builder.h', + 'standalone_cast_environment.cc', + 'standalone_cast_environment.h', 'video_utility.cc', 'video_utility.h', ], # source }, ], -}
\ No newline at end of file +} diff --git a/media/cast/transport/cast_transport_sender_impl.cc b/media/cast/transport/cast_transport_sender_impl.cc index 38f10f8..7754e54 100644 --- a/media/cast/transport/cast_transport_sender_impl.cc +++ b/media/cast/transport/cast_transport_sender_impl.cc @@ -59,7 +59,7 @@ CastTransportSenderImpl::CastTransportSenderImpl( external_transport ? external_transport : transport_.get(), transport_task_runner), rtcp_builder_(&pacer_), - logging_(transport_task_runner, logging_config), + logging_(logging_config), raw_events_callback_(raw_events_callback) { if (!raw_events_callback_.is_null()) { DCHECK(logging_config.enable_raw_data_collection); |