blob: 5cfcb4d764bad470a53c8b3a1fac9a00cac8e461 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef TALK_MEDIA_BASE_MEDIAENGINE_H_
29#define TALK_MEDIA_BASE_MEDIAENGINE_H_
30
31#ifdef OSX
32#include <CoreAudio/CoreAudio.h>
33#endif
34
35#include <climits>
36#include <string>
37#include <vector>
38
39#include "talk/base/sigslotrepeater.h"
40#include "talk/media/base/codec.h"
41#include "talk/media/base/mediachannel.h"
42#include "talk/media/base/mediacommon.h"
43#include "talk/media/base/videocapturer.h"
44#include "talk/media/base/videocommon.h"
45#include "talk/media/base/videoprocessor.h"
46#include "talk/media/base/voiceprocessor.h"
47#include "talk/media/devices/devicemanager.h"
48
49#if defined(GOOGLE_CHROME_BUILD) || defined(CHROMIUM_BUILD)
50#define DISABLE_MEDIA_ENGINE_FACTORY
51#endif
52
53namespace cricket {
54
55class VideoCapturer;
56
57// MediaEngineInterface is an abstraction of a media engine which can be
58// subclassed to support different media componentry backends.
59// It supports voice and video operations in the same class to facilitate
60// proper synchronization between both media types.
61class MediaEngineInterface {
62 public:
63 // Bitmask flags for options that may be supported by the media engine
64 // implementation. This can be converted to and from an
65 // AudioOptions struct for backwards compatibility with calls that
66 // use flags until we transition to using structs everywhere.
67 enum AudioFlags {
68 // Audio processing that attempts to filter away the output signal from
69 // later inbound pickup.
70 ECHO_CANCELLATION = 1 << 0,
71 // Audio processing to adjust the sensitivity of the local mic dynamically.
72 AUTO_GAIN_CONTROL = 1 << 1,
73 // Audio processing to filter out background noise.
74 NOISE_SUPPRESSION = 1 << 2,
75 // Audio processing to remove background noise of lower frequencies.
76 HIGHPASS_FILTER = 1 << 3,
77 // A switch to swap which captured signal is left and right in stereo mode.
78 STEREO_FLIPPING = 1 << 4,
79 // Controls delegation echo cancellation to use the OS' facility.
80 SYSTEM_AEC_MODE = 1 << 5,
81
82 ALL_AUDIO_OPTIONS = (1 << 6) - 1,
83 DEFAULT_AUDIO_OPTIONS = ECHO_CANCELLATION | AUTO_GAIN_CONTROL |
84 NOISE_SUPPRESSION | HIGHPASS_FILTER,
85 };
86
87 // Default value to be used for SetAudioDelayOffset().
88 static const int kDefaultAudioDelayOffset;
89
90 virtual ~MediaEngineInterface() {}
91
92 // Initialization
93 // Starts the engine.
94 virtual bool Init(talk_base::Thread* worker_thread) = 0;
95 // Shuts down the engine.
96 virtual void Terminate() = 0;
97 // Returns what the engine is capable of, as a set of Capabilities, above.
98 virtual int GetCapabilities() = 0;
99
100 // MediaChannel creation
101 // Creates a voice media channel. Returns NULL on failure.
102 virtual VoiceMediaChannel *CreateChannel() = 0;
103 // Creates a video media channel, paired with the specified voice channel.
104 // Returns NULL on failure.
105 virtual VideoMediaChannel *CreateVideoChannel(
106 VoiceMediaChannel* voice_media_channel) = 0;
107
108 // Creates a soundclip object for playing sounds on. Returns NULL on failure.
109 virtual SoundclipMedia *CreateSoundclip() = 0;
110
111 // Configuration
112 // Sets global audio options. "options" are from AudioOptions, above.
113 virtual bool SetAudioOptions(int options) = 0;
114 // Sets global video options. "options" are from VideoOptions, above.
115 virtual bool SetVideoOptions(int options) = 0;
116 // Sets the value used by the echo canceller to offset delay values obtained
117 // from the OS.
118 virtual bool SetAudioDelayOffset(int offset) = 0;
119 // Sets the default (maximum) codec/resolution and encoder option to capture
120 // and encode video.
121 virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config)
122 = 0;
123
124 // Device selection
125 // TODO(tschmelcher): Add method for selecting the soundclip device.
126 virtual bool SetSoundDevices(const Device* in_device,
127 const Device* out_device) = 0;
128 // Sets the externally provided video capturer. The ssrc is the ssrc of the
129 // (video) stream for which the video capturer should be set.
130 virtual bool SetVideoCapturer(VideoCapturer* capturer) = 0;
131 virtual VideoCapturer* GetVideoCapturer() const = 0;
132
133 // Device configuration
134 // Gets the current speaker volume, as a value between 0 and 255.
135 virtual bool GetOutputVolume(int* level) = 0;
136 // Sets the current speaker volume, as a value between 0 and 255.
137 virtual bool SetOutputVolume(int level) = 0;
138
139 // Local monitoring
140 // Gets the current microphone level, as a value between 0 and 10.
141 virtual int GetInputLevel() = 0;
142 // Starts or stops the local microphone. Useful if local mic info is needed
143 // prior to a call being connected; the mic will be started automatically
144 // when a VoiceMediaChannel starts sending.
145 virtual bool SetLocalMonitor(bool enable) = 0;
146 // Installs a callback for raw frames from the local camera.
147 virtual bool SetLocalRenderer(VideoRenderer* renderer) = 0;
148 // Starts/stops local camera.
149 virtual bool SetVideoCapture(bool capture) = 0;
150
151 virtual const std::vector<AudioCodec>& audio_codecs() = 0;
152 virtual const std::vector<RtpHeaderExtension>&
153 audio_rtp_header_extensions() = 0;
154 virtual const std::vector<VideoCodec>& video_codecs() = 0;
155 virtual const std::vector<RtpHeaderExtension>&
156 video_rtp_header_extensions() = 0;
157
158 // Logging control
159 virtual void SetVoiceLogging(int min_sev, const char* filter) = 0;
160 virtual void SetVideoLogging(int min_sev, const char* filter) = 0;
161
162 // Voice processors for effects.
163 virtual bool RegisterVoiceProcessor(uint32 ssrc,
164 VoiceProcessor* video_processor,
165 MediaProcessorDirection direction) = 0;
166 virtual bool UnregisterVoiceProcessor(uint32 ssrc,
167 VoiceProcessor* video_processor,
168 MediaProcessorDirection direction) = 0;
169
170 virtual VideoFormat GetStartCaptureFormat() const = 0;
171
172 virtual sigslot::repeater2<VideoCapturer*, CaptureState>&
173 SignalVideoCaptureStateChange() = 0;
174};
175
176
177#if !defined(DISABLE_MEDIA_ENGINE_FACTORY)
178class MediaEngineFactory {
179 public:
180 static MediaEngineInterface* Create();
181};
182#endif
183
184// CompositeMediaEngine constructs a MediaEngine from separate
185// voice and video engine classes.
186template<class VOICE, class VIDEO>
187class CompositeMediaEngine : public MediaEngineInterface {
188 public:
189 CompositeMediaEngine() {}
190 virtual ~CompositeMediaEngine() {}
191 virtual bool Init(talk_base::Thread* worker_thread) {
192 if (!voice_.Init(worker_thread))
193 return false;
194 if (!video_.Init(worker_thread)) {
195 voice_.Terminate();
196 return false;
197 }
198 SignalVideoCaptureStateChange().repeat(video_.SignalCaptureStateChange);
199 return true;
200 }
201 virtual void Terminate() {
202 video_.Terminate();
203 voice_.Terminate();
204 }
205
206 virtual int GetCapabilities() {
207 return (voice_.GetCapabilities() | video_.GetCapabilities());
208 }
209 virtual VoiceMediaChannel *CreateChannel() {
210 return voice_.CreateChannel();
211 }
212 virtual VideoMediaChannel *CreateVideoChannel(VoiceMediaChannel* channel) {
213 return video_.CreateChannel(channel);
214 }
215 virtual SoundclipMedia *CreateSoundclip() {
216 return voice_.CreateSoundclip();
217 }
218
219 virtual bool SetAudioOptions(int o) {
220 return voice_.SetOptions(o);
221 }
222 virtual bool SetVideoOptions(int o) {
223 return video_.SetOptions(o);
224 }
225 virtual bool SetAudioDelayOffset(int offset) {
226 return voice_.SetDelayOffset(offset);
227 }
228 virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) {
229 return video_.SetDefaultEncoderConfig(config);
230 }
231
232 virtual bool SetSoundDevices(const Device* in_device,
233 const Device* out_device) {
234 return voice_.SetDevices(in_device, out_device);
235 }
236 virtual bool SetVideoCapturer(VideoCapturer* capturer) {
237 return video_.SetVideoCapturer(capturer);
238 }
239 virtual VideoCapturer* GetVideoCapturer() const {
240 return video_.GetVideoCapturer();
241 }
242
243 virtual bool GetOutputVolume(int* level) {
244 return voice_.GetOutputVolume(level);
245 }
246 virtual bool SetOutputVolume(int level) {
247 return voice_.SetOutputVolume(level);
248 }
249
250 virtual int GetInputLevel() {
251 return voice_.GetInputLevel();
252 }
253 virtual bool SetLocalMonitor(bool enable) {
254 return voice_.SetLocalMonitor(enable);
255 }
256 virtual bool SetLocalRenderer(VideoRenderer* renderer) {
257 return video_.SetLocalRenderer(renderer);
258 }
259 virtual bool SetVideoCapture(bool capture) {
260 return video_.SetCapture(capture);
261 }
262
263 virtual const std::vector<AudioCodec>& audio_codecs() {
264 return voice_.codecs();
265 }
266 virtual const std::vector<RtpHeaderExtension>& audio_rtp_header_extensions() {
267 return voice_.rtp_header_extensions();
268 }
269 virtual const std::vector<VideoCodec>& video_codecs() {
270 return video_.codecs();
271 }
272 virtual const std::vector<RtpHeaderExtension>& video_rtp_header_extensions() {
273 return video_.rtp_header_extensions();
274 }
275
276 virtual void SetVoiceLogging(int min_sev, const char* filter) {
277 return voice_.SetLogging(min_sev, filter);
278 }
279 virtual void SetVideoLogging(int min_sev, const char* filter) {
280 return video_.SetLogging(min_sev, filter);
281 }
282
283 virtual bool RegisterVoiceProcessor(uint32 ssrc,
284 VoiceProcessor* processor,
285 MediaProcessorDirection direction) {
286 return voice_.RegisterProcessor(ssrc, processor, direction);
287 }
288 virtual bool UnregisterVoiceProcessor(uint32 ssrc,
289 VoiceProcessor* processor,
290 MediaProcessorDirection direction) {
291 return voice_.UnregisterProcessor(ssrc, processor, direction);
292 }
293 virtual VideoFormat GetStartCaptureFormat() const {
294 return video_.GetStartCaptureFormat();
295 }
296 virtual sigslot::repeater2<VideoCapturer*, CaptureState>&
297 SignalVideoCaptureStateChange() {
298 return signal_state_change_;
299 }
300
301 protected:
302 VOICE voice_;
303 VIDEO video_;
304 sigslot::repeater2<VideoCapturer*, CaptureState> signal_state_change_;
305};
306
307// NullVoiceEngine can be used with CompositeMediaEngine in the case where only
308// a video engine is desired.
309class NullVoiceEngine {
310 public:
311 bool Init(talk_base::Thread* worker_thread) { return true; }
312 void Terminate() {}
313 int GetCapabilities() { return 0; }
314 // If you need this to return an actual channel, use FakeMediaEngine instead.
315 VoiceMediaChannel* CreateChannel() {
316 return NULL;
317 }
318 SoundclipMedia* CreateSoundclip() {
319 return NULL;
320 }
321 bool SetDelayOffset(int offset) { return true; }
322 bool SetOptions(int opts) { return true; }
323 bool SetDevices(const Device* in_device, const Device* out_device) {
324 return true;
325 }
326 bool GetOutputVolume(int* level) {
327 *level = 0;
328 return true;
329 }
330 bool SetOutputVolume(int level) { return true; }
331 int GetInputLevel() { return 0; }
332 bool SetLocalMonitor(bool enable) { return true; }
333 const std::vector<AudioCodec>& codecs() { return codecs_; }
334 const std::vector<RtpHeaderExtension>& rtp_header_extensions() {
335 return rtp_header_extensions_;
336 }
337 void SetLogging(int min_sev, const char* filter) {}
338 bool RegisterProcessor(uint32 ssrc,
339 VoiceProcessor* voice_processor,
340 MediaProcessorDirection direction) { return true; }
341 bool UnregisterProcessor(uint32 ssrc,
342 VoiceProcessor* voice_processor,
343 MediaProcessorDirection direction) { return true; }
344
345 private:
346 std::vector<AudioCodec> codecs_;
347 std::vector<RtpHeaderExtension> rtp_header_extensions_;
348};
349
350// NullVideoEngine can be used with CompositeMediaEngine in the case where only
351// a voice engine is desired.
352class NullVideoEngine {
353 public:
354 bool Init(talk_base::Thread* worker_thread) { return true; }
355 void Terminate() {}
356 int GetCapabilities() { return 0; }
357 // If you need this to return an actual channel, use FakeMediaEngine instead.
358 VideoMediaChannel* CreateChannel(
359 VoiceMediaChannel* voice_media_channel) {
360 return NULL;
361 }
362 bool SetOptions(int opts) { return true; }
363 bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) {
364 return true;
365 }
366 bool SetLocalRenderer(VideoRenderer* renderer) { return true; }
367 bool SetCapture(bool capture) { return true; }
368 const std::vector<VideoCodec>& codecs() { return codecs_; }
369 const std::vector<RtpHeaderExtension>& rtp_header_extensions() {
370 return rtp_header_extensions_;
371 }
372 void SetLogging(int min_sev, const char* filter) {}
373 VideoFormat GetStartCaptureFormat() const { return VideoFormat(); }
374 bool SetVideoCapturer(VideoCapturer* capturer) { return true; }
375 VideoCapturer* GetVideoCapturer() const { return NULL; }
376
377 sigslot::signal2<VideoCapturer*, CaptureState> SignalCaptureStateChange;
378 private:
379 std::vector<VideoCodec> codecs_;
380 std::vector<RtpHeaderExtension> rtp_header_extensions_;
381};
382
383typedef CompositeMediaEngine<NullVoiceEngine, NullVideoEngine> NullMediaEngine;
384
385enum DataChannelType {
386 DCT_NONE = 0,
387 DCT_RTP = 1,
388 DCT_SCTP = 2
389};
390
391class DataEngineInterface {
392 public:
393 virtual ~DataEngineInterface() {}
394 virtual DataMediaChannel* CreateChannel(DataChannelType type) = 0;
395 virtual const std::vector<DataCodec>& data_codecs() = 0;
396};
397
398} // namespace cricket
399
400#endif // TALK_MEDIA_BASE_MEDIAENGINE_H_