1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // A fake media source that generates video and audio frames to a cast
7 // This class can transcode a WebM file using FFmpeg. It can also
8 // generate an animation and audio of fixed frequency.
10 #ifndef MEDIA_CAST_TEST_FAKE_MEDIA_SOURCE_H_
11 #define MEDIA_CAST_TEST_FAKE_MEDIA_SOURCE_H_
15 #include "base/files/file_path.h"
16 #include "base/files/memory_mapped_file.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/single_thread_task_runner.h"
20 #include "base/time/tick_clock.h"
21 #include "media/audio/audio_parameters.h"
22 #include "media/base/audio_converter.h"
23 #include "media/cast/cast_config.h"
24 #include "media/filters/audio_renderer_algorithm.h"
25 #include "media/filters/ffmpeg_demuxer.h"
27 struct AVCodecContext
;
28 struct AVFormatContext
;
35 class AudioTimestampHelper
;
37 class InMemoryUrlProtocol
;
41 class AudioFrameInput
;
42 class VideoFrameInput
;
43 class TestAudioBusFactory
;
45 class FakeMediaSource
: public media::AudioConverter::InputCallback
{
47 // |task_runner| is to schedule decoding tasks.
48 // |clock| is used by this source but is not owned.
49 // |audio_config| is the desired audio config.
50 // |video_config| is the desired video config.
51 // |keep_frames| is true if all VideoFrames are saved in a queue.
52 FakeMediaSource(scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
,
53 base::TickClock
* clock
,
54 const AudioSenderConfig
& audio_config
,
55 const VideoSenderConfig
& video_config
,
57 ~FakeMediaSource() final
;
59 // Transcode this file as the source of video and audio frames.
60 // If |final_fps| is non zero then the file is played at the desired rate.
61 void SetSourceFile(const base::FilePath
& video_file
, int final_fps
);
63 // Set to true to randomly change the frame size at random points in time.
64 // Only applies when SetSourceFile() is not used.
65 void SetVariableFrameSizeMode(bool enabled
);
67 void Start(scoped_refptr
<AudioFrameInput
> audio_frame_input
,
68 scoped_refptr
<VideoFrameInput
> video_frame_input
);
70 const VideoSenderConfig
& get_video_config() const { return video_config_
; }
72 scoped_refptr
<media::VideoFrame
> PopOldestInsertedVideoFrame();
75 bool is_transcoding_audio() const { return audio_stream_index_
>= 0; }
76 bool is_transcoding_video() const { return video_stream_index_
>= 0; }
79 void SendNextFakeFrame();
81 void UpdateNextFrameSize();
83 // Return true if a frame was sent.
84 bool SendNextTranscodedVideo(base::TimeDelta elapsed_time
);
86 // Return true if a frame was sent.
87 bool SendNextTranscodedAudio(base::TimeDelta elapsed_time
);
89 // Helper methods to compute timestamps for the frame number specified.
90 base::TimeDelta
VideoFrameTime(int frame_number
);
92 base::TimeDelta
ScaleTimestamp(base::TimeDelta timestamp
);
94 base::TimeDelta
AudioFrameTime(int frame_number
);
96 // Go to the beginning of the stream.
99 // Call FFmpeg to fetch one packet.
100 ScopedAVPacket
DemuxOnePacket(bool* audio
);
102 void DecodeAudio(ScopedAVPacket packet
);
103 void DecodeVideo(ScopedAVPacket packet
);
104 void Decode(bool decode_audio
);
106 // media::AudioConverter::InputCallback implementation.
107 double ProvideInput(media::AudioBus
* output_bus
, base::TimeDelta buffer_delay
)
110 AVStream
* av_audio_stream();
111 AVStream
* av_video_stream();
112 AVCodecContext
* av_audio_context();
113 AVCodecContext
* av_video_context();
115 const scoped_refptr
<base::SingleThreadTaskRunner
> task_runner_
;
116 const media::AudioParameters output_audio_params_
;
117 const VideoSenderConfig video_config_
;
118 const bool keep_frames_
;
119 bool variable_frame_size_mode_
;
120 gfx::Size current_frame_size_
;
121 base::TimeTicks next_frame_size_change_time_
;
122 scoped_refptr
<AudioFrameInput
> audio_frame_input_
;
123 scoped_refptr
<VideoFrameInput
> video_frame_input_
;
124 uint8 synthetic_count_
;
125 base::TickClock
* const clock_
; // Not owned by this class.
127 // Time when the stream starts.
128 base::TimeTicks start_time_
;
130 // The following three members are used only for fake frames.
131 int audio_frame_count_
; // Each audio frame is exactly 10ms.
132 int video_frame_count_
;
133 scoped_ptr
<TestAudioBusFactory
> audio_bus_factory_
;
135 base::MemoryMappedFile file_data_
;
136 scoped_ptr
<InMemoryUrlProtocol
> protocol_
;
137 scoped_ptr
<FFmpegGlue
> glue_
;
138 AVFormatContext
* av_format_context_
;
140 int audio_stream_index_
;
141 AudioParameters source_audio_params_
;
142 double playback_rate_
;
144 int video_stream_index_
;
145 int video_frame_rate_numerator_
;
146 int video_frame_rate_denominator_
;
148 // These are used for audio resampling.
149 scoped_ptr
<media::AudioConverter
> audio_converter_
;
150 scoped_ptr
<media::AudioFifo
> audio_fifo_
;
151 scoped_ptr
<media::AudioBus
> audio_fifo_input_bus_
;
152 media::AudioRendererAlgorithm audio_algo_
;
154 // Track the timestamp of audio sent to the receiver.
155 scoped_ptr
<media::AudioTimestampHelper
> audio_sent_ts_
;
157 std::queue
<scoped_refptr
<VideoFrame
> > video_frame_queue_
;
158 std::queue
<scoped_refptr
<VideoFrame
> > inserted_video_frame_queue_
;
159 int64 video_first_pts_
;
160 bool video_first_pts_set_
;
161 base::TimeDelta last_video_frame_timestamp_
;
163 std::queue
<AudioBus
*> audio_bus_queue_
;
165 // NOTE: Weak pointers must be invalidated before all other member variables.
166 base::WeakPtrFactory
<FakeMediaSource
> weak_factory_
;
168 DISALLOW_COPY_AND_ASSIGN(FakeMediaSource
);
174 #endif // MEDIA_CAST_TEST_FAKE_MEDIA_SOURCE_H_