blob: f0822ceba3ea99ebdf98217b40ff9134b44295e3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
// 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 <queue>
#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/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 AudioFifo;
class AudioTimestampHelper;
class FFmpegGlue;
class InMemoryUrlProtocol;
class MultiChannelResampler;
namespace cast {
class AudioFrameInput;
class VideoFrameInput;
class TestAudioBusFactory;
class FakeMediaSource {
public:
// |task_runner| is to schedule decoding tasks.
// |clock| is used by this source but is not owned.
// |video_config| is the desired video config.
// |keep_frames| is true if all VideoFrames are saved in a queue.
FakeMediaSource(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::TickClock* clock,
const VideoSenderConfig& video_config,
bool keep_frames);
~FakeMediaSource();
// Transcode this file as the source of video and audio frames.
// If |override_fps| is non zero then the file is played at the desired rate.
void SetSourceFile(const base::FilePath& video_file, int override_fps);
void Start(scoped_refptr<AudioFrameInput> audio_frame_input,
scoped_refptr<VideoFrameInput> video_frame_input);
const VideoSenderConfig& get_video_config() const { return video_config_; }
scoped_refptr<media::VideoFrame> 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();
// 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);
void ProvideData(int frame_delay, media::AudioBus* output_bus);
AVStream* av_audio_stream();
AVStream* av_video_stream();
AVCodecContext* av_audio_context();
AVCodecContext* av_video_context();
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
const VideoSenderConfig video_config_;
const bool keep_frames_;
scoped_refptr<AudioFrameInput> audio_frame_input_;
scoped_refptr<VideoFrameInput> 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<TestAudioBusFactory> audio_bus_factory_;
base::MemoryMappedFile file_data_;
scoped_ptr<InMemoryUrlProtocol> protocol_;
scoped_ptr<FFmpegGlue> glue_;
AVFormatContext* av_format_context_;
int audio_stream_index_;
AudioParameters 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<media::MultiChannelResampler> audio_resampler_;
scoped_ptr<media::AudioFifo> audio_fifo_;
scoped_ptr<media::AudioBus> audio_fifo_input_bus_;
media::AudioRendererAlgorithm audio_algo_;
// Track the timestamp of audio sent to the receiver.
scoped_ptr<media::AudioTimestampHelper> audio_sent_ts_;
std::queue<scoped_refptr<VideoFrame> > video_frame_queue_;
std::queue<scoped_refptr<VideoFrame> > inserted_video_frame_queue_;
int64 video_first_pts_;
bool video_first_pts_set_;
base::TimeDelta last_video_frame_timestamp_;
std::queue<AudioBus*> audio_bus_queue_;
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<FakeMediaSource> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeMediaSource);
};
} // namespace cast
} // namespace media
#endif // MEDIA_CAST_TEST_FAKE_MEDIA_SOURCE_H_
|