// 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. // A fake media source that generates video and audio frames to a cast // sender. // This class can transcode a WebM file using FFmpeg. It can also // generate an animation and audio of fixed frequency. #ifndef MEDIA_CAST_TEST_FAKE_MEDIA_SOURCE_H_ #define MEDIA_CAST_TEST_FAKE_MEDIA_SOURCE_H_ #include #include "base/files/file_path.h" #include "base/files/memory_mapped_file.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/time/tick_clock.h" #include "media/audio/audio_parameters.h" #include "media/base/audio_converter.h" #include "media/cast/cast_config.h" #include "media/filters/audio_renderer_algorithm.h" #include "media/filters/ffmpeg_demuxer.h" struct AVCodecContext; struct AVFormatContext; namespace media { class AudioBus; class AudioConverter; class AudioFifo; class AudioTimestampHelper; class FFmpegGlue; class InMemoryUrlProtocol; namespace cast { class AudioFrameInput; class VideoFrameInput; class TestAudioBusFactory; class FakeMediaSource : public media::AudioConverter::InputCallback { public: // |task_runner| is to schedule decoding tasks. // |clock| is used by this source but is not owned. // |audio_config| is the desired audio config. // |video_config| is the desired video config. // |keep_frames| is true if all VideoFrames are saved in a queue. FakeMediaSource(scoped_refptr task_runner, base::TickClock* clock, const AudioSenderConfig& audio_config, const VideoSenderConfig& video_config, bool keep_frames); ~FakeMediaSource() final; // Transcode this file as the source of video and audio frames. // If |final_fps| is non zero then the file is played at the desired rate. void SetSourceFile(const base::FilePath& video_file, int final_fps); // Set to true to randomly change the frame size at random points in time. // Only applies when SetSourceFile() is not used. void SetVariableFrameSizeMode(bool enabled); void Start(scoped_refptr audio_frame_input, scoped_refptr video_frame_input); const VideoSenderConfig& get_video_config() const { return video_config_; } scoped_refptr PopOldestInsertedVideoFrame(); private: bool is_transcoding_audio() const { return audio_stream_index_ >= 0; } bool is_transcoding_video() const { return video_stream_index_ >= 0; } void SendNextFrame(); void SendNextFakeFrame(); void UpdateNextFrameSize(); // Return true if a frame was sent. bool SendNextTranscodedVideo(base::TimeDelta elapsed_time); // Return true if a frame was sent. bool SendNextTranscodedAudio(base::TimeDelta elapsed_time); // Helper methods to compute timestamps for the frame number specified. base::TimeDelta VideoFrameTime(int frame_number); base::TimeDelta ScaleTimestamp(base::TimeDelta timestamp); base::TimeDelta AudioFrameTime(int frame_number); // Go to the beginning of the stream. void Rewind(); // Call FFmpeg to fetch one packet. ScopedAVPacket DemuxOnePacket(bool* audio); void DecodeAudio(ScopedAVPacket packet); void DecodeVideo(ScopedAVPacket packet); void Decode(bool decode_audio); // media::AudioConverter::InputCallback implementation. double ProvideInput(media::AudioBus* output_bus, base::TimeDelta buffer_delay) final; AVStream* av_audio_stream(); AVStream* av_video_stream(); AVCodecContext* av_audio_context(); AVCodecContext* av_video_context(); const scoped_refptr task_runner_; const media::AudioParameters output_audio_params_; const VideoSenderConfig video_config_; const bool keep_frames_; bool variable_frame_size_mode_; gfx::Size current_frame_size_; base::TimeTicks next_frame_size_change_time_; scoped_refptr audio_frame_input_; scoped_refptr video_frame_input_; uint8 synthetic_count_; base::TickClock* const clock_; // Not owned by this class. // Time when the stream starts. base::TimeTicks start_time_; // The following three members are used only for fake frames. int audio_frame_count_; // Each audio frame is exactly 10ms. int video_frame_count_; scoped_ptr audio_bus_factory_; base::MemoryMappedFile file_data_; scoped_ptr protocol_; scoped_ptr glue_; AVFormatContext* av_format_context_; int audio_stream_index_; AudioParameters source_audio_params_; double playback_rate_; int video_stream_index_; int video_frame_rate_numerator_; int video_frame_rate_denominator_; // These are used for audio resampling. scoped_ptr audio_converter_; scoped_ptr audio_fifo_; scoped_ptr audio_fifo_input_bus_; media::AudioRendererAlgorithm audio_algo_; // Track the timestamp of audio sent to the receiver. scoped_ptr audio_sent_ts_; std::queue > video_frame_queue_; std::queue > inserted_video_frame_queue_; int64 video_first_pts_; bool video_first_pts_set_; base::TimeDelta last_video_frame_timestamp_; std::queue audio_bus_queue_; // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(FakeMediaSource); }; } // namespace cast } // namespace media #endif // MEDIA_CAST_TEST_FAKE_MEDIA_SOURCE_H_