1 /* $Id$ */
2 /*
3  * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 
20 #ifndef __PJSUA2_MEDIA_HPP__
21 #define __PJSUA2_MEDIA_HPP__
22 
23 /**
24  * @file pjsua2/media.hpp
25  * @brief PJSUA2 media operations
26  */
27 #include <pjsua-lib/pjsua.h>
28 #include <pjsua2/types.hpp>
29 
30 /** PJSUA2 API is inside pj namespace */
31 namespace pj
32 {
33 
34 /**
35  * @defgroup PJSUA2_MED Media
36  * @ingroup PJSUA2_Ref
37  * @{
38  */
39 
40 using std::string;
41 using std::vector;
42 
43 /**
44  * This structure contains all the information needed to completely describe
45  * a media.
46  */
47 struct MediaFormat
48 {
49     /**
50      * The format id that specifies the audio sample or video pixel format.
51      * Some well known formats ids are declared in pjmedia_format_id
52      * enumeration.
53      *
54      * @see pjmedia_format_id
55      */
56     pj_uint32_t		id;
57 
58     /**
59      * The top-most type of the media, as an information.
60      */
61     pjmedia_type	type;
62 
63 public:
64     /**
65      * Default constructor
66      */
MediaFormatpj::MediaFormat67     MediaFormat() : id(0), type(PJMEDIA_TYPE_NONE)
68     {}
69 };
70 
71 /**
72  * This structure describe detail information about an audio media.
73  */
74 struct MediaFormatAudio : public MediaFormat
75 {
76     unsigned	clockRate;	/**< Audio clock rate in samples or Hz. */
77     unsigned	channelCount;	/**< Number of channels.		*/
78     unsigned	frameTimeUsec;  /**< Frame interval, in microseconds.	*/
79     unsigned	bitsPerSample;	/**< Number of bits per sample.		*/
80     pj_uint32_t	avgBps;		/**< Average bitrate			*/
81     pj_uint32_t	maxBps;		/**< Maximum bitrate			*/
82 
83     /**
84      * Construct from pjmedia_format.
85      */
86     void fromPj(const pjmedia_format &format);
87 
88     /**
89      * Export to pjmedia_format.
90      */
91     pjmedia_format toPj() const;
92 };
93 
94 /**
95  * This structure describe detail information about an video media.
96  */
97 struct MediaFormatVideo : public MediaFormat
98 {
99     unsigned		width;	    /**< Video width. 			*/
100     unsigned		height;	    /**< Video height.			*/
101     int			fpsNum;	    /**< Frames per second numerator.	*/
102     int			fpsDenum;   /**< Frames per second denumerator.	*/
103     pj_uint32_t		avgBps;	    /**< Average bitrate.		*/
104     pj_uint32_t		maxBps;	    /**< Maximum bitrate.		*/
105 
106     /**
107      * Construct from pjmedia_format.
108      */
109     void fromPj(const pjmedia_format &format);
110 
111     /**
112      * Export to pjmedia_format.
113      */
114     pjmedia_format toPj() const;
115 };
116 
117 /** Array of MediaFormatAudio */
118 typedef std::vector<MediaFormatAudio> MediaFormatAudioVector;
119 
120 /** Array of MediaFormatVideo */
121 typedef std::vector<MediaFormatVideo> MediaFormatVideoVector;
122 
123 /**
124  * This structure descibes information about a particular media port that
125  * has been registered into the conference bridge.
126  */
127 struct ConfPortInfo
128 {
129     /**
130      * Conference port number.
131      */
132     int			portId;
133 
134     /**
135      * Port name.
136      */
137     string		name;
138 
139     /**
140      * Media audio format information
141      */
142     MediaFormatAudio	format;
143 
144     /**
145      * Tx level adjustment. Value 1.0 means no adjustment, value 0 means
146      * the port is muted, value 2.0 means the level is amplified two times.
147      */
148     float		txLevelAdj;
149 
150     /**
151      * Rx level adjustment. Value 1.0 means no adjustment, value 0 means
152      * the port is muted, value 2.0 means the level is amplified two times.
153      */
154     float		rxLevelAdj;
155 
156     /**
157      * Array of listeners (in other words, ports where this port is
158      * transmitting to).
159      */
160     IntVector		listeners;
161 
162 public:
163     /**
164      * Construct from pjsua_conf_port_info.
165      */
166     void fromPj(const pjsua_conf_port_info &port_info);
167 };
168 
169 /**
170  * Media port, corresponds to pjmedia_port
171  */
172 typedef void *MediaPort;
173 
174 /**
175  * Media.
176  */
177 class Media
178 {
179 public:
180     /**
181      * Virtual destructor.
182      */
183     virtual ~Media();
184 
185     /**
186      * Get type of the media.
187      *
188      * @return          The media type.
189      */
190     pjmedia_type getType() const;
191 
192 protected:
193     /**
194      * Constructor.
195      */
196     Media(pjmedia_type med_type);
197 
198 private:
199     /**
200      * Media type.
201      */
202     pjmedia_type        type;
203 };
204 
205 /**
206  * Parameters for AudioMedia::startTransmit2() method.
207  */
208 struct AudioMediaTransmitParam
209 {
210     /**
211      * Signal level adjustment. Value 1.0 means no level adjustment,
212      * while value 0 means to mute the port.
213      *
214      * Default: 1.0
215      */
216     float		level;
217 
218 public:
219     /**
220      * Default constructor
221      */
222     AudioMediaTransmitParam();
223 };
224 
225 /**
226  * Audio Media. This is a lite wrapper class for audio conference bridge port,
227  * i.e: this class only maintains one data member, conference slot ID, and
228  * the methods are simply proxies for conference bridge operations.
229  *
230  * Application can create a derived class and use registerMediaPort2()/
231  * unregisterMediaPort() to register/unregister a media port to/from the
232  * conference bridge.
233  *
234  * The library will not keep a list of AudioMedia instances, so any
235  * AudioMedia (descendant) instances instantiated by application must be
236  * maintained and destroyed by the application itself.
237  *
238  * Note that any PJSUA2 APIs that return AudioMedia instance(s) such as
239  * Endpoint::mediaEnumPorts2() or Call::getAudioMedia() will just return
240  * generated copy. All AudioMedia methods should work normally on this
241  * generated copy instance.
242  */
243 class AudioMedia : public Media
244 {
245 public:
246     /**
247     * Get information about the specified conference port.
248     */
249     ConfPortInfo getPortInfo() const PJSUA2_THROW(Error);
250 
251     /**
252      * Get port Id.
253      */
254     int getPortId() const;
255 
256     /**
257      * Get information from specific port id.
258      */
259     static ConfPortInfo getPortInfoFromId(int port_id) PJSUA2_THROW(Error);
260 
261     /**
262      * Establish unidirectional media flow to sink. This media port
263      * will act as a source, and it may transmit to multiple destinations/sink.
264      * And if multiple sources are transmitting to the same sink, the media
265      * will be mixed together. Source and sink may refer to the same Media,
266      * effectively looping the media.
267      *
268      * If bidirectional media flow is desired, application needs to call
269      * this method twice, with the second one called from the opposite source
270      * media.
271      *
272      * @param sink		The destination Media.
273      */
274     void startTransmit(const AudioMedia &sink) const PJSUA2_THROW(Error);
275 
276     /**
277      * Establish unidirectional media flow to sink. This media port
278      * will act as a source, and it may transmit to multiple destinations/sink.
279      * And if multiple sources are transmitting to the same sink, the media
280      * will be mixed together. Source and sink may refer to the same Media,
281      * effectively looping the media.
282      *
283      * Signal level from this source to the sink can be adjusted by making
284      * it louder or quieter via the parameter param. The level adjustment
285      * will apply to a specific connection only (i.e. only for signal
286      * from this source to the sink), as compared to
287      * adjustTxLevel()/adjustRxLevel() which applies to all signals from/to
288      * this media port. The signal adjustment
289      * will be cumulative, in this following order:
290      * signal from this source will be adjusted with the level specified
291      * in adjustTxLevel(), then with the level specified via this API,
292      * and finally with the level specified to the sink's adjustRxLevel().
293      *
294      * If bidirectional media flow is desired, application needs to call
295      * this method twice, with the second one called from the opposite source
296      * media.
297      *
298      * @param sink		The destination Media.
299      * @param param		The parameter.
300      */
301     void startTransmit2(const AudioMedia &sink,
302 			const AudioMediaTransmitParam &param) const
303          PJSUA2_THROW(Error);
304 
305     /**
306      *  Stop media flow to destination/sink port.
307      *
308      * @param sink		The destination media.
309      *
310      */
311     void stopTransmit(const AudioMedia &sink) const PJSUA2_THROW(Error);
312 
313     /**
314      * Adjust the signal level to be transmitted from the bridge to this
315      * media port by making it louder or quieter.
316      *
317      * @param level		Signal level adjustment. Value 1.0 means no
318      *				level adjustment, while value 0 means to mute
319      *				the port.
320      */
321     void adjustRxLevel(float level) PJSUA2_THROW(Error);
322 
323     /**
324      * Adjust the signal level to be received from this media port (to
325      * the bridge) by making it louder or quieter.
326      *
327      * @param level		Signal level adjustment. Value 1.0 means no
328      *				level adjustment, while value 0 means to mute
329      *				the port.
330      */
331     void adjustTxLevel(float level) PJSUA2_THROW(Error);
332 
333     /**
334      * Get the last received signal level.
335      *
336      * @return			Signal level in percent.
337      */
338     unsigned getRxLevel() const PJSUA2_THROW(Error);
339 
340     /**
341      * Get the last transmitted signal level.
342      *
343      * @return			Signal level in percent.
344      */
345     unsigned getTxLevel() const PJSUA2_THROW(Error);
346 
347     /**
348      * Warning: deprecated and will be removed in future release.
349      *
350      * Typecast from base class Media. This is useful for application written
351      * in language that does not support downcasting such as Python.
352      *
353      * @param media		The object to be downcasted
354      *
355      * @return			The object as AudioMedia instance
356      */
357     static AudioMedia* typecastFromMedia(Media *media);
358 
359     /**
360      * Default Constructor.
361      *
362      * Normally application will not create AudioMedia object directly,
363      * but it instantiates an AudioMedia derived class. This is set as public
364      * because some STL vector implementations require it.
365      */
366     AudioMedia();
367 
368     /**
369      * Virtual Destructor.
370      */
371     virtual ~AudioMedia();
372 
373 protected:
374     /**
375      * Conference port Id.
376      */
377     int			 id;
378 
379 protected:
380     /**
381      * Warning: deprecated and will be removed in future release, use
382      * registerMediaPort2() instead.
383      *
384      * This method needs to be called by descendants of this class to register
385      * the media port created to the conference bridge and Endpoint's
386      * media list.
387      *
388      * param port  The media port to be registered to the conference bridge.
389      *
390      */
391     void registerMediaPort(MediaPort port) PJSUA2_THROW(Error);
392 
393     /**
394      * This method needs to be called by descendants of this class to register
395      * the media port created to the conference bridge and Endpoint's
396      * media list.
397      *
398      * param port  The media port to be registered to the conference bridge.
399      * param pool  The memory pool.
400      *
401      */
402     void registerMediaPort2(MediaPort port, pj_pool_t *pool)
403 			    PJSUA2_THROW(Error);
404 
405     /**
406      * This method needs to be called by descendants of this class to remove
407      * the media port from the conference bridge and Endpoint's media list.
408      * Descendant should only call this method if it has registered the media
409      * with the previous call to registerMediaPort().
410      */
411     void unregisterMediaPort();
412 
413 private:
414     /* Memory pool for deprecated registerMediaPort() */
415     pj_caching_pool 	 mediaCachingPool;
416     pj_pool_t 		*mediaPool;
417 };
418 
419 /**
420  * Warning: deprecated, use AudioMediaVector2 instead.
421  *
422  * Array of Audio Media.
423  */
424 typedef std::vector<AudioMedia*> AudioMediaVector;
425 
426 
427 /** Array of Audio Media */
428 typedef std::vector<AudioMedia> AudioMediaVector2;
429 
430 /**
431  * This structure contains additional info about AudioMediaPlayer.
432  */
433 struct AudioMediaPlayerInfo
434 {
435     /**
436      * Format ID of the payload.
437      */
438     pjmedia_format_id	formatId;
439 
440     /**
441      * The number of bits per sample of the file payload. For example,
442      * the value is 16 for PCM WAV and 8 for Alaw/Ulas WAV files.
443      */
444     unsigned		payloadBitsPerSample;
445 
446     /**
447      * The WAV payload size in bytes.
448      */
449     pj_uint32_t		sizeBytes;
450 
451     /**
452      * The WAV payload size in samples.
453      */
454     pj_uint32_t		sizeSamples;
455 
456 public:
457     /**
458      * Default constructor
459      */
AudioMediaPlayerInfopj::AudioMediaPlayerInfo460     AudioMediaPlayerInfo() : formatId(PJMEDIA_FORMAT_L16)
461     {}
462 };
463 
464 /**
465  * Audio Media Player.
466  */
467 class AudioMediaPlayer : public AudioMedia
468 {
469 public:
470     /**
471      * Constructor.
472      */
473     AudioMediaPlayer();
474 
475     /**
476      * Create a file player,  and automatically add this
477      * player to the conference bridge.
478      *
479      * @param file_name	 The filename to be played. Currently only
480      *			 WAV files are supported, and the WAV file MUST be
481      *			 formatted as 16bit PCM mono/single channel (any
482      *			 clock rate is supported).
483      * @param options	 Optional option flag. Application may specify
484      *			 PJMEDIA_FILE_NO_LOOP to prevent playback loop.
485      */
486     void createPlayer(const string &file_name,
487 		      unsigned options=0) PJSUA2_THROW(Error);
488 
489     /**
490      * Create a file playlist media port, and automatically add the port
491      * to the conference bridge.
492      *
493      * @param file_names  Array of file names to be added to the play list.
494      *			  Note that the files must have the same clock rate,
495      *			  number of channels, and number of bits per sample.
496      * @param label	  Optional label to be set for the media port.
497      * @param options	  Optional option flag. Application may specify
498      *			  PJMEDIA_FILE_NO_LOOP to prevent looping.
499      */
500     void createPlaylist(const StringVector &file_names,
501 			const string &label="",
502 			unsigned options=0) PJSUA2_THROW(Error);
503 
504     /**
505      * Get additional info about the player. This operation is only valid
506      * for player. For playlist, Error will be thrown.
507      *
508      * @return		the info.
509      */
510     AudioMediaPlayerInfo getInfo() const PJSUA2_THROW(Error);
511 
512     /**
513      * Get current playback position in samples. This operation is not valid
514      * for playlist.
515      *
516      * @return		   Current playback position, in samples.
517      */
518     pj_uint32_t getPos() const PJSUA2_THROW(Error);
519 
520     /**
521      * Set playback position in samples. This operation is not valid for
522      * playlist.
523      *
524      * @param samples	   The desired playback position, in samples.
525      */
526     void setPos(pj_uint32_t samples) PJSUA2_THROW(Error);
527 
528     /**
529      * Warning: deprecated and will be removed in future release.
530      *
531      * Typecast from base class AudioMedia. This is useful for application
532      * written in language that does not support downcasting such as Python.
533      *
534      * @param media		The object to be downcasted
535      *
536      * @return			The object as AudioMediaPlayer instance
537      */
538     static AudioMediaPlayer* typecastFromAudioMedia(AudioMedia *media);
539 
540     /**
541      * Destructor. This will unregister the player port from the conference
542      * bridge.
543      */
544     virtual ~AudioMediaPlayer();
545 
546 public:
547     /*
548      * Callbacks
549      */
550 
551 
552 /* Unfortunately for pjsua2, a hard deprecation is inevitable. */
553 #if 0 // !DEPRECATED_FOR_TICKET_2251
554     /**
555      * Register a callback to be called when the file player reading has
556      * reached the end of file, or when the file reading has reached the
557      * end of file of the last file for a playlist. If the file or playlist
558      * is set to play repeatedly, then the callback will be called multiple
559      * times.
560      *
561      * @return			If the callback returns false, the playback
562      * 				will stop. Note that if application destroys
563      * 				the player in the callback, it must return
564      * 				false here.
565      */
566     virtual bool onEof()
567     { return true; }
568 #endif
569 
570     /**
571      * Register a callback to be called when the file player reading has
572      * reached the end of file, or when the file reading has reached the
573      * end of file of the last file for a playlist. If the file or playlist
574      * is set to play repeatedly, then the callback will be called multiple
575      * times.
576      *
577      * If application wishes to stop the playback, it can stop the media
578      * transmission in the callback, and only after all transmissions have
579      * been stopped, could the application safely destroy the player.
580      */
onEof2()581     virtual void onEof2()
582     { }
583 
584 private:
585     /**
586      * Player Id.
587      */
588     int	playerId;
589 
590     /**
591      *  Low level PJMEDIA callback
592      */
593     static void eof_cb(pjmedia_port *port,
594                        void *usr_data);
595 };
596 
597 /**
598  * Audio Media Recorder.
599  */
600 class AudioMediaRecorder : public AudioMedia
601 {
602 public:
603     /**
604      * Constructor.
605      */
606     AudioMediaRecorder();
607 
608     /**
609      * Create a file recorder, and automatically connect this recorder to
610      * the conference bridge. The recorder currently supports recording WAV
611      * file. The type of the recorder to use is determined by the extension of
612      * the file (e.g. ".wav").
613      *
614      * @param file_name	 Output file name. The function will determine the
615      *			 default format to be used based on the file extension.
616      *			 Currently ".wav" is supported on all platforms.
617      * @param enc_type	 Optionally specify the type of encoder to be used to
618      *			 compress the media, if the file can support different
619      *			 encodings. This value must be zero for now.
620      * @param max_size	 Maximum file size. Specify zero or -1 to remove size
621      *			 limitation. This value must be zero or -1 for now.
622      * @param options	 Optional options, which can be used to specify the
623      * 			 recording file format. Supported options are
624      * 			 PJMEDIA_FILE_WRITE_PCM, PJMEDIA_FILE_WRITE_ALAW,
625      * 			 and PJMEDIA_FILE_WRITE_ULAW. Default is zero or
626      * 			 PJMEDIA_FILE_WRITE_PCM.
627      */
628     void createRecorder(const string &file_name,
629 			unsigned enc_type=0,
630 			long max_size=0,
631 			unsigned options=0) PJSUA2_THROW(Error);
632 
633     /**
634      * Warning: deprecated and will be removed in future release.
635      *
636      * Typecast from base class AudioMedia. This is useful for application
637      * written in language that does not support downcasting such as Python.
638      *
639      * @param media		The object to be downcasted
640      *
641      * @return			The object as AudioMediaRecorder instance
642      */
643     static AudioMediaRecorder* typecastFromAudioMedia(AudioMedia *media);
644 
645     /**
646      * Destructor. This will unregister the recorder port from the conference
647      * bridge.
648      */
649     virtual ~AudioMediaRecorder();
650 
651 private:
652     /**
653      * Recorder Id.
654      */
655     int	recorderId;
656 };
657 
658 /**
659  * Tone descriptor (abstraction for pjmedia_tone_desc)
660  */
661 class ToneDesc : public pjmedia_tone_desc
662 {
663 public:
ToneDesc()664     ToneDesc()
665     {
666 	pj_bzero(this, sizeof(*this));
667     }
~ToneDesc()668     ~ToneDesc() {}
669 };
670 
671 /**
672  * Array of tone descriptor.
673  */
674 typedef std::vector<ToneDesc> ToneDescVector;
675 
676 /**
677  * Tone digit (abstraction for pjmedia_tone_digit)
678  */
679 class ToneDigit : public pjmedia_tone_digit
680 {
681 public:
ToneDigit()682     ToneDigit()
683     {
684 	pj_bzero(this, sizeof(*this));
685     }
~ToneDigit()686     ~ToneDigit() {}
687 };
688 
689 /**
690  * Array of tone digits.
691  */
692 typedef std::vector<ToneDigit> ToneDigitVector;
693 
694 /**
695  * A digit in tone digit map
696  */
697 struct ToneDigitMapDigit
698 {
699 public:
700     string	digit;
701     int		freq1;
702     int		freq2;
703 };
704 
705 /**
706  * Tone digit map
707  */
708 typedef std::vector<ToneDigitMapDigit> ToneDigitMapVector;
709 
710 /**
711  * Tone generator.
712  */
713 class ToneGenerator : public AudioMedia
714 {
715 public:
716     /**
717      * Constructor.
718      */
719     ToneGenerator();
720 
721     /**
722      * Destructor. This will unregister the tone generator port from the
723      * conference bridge.
724      */
725     ~ToneGenerator();
726 
727     /**
728      * Create tone generator and register the port to the conference bridge.
729      */
730     void createToneGenerator(unsigned clock_rate = 16000,
731 			     unsigned channel_count = 1) PJSUA2_THROW(Error);
732 
733     /**
734      * Check if the tone generator is still busy producing some tones.
735      * @return		    Non-zero if busy.
736      */
737     bool isBusy() const;
738 
739     /**
740      * Instruct the tone generator to stop current processing.
741      */
742     void stop() PJSUA2_THROW(Error);
743 
744     /**
745      * Rewind the playback. This will start the playback to the first
746      * tone in the playback list.
747      */
748     void rewind() PJSUA2_THROW(Error);
749 
750     /**
751      * Instruct the tone generator to play single or dual frequency tones
752      * with the specified duration. The new tones will be appended to
753      * currently playing tones, unless stop() is called before calling this
754      * function. The playback will begin as soon as the tone generator is
755      * connected to other media.
756      *
757      * @param tones	    Array of tones to be played.
758      * @param loop	    Play the tone in a loop.
759      */
760     void play(const ToneDescVector &tones,
761               bool loop=false) PJSUA2_THROW(Error);
762 
763     /**
764      * Instruct the tone generator to play multiple MF digits with each of
765      * the digits having individual ON/OFF duration. Each of the digit in the
766      * digit array must have the corresponding descriptor in the digit map.
767      * The new tones will be appended to currently playing tones, unless
768      * stop() is called before calling this function. The playback will begin
769      * as soon as the tone generator is connected to a sink media.
770      *
771      * @param digits	    Array of MF digits.
772      * @param loop	    Play the tone in a loop.
773      */
774     void playDigits(const ToneDigitVector &digits,
775                     bool loop=false) PJSUA2_THROW(Error);
776 
777     /**
778      * Get the digit-map currently used by this tone generator.
779      *
780      * @return		    The digitmap currently used by the tone generator
781      */
782     ToneDigitMapVector getDigitMap() const PJSUA2_THROW(Error);
783 
784     /**
785      * Set digit map to be used by the tone generator.
786      *
787      * @param digit_map	    Digitmap to be used by the tone generator.
788      */
789     void setDigitMap(const ToneDigitMapVector &digit_map) PJSUA2_THROW(Error);
790 
791 private:
792     pj_pool_t *pool;
793     pjmedia_port *tonegen;
794     pjmedia_tone_digit_map digitMap;
795 };
796 
797 
798 /*************************************************************************
799 * Sound device management
800 */
801 
802 /**
803  * Audio device information structure.
804  */
805 struct AudioDevInfo
806 {
807     /**
808      * The device name
809      */
810     string name;
811 
812     /**
813      * Maximum number of input channels supported by this device. If the
814      * value is zero, the device does not support input operation (i.e.
815      * it is a playback only device).
816      */
817     unsigned inputCount;
818 
819     /**
820      * Maximum number of output channels supported by this device. If the
821      * value is zero, the device does not support output operation (i.e.
822      * it is an input only device).
823      */
824     unsigned outputCount;
825 
826     /**
827      * Default sampling rate.
828      */
829     unsigned defaultSamplesPerSec;
830 
831     /**
832      * The underlying driver name
833      */
834     string driver;
835 
836     /**
837      * Device capabilities, as bitmask combination of pjmedia_aud_dev_cap.
838      */
839     unsigned caps;
840 
841     /**
842      * Supported audio device routes, as bitmask combination of
843      * pjmedia_aud_dev_route. The value may be zero if the device
844      * does not support audio routing.
845      */
846     unsigned routes;
847 
848     /**
849      * Array of supported extended audio formats
850      */
851     MediaFormatAudioVector extFmt;
852 
853     /**
854      * Construct from pjmedia_aud_dev_info.
855      */
856     void fromPj(const pjmedia_aud_dev_info &dev_info);
857 
858     /**
859      * Destructor.
860      */
861     ~AudioDevInfo();
862 };
863 
864 /**
865  * Warning: deprecated, use AudioDevInfoVector2 instead.
866  *
867  * Array of audio device info.
868  */
869 typedef std::vector<AudioDevInfo*> AudioDevInfoVector;
870 
871 /** Array of audio device info */
872 typedef std::vector<AudioDevInfo> AudioDevInfoVector2;
873 
874 /**
875  * Audio device manager.
876  */
877 class AudDevManager
878 {
879 public:
880     /**
881      * Get currently active capture sound devices. If sound devices has not been
882      * created, it is possible that the function returns -1 as device IDs.
883      *
884      * @return 			Device ID of the capture device.
885      */
886     int getCaptureDev() const PJSUA2_THROW(Error);
887 
888     /**
889      * Get the AudioMedia of the capture audio device.
890      *
891      * @return			Audio media for the capture device.
892      */
893     AudioMedia &getCaptureDevMedia() PJSUA2_THROW(Error);
894 
895     /**
896      * Get currently active playback sound devices. If sound devices has not
897      * been created, it is possible that the function returns -1 as device IDs.
898      *
899      * @return 			Device ID of the playback device.
900      */
901     int getPlaybackDev() const PJSUA2_THROW(Error);
902 
903     /**
904      * Get the AudioMedia of the speaker/playback audio device.
905      *
906      * @return			Audio media for the speaker/playback device.
907      */
908     AudioMedia &getPlaybackDevMedia() PJSUA2_THROW(Error);
909 
910     /**
911      * Select or change capture sound device. Application may call this
912      * function at any time to replace current sound device. Calling this
913      * method will not change the state of the sound device (opened/closed).
914      * Note that this method will override the mode set by setSndDevMode().
915      *
916      * @param capture_dev   	Device ID of the capture device.
917      */
918     void setCaptureDev(int capture_dev) const PJSUA2_THROW(Error);
919 
920     /**
921      * Select or change playback sound device. Application may call this
922      * function at any time to replace current sound device. Calling this
923      * method will not change the state of the sound device (opened/closed).
924      * Note that this method will override the mode set by setSndDevMode().
925      *
926      * @param playback_dev   	Device ID of the playback device.
927      */
928     void setPlaybackDev(int playback_dev) const PJSUA2_THROW(Error);
929 
930 #if !DEPRECATED_FOR_TICKET_2232
931     /**
932      * Warning: deprecated, use enumDev2 instead. This function is not
933      * safe in multithreaded environment.
934      *
935      * Enum all audio devices installed in the system. This function is not
936      * safe in multithreaded environment.
937      *
938      * @return			The list of audio device info.
939      */
940     const AudioDevInfoVector &enumDev() PJSUA2_THROW(Error);
941 #endif
942 
943     /**
944      * Enum all audio devices installed in the system.
945      *
946      * @return			The list of audio device info.
947      */
948     AudioDevInfoVector2 enumDev2() const PJSUA2_THROW(Error);
949 
950     /**
951      * Set pjsua to use null sound device. The null sound device only provides
952      * the timing needed by the conference bridge, and will not interract with
953      * any hardware.
954      *
955      */
956     void setNullDev() PJSUA2_THROW(Error);
957 
958     /**
959      * Disconnect the main conference bridge from any sound devices, and let
960      * application connect the bridge to it's own sound device/master port.
961      *
962      * @return			The port interface of the conference bridge,
963      *				so that application can connect this to it's
964      *				own sound device or master port.
965      */
966     MediaPort *setNoDev();
967 
968     /**
969      * Set sound device mode. Note that calling the APIs to set sound device
970      * (setPlaybackDev()/setCaptureDev()) will reset the mode.
971      *
972      * @param mode		The sound device mode, as bitmask combination
973      *				of #pjsua_snd_dev_mode
974      *
975      */
976     void setSndDevMode(unsigned mode) const PJSUA2_THROW(Error);
977 
978     /**
979      * Change the echo cancellation settings.
980      *
981      * The behavior of this function depends on whether the sound device is
982      * currently active, and if it is, whether device or software AEC is
983      * being used.
984      *
985      * If the sound device is currently active, and if the device supports AEC,
986      * this function will forward the change request to the device and it will
987      * be up to the device on whether support the request. If software AEC is
988      * being used (the software EC will be used if the device does not support
989      * AEC), this function will change the software EC settings. In all cases,
990      * the setting will be saved for future opening of the sound device.
991      *
992      * If the sound device is not currently active, this will only change the
993      * default AEC settings and the setting will be applied next time the
994      * sound device is opened.
995      *
996      * @param tail_msec		The tail length, in miliseconds. Set to zero to
997      *				disable AEC.
998      * @param options		Options to be passed to pjmedia_echo_create().
999      *				Normally the value should be zero.
1000      *
1001      */
1002     void setEcOptions(unsigned tail_msec, unsigned options) PJSUA2_THROW(Error);
1003 
1004     /**
1005      * Get current echo canceller tail length.
1006      *
1007      * @return			The EC tail length in milliseconds,
1008      *				If AEC is disabled, the value will be zero.
1009      */
1010     unsigned getEcTail() const PJSUA2_THROW(Error);
1011 
1012     /**
1013      * Check whether the sound device is currently active. The sound device
1014      * may be inactive if the application has set the auto close feature to
1015      * non-zero (the sndAutoCloseTime setting in MediaConfig), or
1016      * if null sound device or no sound device has been configured via the
1017      * setNoDev() function.
1018      */
1019     bool sndIsActive() const;
1020 
1021     /**
1022      * Refresh the list of sound devices installed in the system. This method
1023      * will only refresh the list of audio device so all active audio streams
1024      * will be unaffected. After refreshing the device list, application MUST
1025      * make sure to update all index references to audio devices before calling
1026      * any method that accepts audio device index as its parameter.
1027      *
1028      */
1029     void refreshDevs() PJSUA2_THROW(Error);
1030 
1031     /**
1032      * Get the number of sound devices installed in the system.
1033      *
1034      * @return 			The number of sound devices installed in the
1035      * 				system.
1036      *
1037      */
1038     unsigned getDevCount() const;
1039 
1040     /**
1041      * Get device information.
1042      *
1043      * @param id		The audio device ID.
1044      *
1045      * @return			The device information which will be filled in
1046      * 				by this method once it returns successfully.
1047      */
1048     AudioDevInfo getDevInfo(int id) const PJSUA2_THROW(Error);
1049 
1050     /**
1051      * Lookup device index based on the driver and device name.
1052      *
1053      * @param drv_name		The driver name.
1054      * @param dev_name		The device name.
1055      *
1056      * @return			The device ID. If the device is not found,
1057      * 				Error will be thrown.
1058      */
1059     int lookupDev(const string &drv_name,
1060 		  const string &dev_name) const PJSUA2_THROW(Error);
1061 
1062     /**
1063      * Get string info for the specified capability.
1064      *
1065      * @param cap		The capability ID.
1066      *
1067      * @return			Capability name.
1068      */
1069     string capName(pjmedia_aud_dev_cap cap) const;
1070 
1071     /**
1072      * This will configure audio format capability (other than PCM) to the
1073      * sound device being used. If sound device is currently active, the method
1074      * will forward the setting to the sound device instance to be applied
1075      * immediately, if it supports it.
1076      *
1077      * This method is only valid if the device has
1078      * PJMEDIA_AUD_DEV_CAP_EXT_FORMAT capability in AudioDevInfo.caps flags,
1079      * otherwise Error will be thrown.
1080      *
1081      * Note that in case the setting is kept for future use, it will be applied
1082      * to any devices, even when application has changed the sound device to be
1083      * used.
1084      *
1085      * @param format		The audio format.
1086      * @param keep		Specify whether the setting is to be kept for
1087      * 				future use.
1088      *
1089      */
1090     void setExtFormat(const MediaFormatAudio &format, bool keep=true)
1091 		      PJSUA2_THROW(Error);
1092 
1093     /**
1094      * Get the audio format capability (other than PCM) of the sound device
1095      * being used. If sound device is currently active, the method will forward
1096      * the request to the sound device. If sound device is currently inactive,
1097      * and if application had previously set the setting and mark the setting
1098      * as kept, then that setting will be returned. Otherwise, this method
1099      * will raise error.
1100      *
1101      * This method is only valid if the device has
1102      * PJMEDIA_AUD_DEV_CAP_EXT_FORMAT capability in AudioDevInfo.caps flags,
1103      * otherwise Error will be thrown.
1104      *
1105      * @return	    		The audio format.
1106      *
1107      */
1108     MediaFormatAudio getExtFormat() const PJSUA2_THROW(Error);
1109 
1110     /**
1111      * This will configure audio input latency control or query capability to
1112      * the sound device being used. If sound device is currently active,
1113      * the method will forward the setting to the sound device instance to be
1114      * applied immediately, if it supports it.
1115      *
1116      * This method is only valid if the device has
1117      * PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY capability in AudioDevInfo.caps flags,
1118      * otherwise Error will be thrown.
1119      *
1120      * Note that in case the setting is kept for future use, it will be applied
1121      * to any devices, even when application has changed the sound device to be
1122      * used.
1123      *
1124      * @param latency_msec	The input latency.
1125      * @param keep		Specify whether the setting is to be kept
1126      *				for future use.
1127      */
1128     void
1129     setInputLatency(unsigned latency_msec, bool keep=true) PJSUA2_THROW(Error);
1130 
1131     /**
1132      * Get the audio input latency control or query capability of the sound
1133      * device being used. If sound device is currently active, the method will
1134      * forward the request to the sound device. If sound device is currently
1135      * inactive, and if application had previously set the setting and mark the
1136      * setting as kept, then that setting will be returned. Otherwise, this
1137      * method will raise error.
1138      *
1139      * This method is only valid if the device has
1140      * PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY capability in AudioDevInfo.caps flags,
1141      * otherwise Error will be thrown.
1142      *
1143      * @return	    		The audio input latency.
1144      *
1145      */
1146     unsigned getInputLatency() const PJSUA2_THROW(Error);
1147 
1148     /**
1149      * This will configure audio output latency control or query capability to
1150      * the sound device being used. If sound device is currently active,
1151      * the method will forward the setting to the sound device instance to be
1152      * applied immediately, if it supports it.
1153      *
1154      * This method is only valid if the device has
1155      * PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY capability in AudioDevInfo.caps flags,
1156      * otherwise Error will be thrown.
1157      *
1158      * Note that in case the setting is kept for future use, it will be applied
1159      * to any devices, even when application has changed the sound device to be
1160      * used.
1161      *
1162      * @param latency_msec    	The output latency.
1163      * @param keep		Specify whether the setting is to be kept
1164      * 				for future use.
1165      *
1166      */
1167     void
1168     setOutputLatency(unsigned latency_msec, bool keep=true) PJSUA2_THROW(Error);
1169 
1170     /**
1171      * Get the audio output latency control or query capability of the sound
1172      * device being used. If sound device is currently active, the method will
1173      * forward the request to the sound device. If sound device is currently
1174      * inactive, and if application had previously set the setting and mark the
1175      * setting as kept, then that setting will be returned. Otherwise, this
1176      * method will raise error.
1177      *
1178      * This method is only valid if the device has
1179      * PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY capability in AudioDevInfo.caps flags,
1180      * otherwise Error will be thrown.
1181      *
1182      * @return	    		The audio output latency.
1183      *
1184      */
1185     unsigned getOutputLatency() const PJSUA2_THROW(Error);
1186 
1187     /**
1188      * This will configure audio input volume level capability to the
1189      * sound device being used.
1190      * If sound device is currently active, the method will forward the
1191      * setting to the sound device instance to be applied immediately,
1192      * if it supports it.
1193      *
1194      * This method is only valid if the device has
1195      * PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING capability in AudioDevInfo.caps
1196      * flags, otherwise Error will be thrown.
1197      *
1198      * Note that in case the setting is kept for future use, it will be applied
1199      * to any devices, even when application has changed the sound device to be
1200      * used.
1201      *
1202      * @param volume		The input volume level, in percent.
1203      * @param keep		Specify whether the setting is to be kept for
1204      * 				future use.
1205      *
1206      */
1207     void setInputVolume(unsigned volume, bool keep=true) PJSUA2_THROW(Error);
1208 
1209     /**
1210      * Get the audio input volume level capability of the sound device being
1211      * used. If sound device is currently active, the method will forward the
1212      * request to the sound device. If sound device is currently inactive,
1213      * and if application had previously set the setting and mark the setting
1214      * as kept, then that setting will be returned. Otherwise, this method
1215      * will raise error.
1216      *
1217      * This method is only valid if the device has
1218      * PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING capability in AudioDevInfo.caps
1219      * flags, otherwise Error will be thrown.     *
1220 
1221      * @return	    		The audio input volume level, in percent.
1222      *
1223      */
1224     unsigned getInputVolume() const PJSUA2_THROW(Error);
1225 
1226     /**
1227      * This will configure audio output volume level capability to the sound
1228      * device being used. If sound device is currently active, the method will
1229      * forward the setting to the sound device instance to be applied
1230      * immediately, if it supports it.
1231      *
1232      * This method is only valid if the device has
1233      * PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING capability in AudioDevInfo.caps
1234      * flags, otherwise Error will be thrown.
1235      *
1236      * Note that in case the setting is kept for future use, it will be applied
1237      * to any devices, even when application has changed the sound device to be
1238      * used.
1239      *
1240      * @param volume		The output volume level, in percent.
1241      * @param keep		Specify whether the setting is to be kept
1242      * 				for future use.
1243      *
1244      */
1245     void setOutputVolume(unsigned volume, bool keep=true) PJSUA2_THROW(Error);
1246 
1247     /**
1248      * Get the audio output volume level capability of the sound device being
1249      * used. If sound device is currently active, the method will forward the
1250      * request to the sound device. If sound device is currently inactive,
1251      * and if application had previously set the setting and mark the setting
1252      * as kept, then that setting will be returned. Otherwise, this method
1253      * will raise error.
1254      *
1255      * This method is only valid if the device has
1256      * PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING capability in AudioDevInfo.caps
1257      * flags, otherwise Error will be thrown.
1258      *
1259      * @return	    		The audio output volume level, in percent.
1260      *
1261      */
1262     unsigned getOutputVolume() const PJSUA2_THROW(Error);
1263 
1264     /**
1265      * Get the audio input signal level capability of the sound device being
1266      * used. If sound device is currently active, the method will forward the
1267      * request to the sound device. If sound device is currently inactive,
1268      * and if application had previously set the setting and mark the setting
1269      * as kept, then that setting will be returned. Otherwise, this method
1270      * will raise error.
1271      *
1272      * This method is only valid if the device has
1273      * PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER capability in AudioDevInfo.caps
1274      * flags, otherwise Error will be thrown.
1275      *
1276      * @return	    		The audio input signal level, in percent.
1277      *
1278      */
1279     unsigned getInputSignal() const PJSUA2_THROW(Error);
1280 
1281     /**
1282      * Get the audio output signal level capability of the sound device being
1283      * used. If sound device is currently active, the method will forward the
1284      * request to the sound device. If sound device is currently inactive,
1285      * and if application had previously set the setting and mark the setting
1286      * as kept, then that setting will be returned. Otherwise, this method
1287      * will raise error.
1288      *
1289      * This method is only valid if the device has
1290      * PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER capability in AudioDevInfo.caps
1291      * flags, otherwise Error will be thrown.
1292      *
1293      * @return	    		The audio output signal level, in percent.
1294      *
1295      */
1296     unsigned getOutputSignal() const PJSUA2_THROW(Error);
1297 
1298     /**
1299      * This will configure audio input route capability to the sound device
1300      * being used. If sound device is currently active, the method will
1301      * forward the setting to the sound device instance to be applied
1302      * immediately, if it supports it.
1303      *
1304      * This method is only valid if the device has
1305      * PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE capability in AudioDevInfo.caps
1306      * flags, otherwise Error will be thrown.
1307      *
1308      * Note that in case the setting is kept for future use, it will be applied
1309      * to any devices, even when application has changed the sound device to be
1310      * used.
1311      *
1312      * @param route		The audio input route.
1313      * @param keep		Specify whether the setting is to be kept
1314      * 				for future use.
1315      *
1316      */
1317     void setInputRoute(pjmedia_aud_dev_route route, bool keep=true)
1318 		       PJSUA2_THROW(Error);
1319 
1320     /**
1321      * Get the audio input route capability of the sound device being used.
1322      * If sound device is currently active, the method will forward the
1323      * request to the sound device. If sound device is currently inactive,
1324      * and if application had previously set the setting and mark the setting
1325      * as kept, then that setting will be returned. Otherwise, this method
1326      * will raise error.
1327      *
1328      * This method is only valid if the device has
1329      * PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE capability in AudioDevInfo.caps
1330      * flags, otherwise Error will be thrown.
1331      *
1332      * @return	    		The audio input route.
1333      *
1334      */
1335     pjmedia_aud_dev_route getInputRoute() const PJSUA2_THROW(Error);
1336 
1337     /**
1338      * This will configure audio output route capability to the sound device
1339      * being used. If sound device is currently active, the method will
1340      * forward the setting to the sound device instance to be applied
1341      * immediately, if it supports it.
1342      *
1343      * This method is only valid if the device has
1344      * PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE capability in AudioDevInfo.caps
1345      * flags, otherwise Error will be thrown.
1346      *
1347      * Note that in case the setting is kept for future use, it will be applied
1348      * to any devices, even when application has changed the sound device to be
1349      * used.
1350      *
1351      * @param route		The audio output route.
1352      * @param keep		Specify whether the setting is to be kept
1353      * 				for future use.
1354      *
1355      */
1356     void setOutputRoute(pjmedia_aud_dev_route route, bool keep=true)
1357 			PJSUA2_THROW(Error);
1358 
1359     /**
1360      * Get the audio output route capability of the sound device being used.
1361      * If sound device is currently active, the method will forward the
1362      * request to the sound device. If sound device is currently inactive,
1363      * and if application had previously set the setting and mark the setting
1364      * as kept, then that setting will be returned. Otherwise, this method
1365      * will raise error.
1366      *
1367      * This method is only valid if the device has
1368      * PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE capability in AudioDevInfo.caps
1369      * flags, otherwise Error will be thrown.
1370      *
1371      * @return	    		The audio output route.
1372      *
1373      */
1374     pjmedia_aud_dev_route getOutputRoute() const PJSUA2_THROW(Error);
1375 
1376     /**
1377      * This will configure audio voice activity detection capability to
1378      * the sound device being used. If sound device is currently active,
1379      * the method will forward the setting to the sound device instance
1380      * to be applied immediately, if it supports it.
1381      *
1382      * This method is only valid if the device has PJMEDIA_AUD_DEV_CAP_VAD
1383      * capability in AudioDevInfo.caps flags, otherwise Error will be thrown.
1384      *
1385      * Note that in case the setting is kept for future use, it will be applied
1386      * to any devices, even when application has changed the sound device to be
1387      * used.
1388      *
1389      * @param enable		Enable/disable voice activity detection
1390      *				feature. Set true to enable.
1391      * @param keep		Specify whether the setting is to be kept for
1392      *				future use.
1393      *
1394      */
1395     void setVad(bool enable, bool keep=true) PJSUA2_THROW(Error);
1396 
1397     /**
1398      * Get the audio voice activity detection capability of the sound device
1399      * being used. If sound device is currently active, the method will
1400      * forward the request to the sound device. If sound device is currently
1401      * inactive, and if application had previously set the setting and mark
1402      * the setting as kept, then that setting will be returned. Otherwise,
1403      * this method will raise error.
1404      *
1405      * This method is only valid if the device has PJMEDIA_AUD_DEV_CAP_VAD
1406      * capability in AudioDevInfo.caps flags, otherwise Error will be thrown.
1407      *
1408      * @return	    		The audio voice activity detection feature.
1409      *
1410      */
1411     bool getVad() const PJSUA2_THROW(Error);
1412 
1413     /**
1414      * This will configure audio comfort noise generation capability to
1415      * the sound device being used. If sound device is currently active,
1416      * the method will forward the setting to the sound device instance
1417      * to be applied immediately, if it supports it.
1418      *
1419      * This method is only valid if the device has PJMEDIA_AUD_DEV_CAP_CNG
1420      * capability in AudioDevInfo.caps flags, otherwise Error will be thrown.
1421      *
1422      * Note that in case the setting is kept for future use, it will be applied
1423      * to any devices, even when application has changed the sound device to be
1424      * used.
1425      *
1426      * @param enable		Enable/disable comfort noise generation
1427      *				feature. Set true to enable.
1428      * @param keep		Specify whether the setting is to be kept for
1429      *				future use.
1430      *
1431      */
1432     void setCng(bool enable, bool keep=true) PJSUA2_THROW(Error);
1433 
1434     /**
1435      * Get the audio comfort noise generation capability of the sound device
1436      * being used. If sound device is currently active, the method will
1437      * forward the request to the sound device. If sound device is currently
1438      * inactive, and if application had previously set the setting and mark
1439      * the setting as kept, then that setting will be returned. Otherwise,
1440      * this method will raise error.
1441      *
1442      * This method is only valid if the device has PJMEDIA_AUD_DEV_CAP_CNG
1443      * capability in AudioDevInfo.caps flags, otherwise Error will be thrown.
1444      *
1445      * @return	    		The audio comfort noise generation feature.
1446      *
1447      */
1448     bool getCng() const PJSUA2_THROW(Error);
1449 
1450     /**
1451      * This will configure audio packet loss concealment capability to
1452      * the sound device being used. If sound device is currently active,
1453      * the method will forward the setting to the sound device instance
1454      * to be applied immediately, if it supports it.
1455      *
1456      * This method is only valid if the device has PJMEDIA_AUD_DEV_CAP_PLC
1457      * capability in AudioDevInfo.caps flags, otherwise Error will be thrown.
1458      *
1459      * Note that in case the setting is kept for future use, it will be applied
1460      * to any devices, even when application has changed the sound device to be
1461      * used.
1462      *
1463      * @param enable		Enable/disable packet loss concealment
1464      *				feature. Set true to enable.
1465      * @param keep		Specify whether the setting is to be kept for
1466      *				future use.
1467      *
1468      */
1469     void setPlc(bool enable, bool keep=true) PJSUA2_THROW(Error);
1470 
1471     /**
1472      * Get the audio packet loss concealment capability of the sound device
1473      * being used. If sound device is currently active, the method will
1474      * forward the request to the sound device. If sound device is currently
1475      * inactive, and if application had previously set the setting and mark
1476      * the setting as kept, then that setting will be returned. Otherwise,
1477      * this method will raise error.
1478      *
1479      * This method is only valid if the device has PJMEDIA_AUD_DEV_CAP_PLC
1480      * capability in AudioDevInfo.caps flags, otherwise Error will be thrown.
1481      *
1482      * @return	    		The audio packet loss concealment feature.
1483      *
1484      */
1485     bool getPlc() const PJSUA2_THROW(Error);
1486 
1487 private:
1488 #if !DEPRECATED_FOR_TICKET_2232
1489     AudioDevInfoVector		 audioDevList;
1490 #endif
1491     AudioMedia			*devMedia;
1492 
1493     /**
1494      * Constructor.
1495      */
1496     AudDevManager();
1497 
1498     /**
1499      * Destructor.
1500      */
1501     ~AudDevManager();
1502 
1503     void clearAudioDevList();
1504     int getActiveDev(bool is_capture) const PJSUA2_THROW(Error);
1505 
1506     friend class Endpoint;
1507 };
1508 
1509 
1510 /**
1511  * Extra audio device. This class allows application to have multiple
1512  * sound device instances active concurrently.
1513 
1514  * Application may also use this class to improve media clock. Normally
1515  * media clock is driven by sound device in master port, but unfortunately
1516  * some sound devices may produce jittery clock. To improve media clock,
1517  * application can install Null Sound Device (i.e: using
1518  * AudDevManager::setNullDev()), which will act as a master port, and
1519  * install the sound device as extra sound device.
1520  *
1521  * Note that extra sound device will not have auto-close upon idle feature.
1522  * Also note that the extra sound device only supports mono channel.
1523  */
1524 class ExtraAudioDevice : public AudioMedia
1525 {
1526 public:
1527     /**
1528      * Constructor.
1529      *
1530      * @param playdev		Playback device ID.
1531      * @param recdev		Record device ID.
1532      */
1533     ExtraAudioDevice(int playdev, int recdev);
1534 
1535     /**
1536      * Destructor.
1537      */
1538     virtual ~ExtraAudioDevice();
1539 
1540     /**
1541      * Open the audio device using format (e.g.: clock rate, bit per sample,
1542      * samples per frame) matched to the conference bridge's format, except
1543      * the channel count, which will be set to one (mono channel). This will
1544      * also register the audio device port to conference bridge.
1545      */
1546     void open();
1547 
1548     /**
1549      * Close the audio device and unregister the audio device port from the
1550      * conference bridge.
1551      */
1552     void close();
1553 
1554     /**
1555      * Is the extra audio device opened?
1556      *
1557      * @return	    		'true' if it is opened.
1558      */
1559     bool isOpened();
1560 
1561 protected:
1562     int playDev;
1563     int recDev;
1564     void *ext_snd_dev;
1565 };
1566 
1567 
1568 /*************************************************************************
1569 * Video media
1570 */
1571 
1572 /**
1573  * Representation of media coordinate.
1574  */
1575 struct MediaCoordinate
1576 {
1577     int		x;	    /**< X position of the coordinate */
1578     int		y;	    /**< Y position of the coordinate */
1579 };
1580 
1581 /**
1582  * Representation of media size.
1583  */
1584 struct MediaSize
1585 {
1586     unsigned	w;	    /**< The width.	*/
1587     unsigned 	h;	    /**< The height.	*/
1588 };
1589 
1590 
1591 /**
1592  * This structure descibes information about a particular media port that
1593  * has been registered into the conference bridge.
1594  */
1595 struct VidConfPortInfo
1596 {
1597     /**
1598      * Conference port number.
1599      */
1600     int			portId;
1601 
1602     /**
1603      * Port name.
1604      */
1605     string		name;
1606 
1607     /**
1608      * Media audio format information
1609      */
1610     MediaFormatVideo	format;
1611 
1612     /**
1613      * Array of listeners (in other words, ports where this port is
1614      * transmitting to).
1615      */
1616     IntVector		listeners;
1617 
1618     /**
1619      * Array of listeners (in other words, ports where this port is
1620      * listening to).
1621      */
1622     IntVector		transmitters;
1623 
1624 public:
1625     /**
1626      * Construct from pjsua_conf_port_info.
1627      */
1628     void fromPj(const pjsua_vid_conf_port_info &port_info);
1629 };
1630 
1631 /**
1632  * Parameters for VideoMedia::startTransmit() method.
1633  */
1634 struct VideoMediaTransmitParam
1635 {
1636 };
1637 
1638 /**
1639  * Video Media.
1640  */
1641 class VideoMedia : public Media
1642 {
1643 public:
1644     /**
1645     * Get information about the specified conference port.
1646     */
1647     VidConfPortInfo getPortInfo() const PJSUA2_THROW(Error);
1648 
1649     /**
1650      * Get port Id.
1651      */
1652     int getPortId() const;
1653 
1654     /**
1655      * Get information from specific port id.
1656      */
1657     static VidConfPortInfo getPortInfoFromId(int port_id) PJSUA2_THROW(Error);
1658 
1659     /**
1660      * Establish unidirectional media flow to sink. This media port
1661      * will act as a source, and it may transmit to multiple destinations/sink.
1662      * And if multiple sources are transmitting to the same sink, the media
1663      * will be mixed together. Source and sink may refer to the same Media,
1664      * effectively looping the media.
1665      *
1666      * If bidirectional media flow is desired, application needs to call
1667      * this method twice, with the second one called from the opposite source
1668      * media.
1669      *
1670      * @param sink		The destination Media.
1671      * @param param		The parameter.
1672      */
1673     void startTransmit(const VideoMedia &sink,
1674 		       const VideoMediaTransmitParam &param) const
1675          PJSUA2_THROW(Error);
1676 
1677     /**
1678      *  Stop media flow to destination/sink port.
1679      *
1680      * @param sink		The destination media.
1681      *
1682      */
1683     void stopTransmit(const VideoMedia &sink) const PJSUA2_THROW(Error);
1684 
1685     /**
1686      * Default Constructor.
1687      *
1688      * Normally application will not create VideoMedia object directly,
1689      * but it instantiates a VideoMedia derived class. This is set as public
1690      * because some STL vector implementations require it.
1691      */
1692     VideoMedia();
1693 
1694     /**
1695      * Virtual Destructor
1696      */
1697     virtual ~VideoMedia();
1698 
1699 protected:
1700     /**
1701      * Conference port Id.
1702      */
1703     int			 id;
1704 
1705 protected:
1706     /**
1707      * This method needs to be called by descendants of this class to register
1708      * the media port created to the conference bridge and Endpoint's
1709      * media list.
1710      *
1711      * param port  The media port to be registered to the conference bridge.
1712      * param pool  The memory pool.
1713      */
1714     void registerMediaPort(MediaPort port, pj_pool_t *pool) PJSUA2_THROW(Error);
1715 
1716     /**
1717      * This method needs to be called by descendants of this class to remove
1718      * the media port from the conference bridge and Endpoint's media list.
1719      * Descendant should only call this method if it has registered the media
1720      * with the previous call to registerMediaPort().
1721      */
1722     void unregisterMediaPort();
1723 };
1724 
1725 /** Array of Video Media */
1726 typedef std::vector<VideoMedia> VideoMediaVector;
1727 
1728 
1729 /**
1730  * Window handle.
1731  */
1732 typedef struct WindowHandle {
1733     void    	*window;    /**< Window		*/
1734     void    	*display;   /**< Display	*/
1735 } WindowHandle;
1736 
1737 /**
1738  * Video window handle.
1739  */
1740 struct VideoWindowHandle
1741 {
1742     /**
1743      * The window handle type.
1744      */
1745     pjmedia_vid_dev_hwnd_type 	type;
1746 
1747     /**
1748      * The window handle.
1749      */
1750     WindowHandle 		handle;
1751 };
1752 
1753 /**
1754  * This structure describes video window info.
1755  */
1756 typedef struct VideoWindowInfo
1757 {
1758     /**
1759      * Flag to indicate whether this window is a native window,
1760      * such as created by built-in preview device. If this field is
1761      * true, only the video window handle field of this
1762      * structure is valid.
1763      */
1764     bool 		isNative;
1765 
1766     /**
1767      * Video window handle.
1768      */
1769     VideoWindowHandle 	winHandle;
1770 
1771     /**
1772      * Renderer device ID.
1773      */
1774     int 		renderDeviceId;
1775 
1776     /**
1777      * Window show status. The window is hidden if false.
1778      */
1779     bool		show;
1780 
1781     /**
1782      * Window position.
1783      */
1784     MediaCoordinate 	pos;
1785 
1786     /**
1787      * Window size.
1788      */
1789     MediaSize 		size;
1790 
1791 } VideoWindowInfo;
1792 
1793 /**
1794  * Video window.
1795  */
1796 class VideoWindow
1797 {
1798 public:
1799     /**
1800      * Constructor
1801      */
1802     VideoWindow(int win_id);
1803 
1804     /**
1805      * Get window info.
1806      *
1807      * @return			video window info.
1808      */
1809     VideoWindowInfo getInfo() const PJSUA2_THROW(Error);
1810 
1811     /**
1812      * Get video media or conference bridge port of the renderer of
1813      * this video window.
1814      *
1815      * @return			Video media of this renderer window.
1816      */
1817     VideoMedia getVideoMedia() PJSUA2_THROW(Error);
1818 
1819     /**
1820      * Show or hide window. This operation is not valid for native windows
1821      * (VideoWindowInfo.isNative=true), on which native windowing API
1822      * must be used instead.
1823      *
1824      * @param show		Set to true to show the window, false to
1825      * 				hide the window.
1826      *
1827      */
1828     void Show(bool show) PJSUA2_THROW(Error);
1829 
1830     /**
1831      * Set video window position. This operation is not valid for native windows
1832      * (VideoWindowInfo.isNative=true), on which native windowing API
1833      * must be used instead.
1834      *
1835      * @param pos		The window position.
1836      *
1837      */
1838     void setPos(const MediaCoordinate &pos) PJSUA2_THROW(Error);
1839 
1840     /**
1841      * Resize window. This operation is not valid for native windows
1842      * (VideoWindowInfo.isNative=true), on which native windowing API
1843      * must be used instead.
1844      *
1845      * @param size		The new window size.
1846      *
1847      */
1848     void setSize(const MediaSize &size) PJSUA2_THROW(Error);
1849 
1850     /**
1851      * Rotate the video window. This function will change the video orientation
1852      * and also possibly the video window size (width and height get swapped).
1853      * This operation is not valid for native windows (VideoWindowInfo.isNative
1854      * =true), on which native windowing API must be used instead.
1855      *
1856      * @param angle		The rotation angle in degrees, must be
1857      *				multiple of 90.
1858      *				Specify positive value for clockwise rotation or
1859      *				negative value for counter-clockwise rotation.
1860      */
1861     void rotate(int angle) PJSUA2_THROW(Error);
1862 
1863     /**
1864      * Set output window. This operation is valid only when the underlying
1865      * video device supports PJMEDIA_VIDEO_DEV_CAP_OUTPUT_WINDOW capability AND
1866      * allows the output window to be changed on-the-fly, otherwise Error will
1867      * be thrown. Currently it is only supported on Android.
1868      *
1869      * @param win		The new output window.
1870      */
1871     void setWindow(const VideoWindowHandle &win) PJSUA2_THROW(Error);
1872 
1873     /**
1874      * Set video window full-screen. This operation is valid only when the
1875      * underlying video device supports PJMEDIA_VID_DEV_CAP_OUTPUT_FULLSCREEN
1876      * capability. Currently it is only supported on SDL backend.
1877      *
1878      * @param enabled   	Set to true if full screen is desired, false
1879      *				otherwise.
1880      */
1881     void setFullScreen(bool enabled) PJSUA2_THROW(Error);
1882 
1883 private:
1884     pjsua_vid_win_id		winId;
1885 };
1886 
1887 /**
1888  * This structure contains parameters for VideoPreview::start()
1889  */
1890 struct VideoPreviewOpParam {
1891     /**
1892      * Device ID for the video renderer to be used for rendering the
1893      * capture stream for preview. This parameter is ignored if native
1894      * preview is being used.
1895      *
1896      * Default: PJMEDIA_VID_DEFAULT_RENDER_DEV
1897      */
1898     pjmedia_vid_dev_index   rendId;
1899 
1900     /**
1901      * Show window initially.
1902      *
1903      * Default: PJ_TRUE.
1904      */
1905     bool		    show;
1906 
1907     /**
1908      * Window flags.  The value is a bitmask combination of
1909      * \a pjmedia_vid_dev_wnd_flag.
1910      *
1911      * Default: 0.
1912      */
1913     unsigned		    windowFlags;
1914 
1915     /**
1916      * Media format. If left unitialized, this parameter will not be used.
1917      */
1918     MediaFormat		    format;
1919 
1920     /**
1921      * Optional output window to be used to display the video preview.
1922      * This parameter will only be used if the video device supports
1923      * PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW capability and the capability
1924      * is not read-only.
1925      */
1926     VideoWindowHandle	    window;
1927 
1928 public:
1929     /**
1930      * Default constructor initializes with default values.
1931      */
1932     VideoPreviewOpParam();
1933 
1934     /**
1935      * Convert from pjsip
1936      */
1937     void fromPj(const pjsua_vid_preview_param &prm);
1938 
1939     /**
1940      * Convert to pjsip
1941      */
1942     pjsua_vid_preview_param toPj() const;
1943 };
1944 
1945 /**
1946  * Video Preview
1947  */
1948 class VideoPreview {
1949 public:
1950     /**
1951      * Constructor
1952      */
1953     VideoPreview(int dev_id);
1954 
1955     /**
1956      * Determine if the specified video input device has built-in native
1957      * preview capability. This is a convenience function that is equal to
1958      * querying device's capability for PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW
1959      * capability.
1960      *
1961      * @return		true if it has.
1962      */
1963     bool hasNative();
1964 
1965     /**
1966      * Start video preview window for the specified capture device.
1967      *
1968      * @param p		Video preview parameters.
1969      */
1970     void start(const VideoPreviewOpParam &param) PJSUA2_THROW(Error);
1971 
1972     /**
1973      * Stop video preview.
1974      */
1975     void stop() PJSUA2_THROW(Error);
1976 
1977     /*
1978      * Get the preview window handle associated with the capture device,if any.
1979      */
1980     VideoWindow getVideoWindow();
1981 
1982     /**
1983      * Get video media or conference bridge port of the video capture device.
1984      *
1985      * @return			Video media of the video capture device.
1986      */
1987     VideoMedia getVideoMedia() PJSUA2_THROW(Error);
1988 
1989 private:
1990     pjmedia_vid_dev_index devId;
1991     pjsua_vid_win_id winId;
1992     void updateDevId();
1993 };
1994 
1995 /**
1996  * Video device information structure.
1997  */
1998 struct VideoDevInfo
1999 {
2000     /**
2001      * The device ID
2002      */
2003     pjmedia_vid_dev_index id;
2004 
2005     /**
2006      * The device name
2007      */
2008     string name;
2009 
2010     /**
2011      * The underlying driver name
2012      */
2013     string driver;
2014 
2015     /**
2016      * The supported direction of the video device, i.e. whether it supports
2017      * capture only, render only, or both.
2018      */
2019     pjmedia_dir dir;
2020 
2021     /**
2022      * Device capabilities, as bitmask combination of #pjmedia_vid_dev_cap
2023      */
2024     unsigned caps;
2025 
2026     /**
2027      * Array of supported video formats. Some fields in each supported video
2028      * format may be set to zero or of "unknown" value, to indicate that the
2029      * value is unknown or should be ignored. When these value are not set
2030      * to zero, it indicates that the exact format combination is being used.
2031      */
2032     MediaFormatVideoVector fmt;
2033 
2034 public:
2035     /**
2036      * Default constructor
2037      */
VideoDevInfopj::VideoDevInfo2038     VideoDevInfo() : id(-1), dir(PJMEDIA_DIR_NONE)
2039     {}
2040 
2041     /**
2042      * Construct from pjmedia_vid_dev_info.
2043      */
2044     void fromPj(const pjmedia_vid_dev_info &dev_info);
2045 
2046     /**
2047      * Destructor.
2048      */
2049     ~VideoDevInfo();
2050 };
2051 
2052 /**
2053  * Warning: deprecated, use VideoDevInfoVector2 instead.
2054  *
2055  * Array of video device info.
2056  */
2057 typedef std::vector<VideoDevInfo*> VideoDevInfoVector;
2058 
2059 /** Array of video device info */
2060 typedef std::vector<VideoDevInfo> VideoDevInfoVector2;
2061 
2062 /**
2063  * Parameter for switching device with PJMEDIA_VID_DEV_CAP_SWITCH capability.
2064  */
2065 struct VideoSwitchParam
2066 {
2067     /**
2068      * Target device ID to switch to. Once the switching is successful, the
2069      * video stream will use this device and the old device will be closed.
2070      */
2071     pjmedia_vid_dev_index target_id;
2072 };
2073 
2074 /**
2075  * Video device manager.
2076  */
2077 class VidDevManager {
2078 public:
2079     /**
2080      * Refresh the list of video devices installed in the system. This function
2081      * will only refresh the list of video device so all active video streams
2082      * will be unaffected. After refreshing the device list, application MUST
2083      * make sure to update all index references to video devices (i.e. all
2084      * variables of type pjmedia_vid_dev_index) before calling any function
2085      * that accepts video device index as its parameter.
2086      */
2087     void refreshDevs() PJSUA2_THROW(Error);
2088 
2089     /**
2090      * Get the number of video devices installed in the system.
2091      *
2092      * @return		The number of devices.
2093      */
2094     unsigned getDevCount();
2095 
2096     /**
2097      * Retrieve the video device info for the specified device index.
2098      *
2099      * @param dev_id	The video device id
2100      *
2101      * @return		The list of video device info
2102      */
2103     VideoDevInfo getDevInfo(int dev_id) const PJSUA2_THROW(Error);
2104 
2105 #if !DEPRECATED_FOR_TICKET_2232
2106     /**
2107      * Warning: deprecated, use enumDev2() instead. This function is not
2108      * safe in multithreaded environment.
2109      *
2110      * Enum all video devices installed in the system.
2111      *
2112      * @return		The list of video device info
2113      */
2114     const VideoDevInfoVector &enumDev() PJSUA2_THROW(Error);
2115 #endif
2116 
2117     /**
2118      * Enum all video devices installed in the system.
2119      *
2120      * @return		The list of video device info
2121      */
2122     VideoDevInfoVector2 enumDev2() const PJSUA2_THROW(Error);
2123 
2124     /**
2125      * Lookup device index based on the driver and device name.
2126      *
2127      * @param drv_name	The driver name.
2128      * @param dev_name	The device name.
2129      *
2130      * @return		The device ID. If the device is not found,
2131      *			Error will be thrown.
2132      */
2133     int lookupDev(const string &drv_name,
2134 		  const string &dev_name) const PJSUA2_THROW(Error);
2135 
2136     /**
2137      * Get string info for the specified capability.
2138      *
2139      * @param cap	The capability ID.
2140      *
2141      * @return		Capability name.
2142      */
2143     string capName(pjmedia_vid_dev_cap cap) const;
2144 
2145     /**
2146      * This will configure video format capability to the video device.
2147      * If video device is currently active, the method will forward the setting
2148      * to the video device instance to be applied immediately, if it
2149      * supports it.
2150      *
2151      * This method is only valid if the device has
2152      * PJMEDIA_VID_DEV_CAP_FORMAT capability in VideoDevInfo.caps flags,
2153      * otherwise Error will be thrown.
2154      *
2155      * Note that in case the setting is kept for future use, it will be applied
2156      * to any devices, even when application has changed the video device to be
2157      * used.
2158      *
2159      * @param dev_id	The video device id.
2160      * @param format	The video format.
2161      * @param keep	Specify whether the setting is to be kept for
2162      * 			future use.
2163      */
2164     void setFormat(int dev_id,
2165 		   const MediaFormatVideo &format,
2166 		   bool keep) PJSUA2_THROW(Error);
2167 
2168     /**
2169      * Get the video format capability to the video device.
2170      * If video device is currently active, the method will forward the request
2171      * to the video device. If video device is currently inactive, and if
2172      * application had previously set the setting and mark the setting as kept,
2173      * then that setting will be returned. Otherwise, this method will
2174      * raise error.
2175      *
2176      * This method is only valid if the device has
2177      * PJMEDIA_VID_DEV_CAP_FORMAT capability in VideoDevInfo.caps flags,
2178      * otherwise Error will be thrown.
2179      *
2180      * @param dev_id	The video device id.
2181      * @return keep	The video format.
2182      */
2183     MediaFormatVideo getFormat(int dev_id) const PJSUA2_THROW(Error);
2184 
2185     /**
2186      * This will configure video format capability to the video device.
2187      * If video device is currently active, the method will forward the setting
2188      * to the video device instance to be applied immediately, if it
2189      * supports it.
2190      *
2191      * This method is only valid if the device has
2192      * PJMEDIA_VID_DEV_CAP_INPUT_SCALE capability in VideoDevInfo.caps flags,
2193      * otherwise Error will be thrown.
2194      *
2195      * Note that in case the setting is kept for future use, it will be applied
2196      * to any devices, even when application has changed the video device to be
2197      * used.
2198      *
2199      * @param dev_id	The video device id.
2200      * @param scale	The video scale.
2201      * @param keep	Specify whether the setting is to be kept for
2202      * 			future use.
2203      */
2204     void setInputScale(int dev_id,
2205 		       const MediaSize &scale,
2206 		       bool keep) PJSUA2_THROW(Error);
2207 
2208     /**
2209      * Get the video input scale capability to the video device.
2210      * If video device is currently active, the method will forward the request
2211      * to the video device. If video device is currently inactive, and if
2212      * application had previously set the setting and mark the setting as kept,
2213      * then that setting will be returned. Otherwise, this method will
2214      * raise error.
2215      *
2216      * This method is only valid if the device has
2217      * PJMEDIA_VID_DEV_CAP_FORMAT capability in VideoDevInfo.caps flags,
2218      * otherwise Error will be thrown.
2219      *
2220      * @param dev_id	The video device id.
2221      * @return keep	The video format.
2222      */
2223     MediaSize getInputScale(int dev_id) const PJSUA2_THROW(Error);
2224 
2225     /**
2226      * This will configure fast switching to another video device.
2227      * If video device is currently active, the method will forward the setting
2228      * to the video device instance to be applied immediately, if it
2229      * supports it.
2230      *
2231      * This method is only valid if the device has
2232      * PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS capability in VideoDevInfo.caps
2233      * flags, otherwise Error will be thrown.
2234      *
2235      * Note that in case the setting is kept for future use, it will be applied
2236      * to any devices, even when application has changed the video device to be
2237      * used.
2238      *
2239      * @param dev_id	The video device id.
2240      * @param flags	The video window flag.
2241      * @param keep	Specify whether the setting is to be kept for
2242      * 			future use.
2243      */
2244     void setOutputWindowFlags(int dev_id, int flags, bool keep)
2245 			      PJSUA2_THROW(Error);
2246 
2247     /**
2248      * Get the window output flags capability to the video device.
2249      * If video device is currently active, the method will forward the request
2250      * to the video device. If video device is currently inactive, and if
2251      * application had previously set the setting and mark the setting as kept,
2252      * then that setting will be returned. Otherwise, this method will
2253      * raise error.
2254      *
2255      * This method is only valid if the device has
2256      * PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS capability in VideoDevInfo.caps
2257      * flags, otherwise Error will be thrown.
2258      *
2259      * @param dev_id	The video device id.
2260      * @return keep	The video format.
2261      */
2262     int getOutputWindowFlags(int dev_id) PJSUA2_THROW(Error);
2263 
2264     /**
2265      * This will configure fast switching to another video device.
2266      * If video device is currently active, the method will forward the setting
2267      * to the video device instance to be applied immediately, if it
2268      * supports it.
2269      *
2270      * This method is only valid if the device has
2271      * PJMEDIA_VID_DEV_CAP_SWITCH capability in VideoDevInfo.caps flags,
2272      * otherwise Error will be thrown.
2273      *
2274      * @param dev_id	The video device id.
2275      * @param param	The video switch param.
2276      */
2277     void switchDev(int dev_id,
2278 		   const VideoSwitchParam &param) PJSUA2_THROW(Error);
2279 
2280     /**
2281      * Check whether the video capture device is currently active, i.e. if
2282      * a video preview has been started or there is a video call using
2283      * the device.
2284      *
2285      * @param dev_id	The video device id
2286      *
2287      * @return		True if it's active.
2288      */
2289     bool isCaptureActive(int dev_id) const;
2290 
2291     /**
2292      * This will configure video orientation of the video capture device.
2293      * If the device is currently active (i.e. if there is a video call
2294      * using the device or a video preview has been started), the method
2295      * will forward the setting to the video device instance to be applied
2296      * immediately, if it supports it.
2297      *
2298      * The setting will be saved for future opening of the video device,
2299      * if the "keep" argument is set to true. If the video device is
2300      * currently inactive, and the "keep" argument is false, this method
2301      * will throw Error.
2302      *
2303      * @param dev_id	The video device id
2304      * @param orient	The video orientation.
2305      * @param keep	Specify whether the setting is to be kept for
2306      * 			future use.
2307      *
2308      */
2309     void setCaptureOrient(pjmedia_vid_dev_index dev_id,
2310     			  pjmedia_orient orient,
2311     			  bool keep=true) PJSUA2_THROW(Error);
2312 
2313 private:
2314 #if !DEPRECATED_FOR_TICKET_2232
2315     VideoDevInfoVector videoDevList;
2316 #endif
2317 
2318     void clearVideoDevList();
2319 
2320     /**
2321      * Constructor.
2322      */
2323     VidDevManager();
2324 
2325     /**
2326      * Destructor.
2327      */
2328     ~VidDevManager();
2329 
2330     friend class Endpoint;
2331 };
2332 
2333 
2334 /*************************************************************************
2335 * Codec management
2336 */
2337 
2338 /**
2339  * This structure describes codec information.
2340  */
2341 struct CodecInfo
2342 {
2343     /**
2344      * Codec unique identification.
2345      */
2346     string		codecId;
2347 
2348     /**
2349      * Codec priority (integer 0-255).
2350      */
2351     pj_uint8_t		priority;
2352 
2353     /**
2354      * Codec description.
2355      */
2356     string		desc;
2357 
2358     /**
2359      * Construct from pjsua_codec_info.
2360      */
2361     void fromPj(const pjsua_codec_info &codec_info);
2362 };
2363 
2364 /**
2365  * Warning: deprecated, use CodecInfoVector2 instead.
2366  *
2367  * Array of codec info.
2368  */
2369 typedef std::vector<CodecInfo*> CodecInfoVector;
2370 
2371 /** Array of codec info */
2372 typedef std::vector<CodecInfo> CodecInfoVector2;
2373 
2374 /**
2375  * Structure of codec specific parameters which contains name=value pairs.
2376  * The codec specific parameters are to be used with SDP according to
2377  * the standards (e.g: RFC 3555) in SDP 'a=fmtp' attribute.
2378  */
2379 typedef struct CodecFmtp
2380 {
2381     string name;
2382     string val;
2383 } CodecFmtp;
2384 
2385 /** Array of codec fmtp */
2386 typedef std::vector<CodecFmtp> CodecFmtpVector;
2387 
2388 /**
2389  * Audio codec parameters info.
2390  */
2391 struct CodecParamInfo
2392 {
2393     unsigned	clockRate;		/**< Sampling rate in Hz	    */
2394     unsigned	channelCnt;		/**< Channel count.		    */
2395     unsigned 	avgBps;			/**< Average bandwidth in bits/sec  */
2396     unsigned	maxBps;			/**< Maximum bandwidth in bits/sec  */
2397     unsigned    maxRxFrameSize;		/**< Maximum frame size             */
2398     unsigned 	frameLen;		/**< Decoder frame ptime in msec.   */
2399     unsigned  	pcmBitsPerSample;	/**< Bits/sample in the PCM side    */
2400     unsigned  	pt;			/**< Payload type.		    */
2401     pjmedia_format_id fmtId;		/**< Source format, it's format of
2402 					     encoder input and decoder
2403 					     output.			    */
2404 public:
2405     /**
2406      * Default constructor
2407      */
CodecParamInfopj::CodecParamInfo2408     CodecParamInfo() : fmtId(PJMEDIA_FORMAT_L16)
2409     {}
2410 };
2411 
2412 /**
2413  * Audio codec parameters setting.
2414  */
2415 struct CodecParamSetting
2416 {
2417     unsigned  	frmPerPkt;	    /**< Number of frames per packet.	*/
2418     bool	vad;		    /**< Voice Activity Detector.	*/
2419     bool	cng;		    /**< Comfort Noise Generator.	*/
2420     bool	penh;		    /**< Perceptual Enhancement		*/
2421     bool	plc;		    /**< Packet loss concealment	*/
2422     bool	reserved;	    /**< Reserved, must be zero.	*/
2423     CodecFmtpVector encFmtp;	    /**< Encoder's fmtp params.		*/
2424     CodecFmtpVector decFmtp;	    /**< Decoder's fmtp params.		*/
2425 };
2426 
2427 /**
2428  * Detailed codec attributes used in configuring an audio codec and in querying
2429  * the capability of audio codec factories.
2430  *
2431  * Please note that codec parameter also contains SDP specific setting,
2432  * #setting::decFmtp and #setting::encFmtp, which may need to be set
2433  * appropriately based on the effective setting.
2434  * See each codec documentation for more detail.
2435  */
2436 struct CodecParam
2437 {
2438     struct CodecParamInfo info;
2439     struct CodecParamSetting setting;
2440 
2441     void fromPj(const pjmedia_codec_param &param);
2442 
2443     pjmedia_codec_param toPj() const;
2444 };
2445 
2446 /**
2447  * Opus codec parameters setting;
2448  */
2449 struct CodecOpusConfig
2450 {
2451     unsigned   sample_rate; /**< Sample rate in Hz.                     */
2452     unsigned   channel_cnt; /**< Number of channels.                    */
2453     unsigned   frm_ptime;   /**< Frame time in msec.   			*/
2454     unsigned   bit_rate;    /**< Encoder bit rate in bps.		*/
2455     unsigned   packet_loss; /**< Encoder's expected packet loss pct.	*/
2456     unsigned   complexity;  /**< Encoder complexity, 0-10(10 is highest)*/
2457     bool       cbr;         /**< Constant bit rate?			*/
2458 
2459     pjmedia_codec_opus_config toPj() const;
2460     void fromPj(const pjmedia_codec_opus_config &config);
2461 };
2462 
2463 /**
2464  * Detailed codec attributes used in configuring a video codec and in querying
2465  * the capability of video codec factories.
2466  *
2467  * Please note that codec parameter also contains SDP specific setting,
2468  * #decFmtp and #encFmtp, which may need to be set appropriately based on
2469  * the effective setting. See each codec documentation for more detail.
2470  */
2471 struct VidCodecParam
2472 {
2473     pjmedia_dir         dir;            /**< Direction                      */
2474     pjmedia_vid_packing packing; 	/**< Packetization strategy.	    */
2475 
2476     struct
2477     MediaFormatVideo    encFmt;         /**< Encoded format	            */
2478     CodecFmtpVector	encFmtp;        /**< Encoder fmtp params	    */
2479     unsigned            encMtu;         /**< MTU or max payload size setting*/
2480 
2481     struct
2482     MediaFormatVideo    decFmt;         /**< Decoded format	            */
2483     CodecFmtpVector	decFmtp;        /**< Decoder fmtp params	    */
2484 
2485     bool		ignoreFmtp;	/**< Ignore fmtp params. If set to
2486 					     true, the codec will apply
2487 					     format settings specified in
2488 					     encFmt and decFmt only.	    */
2489 
2490 public:
2491     /**
2492      * Default constructor
2493      */
VidCodecParampj::VidCodecParam2494     VidCodecParam() : dir(PJMEDIA_DIR_NONE),
2495 		      packing(PJMEDIA_VID_PACKING_UNKNOWN)
2496     {}
2497 
2498     void fromPj(const pjmedia_vid_codec_param &param);
2499 
2500     pjmedia_vid_codec_param toPj() const;
2501 };
2502 
2503 
2504 /*************************************************************************
2505 * Media event
2506 */
2507 
2508 /**
2509  * This structure describes a media format changed event.
2510  */
2511 struct MediaFmtChangedEvent
2512 {
2513     unsigned newWidth;      /**< The new width.     */
2514     unsigned newHeight;     /**< The new height.    */
2515 };
2516 
2517 /**
2518  * This structure describes an audio device error event.
2519  */
2520 struct AudDevErrorEvent
2521 {
2522     pjmedia_dir		    dir;	/**< The direction.	    */
2523     int			    id;		/**< The audio device ID.   */
2524     pj_status_t		    status;	/**< The status code.	    */
2525 };
2526 
2527 /**
2528  * Media event data.
2529  */
2530 typedef union MediaEventData {
2531     /**
2532      * Media format changed event data.
2533      */
2534     MediaFmtChangedEvent    fmtChanged;
2535 
2536     /**
2537      * Audio device error event data.
2538      */
2539     AudDevErrorEvent	    audDevError;
2540 
2541     /**
2542      * Pointer to storage to user event data, if it's outside
2543      * this struct
2544      */
2545     GenericData		    ptr;
2546 
2547 } MediaEventData;
2548 
2549 /**
2550  * This structure describes a media event. It corresponds to the
2551  * pjmedia_event structure.
2552  */
2553 struct MediaEvent
2554 {
2555     /**
2556      * The event type.
2557      */
2558     pjmedia_event_type          type;
2559 
2560     /**
2561      * Additional data/parameters about the event. The type of data
2562      * will be specific to the event type being reported.
2563      */
2564     MediaEventData              data;
2565 
2566     /**
2567      * Pointer to original pjmedia_event. Only valid when the struct
2568      * is converted from PJSIP's pjmedia_event.
2569      */
2570     void                       *pjMediaEvent;
2571 
2572 public:
2573     /**
2574      * Default constructor
2575      */
MediaEventpj::MediaEvent2576     MediaEvent() : type(PJMEDIA_EVENT_NONE)
2577     {}
2578 
2579     /**
2580      * Convert from pjsip
2581      */
2582     void fromPj(const pjmedia_event &ev);
2583 };
2584 
2585 /**
2586  * @}  // PJSUA2_MED
2587  */
2588 
2589 } // namespace pj
2590 
2591 #endif	/* __PJSUA2_MEDIA_HPP__ */
2592