Changeset 5255 for pjproject


Ignore:
Timestamp:
Mar 10, 2016 5:02:07 AM (9 years ago)
Author:
ming
Message:

Fixed #1907: Remove pjmedia* circular dependency

Location:
pjproject/trunk/pjmedia
Files:
4 added
9 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/build/Makefile

    r5239 r5255  
    7676                        vid_port.o vid_stream.o vid_stream_info.o vid_tee.o \ 
    7777                        wav_player.o wav_playlist.o wav_writer.o wave.o \ 
    78                         wsola.o 
     78                        wsola.o audiodev.o videodev.o 
    7979 
    8080export PJMEDIA_CFLAGS += $(_CFLAGS) 
    8181export PJMEDIA_CXXFLAGS += $(_CXXFLAGS) 
    82 export PJMEDIA_LDFLAGS += $(PJMEDIA_VIDEODEV_LDLIB) \ 
    83                           $(PJMEDIA_AUDIODEV_LDLIB) \ 
    84                           $(PJLIB_LDLIB) \ 
     82export PJMEDIA_LDFLAGS += $(PJLIB_LDLIB) \ 
    8583                          $(PJLIB_UTIL_LDLIB) \ 
    8684                          $(PJNATH_LDLIB) \ 
     
    9896export PJMEDIA_AUDIODEV_CFLAGS += $(_CFLAGS) 
    9997export PJMEDIA_AUDIODEV_CXXFLAGS += $(_CXXFLAGS) 
    100 export PJMEDIA_AUDIODEV_LDFLAGS += $(PJLIB_LDLIB) \ 
     98export PJMEDIA_AUDIODEV_LDFLAGS += $(PJMEDIA_LDLIB) \ 
     99                                   $(PJLIB_LDLIB) \ 
    101100                                   $(_LDFLAGS) 
    102101 
     
    106105# 
    107106export PJMEDIA_VIDEODEV_SRCDIR = ../src/pjmedia-videodev 
    108 export PJMEDIA_VIDEODEV_OBJS +=  errno.o videodev.o avi_dev.o ffmpeg_dev.o \ 
     107export PJMEDIA_VIDEODEV_OBJS += videodev.o errno.o avi_dev.o ffmpeg_dev.o \ 
    109108                                colorbar_dev.o v4l2_dev.o opengl_dev.o \ 
    110109                                util.o 
    111110export PJMEDIA_VIDEODEV_CFLAGS += $(_CFLAGS) 
    112111export PJMEDIA_VIDEODEV_CXXFLAGS += $(_CXXFLAGS) 
    113 export PJMEDIA_VIDEODEV_LDFLAGS += $(PJLIB_LDLIB) \ 
     112export PJMEDIA_VIDEODEV_LDFLAGS += $(PJMEDIA_LDLIB) \ 
     113                                   $(PJLIB_LDLIB) \ 
    114114                                   $(_LDFLAGS) 
    115115 
     
    212212pjmedia: $(PJMEDIA_LIB) 
    213213$(PJMEDIA_SONAME): $(PJMEDIA_LIB) 
    214 $(PJMEDIA_LIB) $(PJMEDIA_SONAME): $(PJMEDIA_AUDIODEV_LIB) $(PJMEDIA_AUDIODEV_SONAME) $(PJMEDIA_VIDEODEV_LIB) $(PJMEDIA_VIDEODEV_SONAME) 
     214$(PJMEDIA_LIB) $(PJMEDIA_SONAME): 
    215215        $(MAKE) -f $(RULES_MAK) APP=PJMEDIA app=pjmedia $(subst /,$(HOST_PSEP),$(LIBDIR)/$@) 
    216216 
     
    222222pjmedia-videodev: $(PJMEDIA_VIDEODEV_LIB) 
    223223$(PJMEDIA_VIDEODEV_SONAME): $(PJMEDIA_VIDEODEV_LIB) 
    224 $(PJMEDIA_VIDEODEV_LIB) $(PJMEDIA_VIDEODEV_SONAME): 
     224$(PJMEDIA_VIDEODEV_LIB) $(PJMEDIA_VIDEODEV_SONAME): $(PJMEDIA_LIB) $(PJMEDIA_SONAME) 
    225225        $(MAKE) -f $(RULES_MAK) APP=PJMEDIA_VIDEODEV app=pjmedia-videodev $(subst /,$(HOST_PSEP),$(LIBDIR)/$@) 
    226226 
    227227pjmedia-audiodev: $(PJMEDIA_AUDIODEV_LIB) 
    228228$(PJMEDIA_AUDIODEV_SONAME): $(PJMEDIA_AUDIODEV_LIB) 
    229 $(PJMEDIA_AUDIODEV_LIB) $(PJMEDIA_AUDIODEV_SONAME): 
     229$(PJMEDIA_AUDIODEV_LIB) $(PJMEDIA_AUDIODEV_SONAME): $(PJMEDIA_LIB) $(PJMEDIA_SONAME) 
    230230        $(MAKE) -f $(RULES_MAK) APP=PJMEDIA_AUDIODEV app=pjmedia-audiodev $(subst /,$(HOST_PSEP),$(LIBDIR)/$@) 
    231231 
  • pjproject/trunk/pjmedia/include/pjmedia-audiodev/audiodev.h

    r5201 r5255  
    2323/** 
    2424 * @file audiodev.h 
    25  * @brief Audio device API. 
     25 * @brief Audio subsystem API. 
    2626 */ 
    27 #include <pjmedia-audiodev/config.h> 
    28 #include <pjmedia-audiodev/errno.h> 
    29 #include <pjmedia/format.h> 
    30 #include <pjmedia/frame.h> 
    31 #include <pjmedia/types.h> 
    3227#include <pj/pool.h> 
     28#include <pjmedia/audiodev.h> 
    3329 
    3430 
     
    3632 
    3733/** 
    38  * @defgroup s2_audio_device_reference Audio Device API Reference 
    39  * @ingroup audio_device_api 
     34 * @defgroup s2_audio_device_reference Audio Subsystem API Reference 
     35 * @ingroup audio_subsystem_api 
    4036 * @brief API Reference 
    4137 * @{ 
    4238 */ 
    4339 
    44 /** 
    45  * Type for device index. 
    46  */ 
    47 typedef pj_int32_t pjmedia_aud_dev_index; 
    48  
    49 /** 
    50  * Device index constants. 
    51  */ 
    52 enum 
    53 { 
    54     /**  
    55      * Constant to denote default capture device  
    56      */ 
    57     PJMEDIA_AUD_DEFAULT_CAPTURE_DEV = -1, 
    58  
    59     /**  
    60      * Constant to denote default playback device  
    61      */ 
    62     PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV = -2, 
    63  
    64     /** 
    65      * Constant to denote invalid device index. 
    66      */ 
    67     PJMEDIA_AUD_INVALID_DEV = -3 
    68 }; 
    69  
    70  
    71 /** 
    72  * This enumeration identifies various audio device capabilities. These audio 
    73  * capabilities indicates what features are supported by the underlying 
    74  * audio device implementation. 
    75  * 
    76  * Applications get these capabilities in the #pjmedia_aud_dev_info structure. 
    77  * 
    78  * Application can also set the specific features/capabilities when opening 
    79  * the audio stream by setting the \a flags member of #pjmedia_aud_param 
    80  * structure. 
    81  * 
    82  * Once audio stream is running, application can also retrieve or set some 
    83  * specific audio capability, by using #pjmedia_aud_stream_get_cap() and 
    84  * #pjmedia_aud_stream_set_cap() and specifying the desired capability. The 
    85  * value of the capability is specified as pointer, and application needs to 
    86  * supply the pointer with the correct value, according to the documentation 
    87  * of each of the capability. 
    88  */ 
    89 typedef enum pjmedia_aud_dev_cap 
    90 { 
    91     /**  
    92      * Support for audio formats other than PCM. The value of this capability 
    93      * is represented by #pjmedia_format structure. 
    94      */ 
    95     PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1, 
    96  
    97     /**  
    98      * Support for audio input latency control or query. The value of this  
    99      * capability is an unsigned integer containing milliseconds value of 
    100      * the latency. 
    101      */ 
    102     PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2, 
    103  
    104     /**  
    105      * Support for audio output latency control or query. The value of this  
    106      * capability is an unsigned integer containing milliseconds value of 
    107      * the latency. 
    108      */ 
    109     PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4, 
    110  
    111     /**  
    112      * Support for setting/retrieving the audio input device volume level. 
    113      * The value of this capability is an unsigned integer representing  
    114      * the input audio volume setting in percent. 
    115      */ 
    116     PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8, 
    117  
    118     /**  
    119      * Support for setting/retrieving the audio output device volume level. 
    120      * The value of this capability is an unsigned integer representing  
    121      * the output audio volume setting in percent. 
    122      */ 
    123     PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16, 
    124  
    125     /**  
    126      * Support for monitoring the current audio input signal volume.  
    127      * The value of this capability is an unsigned integer representing  
    128      * the audio volume in percent. 
    129      */ 
    130     PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32, 
    131  
    132     /**  
    133      * Support for monitoring the current audio output signal volume.  
    134      * The value of this capability is an unsigned integer representing  
    135      * the audio volume in percent. 
    136      */ 
    137     PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64, 
    138  
    139     /**  
    140      * Support for audio input routing. The value of this capability is an  
    141      * integer containing #pjmedia_aud_dev_route enumeration. 
    142      */ 
    143     PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128, 
    144  
    145     /**  
    146      * Support for audio output routing (e.g. loudspeaker vs earpiece). The 
    147      * value of this capability is an integer containing #pjmedia_aud_dev_route 
    148      * enumeration. 
    149      */ 
    150     PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256, 
    151  
    152     /**  
    153      * The audio device has echo cancellation feature. The value of this 
    154      * capability is a pj_bool_t containing boolean PJ_TRUE or PJ_FALSE. 
    155      */ 
    156     PJMEDIA_AUD_DEV_CAP_EC = 512, 
    157  
    158     /**  
    159      * The audio device supports setting echo cancellation fail length. The 
    160      * value of this capability is an unsigned integer representing the 
    161      * echo tail in milliseconds. 
    162      */ 
    163     PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024, 
    164  
    165     /**  
    166      * The audio device has voice activity detection feature. The value 
    167      * of this capability is a pj_bool_t containing boolean PJ_TRUE or  
    168      * PJ_FALSE. 
    169      */ 
    170     PJMEDIA_AUD_DEV_CAP_VAD = 2048, 
    171  
    172     /**  
    173      * The audio device has comfort noise generation feature. The value 
    174      * of this capability is a pj_bool_t containing boolean PJ_TRUE or  
    175      * PJ_FALSE. 
    176      */ 
    177     PJMEDIA_AUD_DEV_CAP_CNG = 4096, 
    178  
    179     /**  
    180      * The audio device has packet loss concealment feature. The value 
    181      * of this capability is a pj_bool_t containing boolean PJ_TRUE or  
    182      * PJ_FALSE. 
    183      */ 
    184     PJMEDIA_AUD_DEV_CAP_PLC = 8192, 
    185      
    186     /** 
    187      * End of capability 
    188      */ 
    189     PJMEDIA_AUD_DEV_CAP_MAX = 16384 
    190  
    191 } pjmedia_aud_dev_cap; 
    192  
    193  
    194 /** 
    195  * This enumeration describes audio routing setting. 
    196  */ 
    197 typedef enum pjmedia_aud_dev_route 
    198 { 
    199     /** 
    200      * Default route, it is the default audio route of the audio framework 
    201      * backend, as in opening audio device without specifying any route 
    202      * setting or with specifying neutral route setting. 
    203      */ 
    204     PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0, 
    205  
    206     /** Route to loudspeaker */ 
    207     PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1, 
    208  
    209     /** Route to earpiece */ 
    210     PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2, 
    211  
    212     /** Route to paired Bluetooth device */ 
    213     PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH = 4 
    214  
    215 } pjmedia_aud_dev_route; 
    216  
    217  
    218 /** 
    219  * Device information structure returned by #pjmedia_aud_dev_get_info(). 
    220  */ 
    221 typedef struct pjmedia_aud_dev_info 
    222 { 
    223     /**  
    224      * The device name  
    225      */ 
    226     char name[PJMEDIA_AUD_DEV_INFO_NAME_LEN]; 
    227  
    228     /**  
    229      * Maximum number of input channels supported by this device. If the 
    230      * value is zero, the device does not support input operation (i.e. 
    231      * it is a playback only device).  
    232      */ 
    233     unsigned input_count; 
    234  
    235     /**  
    236      * Maximum number of output channels supported by this device. If the 
    237      * value is zero, the device does not support output operation (i.e.  
    238      * it is an input only device). 
    239      */ 
    240     unsigned output_count; 
    241  
    242     /**  
    243      * Default sampling rate. 
    244      */ 
    245     unsigned default_samples_per_sec; 
    246  
    247     /**  
    248      * The underlying driver name  
    249      */ 
    250     char driver[32]; 
    251  
    252     /**  
    253      * Device capabilities, as bitmask combination of #pjmedia_aud_dev_cap. 
    254      */ 
    255     unsigned caps; 
    256  
    257     /**  
    258      * Supported audio device routes, as bitmask combination of  
    259      * #pjmedia_aud_dev_route. The value may be zero if the device 
    260      * does not support audio routing. 
    261      */ 
    262     unsigned routes; 
    263  
    264     /**  
    265      * Number of audio formats supported by this device. The value may be 
    266      * zero if the device does not support non-PCM format. 
    267      */ 
    268     unsigned ext_fmt_cnt; 
    269  
    270     /**  
    271      * Array of supported extended audio formats  
    272      */ 
    273     pjmedia_format ext_fmt[8]; 
    274  
    275  
    276 } pjmedia_aud_dev_info; 
    277  
    278  
    279 /**  
    280  * This callback is called by player stream when it needs additional data 
    281  * to be played by the device. Application must fill in the whole of output  
    282  * buffer with audio samples. 
    283  * 
    284  * The frame argument contains the following values: 
    285  *  - timestamp     Playback timestamp, in samples. 
    286  *  - buf           Buffer to be filled out by application. 
    287  *  - size          The size requested in bytes, which will be equal to 
    288  *                  the size of one whole packet. 
    289  * 
    290  * @param user_data User data associated with the stream. 
    291  * @param frame     Audio frame, which buffer is to be filled in by 
    292  *                  the application. 
    293  * 
    294  * @return          Returning non-PJ_SUCCESS will cause the audio stream 
    295  *                  to stop 
    296  */ 
    297 typedef pj_status_t (*pjmedia_aud_play_cb)(void *user_data, 
    298                                            pjmedia_frame *frame); 
    299  
    300 /** 
    301  * This callback is called by recorder stream when it has captured the whole 
    302  * packet worth of audio samples. 
    303  * 
    304  * @param user_data User data associated with the stream. 
    305  * @param frame     Captured frame. 
    306  * 
    307  * @return          Returning non-PJ_SUCCESS will cause the audio stream 
    308  *                  to stop 
    309  */ 
    310 typedef pj_status_t (*pjmedia_aud_rec_cb)(void *user_data, 
    311                                           pjmedia_frame *frame); 
    312  
    313 /** 
    314  * This structure specifies the parameters to open the audio stream. 
    315  */ 
    316 typedef struct pjmedia_aud_param 
    317 { 
    318     /** 
    319      * The audio direction. This setting is mandatory. 
    320      */ 
    321     pjmedia_dir dir; 
    322  
    323     /** 
    324      * The audio recorder device ID. This setting is mandatory if the audio 
    325      * direction includes input/capture direction. 
    326      */ 
    327     pjmedia_aud_dev_index rec_id; 
    328  
    329     /** 
    330      * The audio playback device ID. This setting is mandatory if the audio 
    331      * direction includes output/playback direction. 
    332      */ 
    333     pjmedia_aud_dev_index play_id; 
    334  
    335     /**  
    336      * Clock rate/sampling rate. This setting is mandatory.  
    337      */ 
    338     unsigned clock_rate; 
    339  
    340     /**  
    341      * Number of channels. This setting is mandatory.  
    342      */ 
    343     unsigned channel_count; 
    344  
    345     /**  
    346      * Number of samples per frame. This setting is mandatory.  
    347      */ 
    348     unsigned samples_per_frame; 
    349  
    350     /**  
    351      * Number of bits per sample. This setting is mandatory.  
    352      */ 
    353     unsigned bits_per_sample; 
    354  
    355     /**  
    356      * This flags specifies which of the optional settings are valid in this 
    357      * structure. The flags is bitmask combination of pjmedia_aud_dev_cap. 
    358      */ 
    359     unsigned flags; 
    360  
    361     /**  
    362      * Set the audio format. This setting is optional, and will only be used 
    363      * if PJMEDIA_AUD_DEV_CAP_EXT_FORMAT is set in the flags. 
    364      */ 
    365     pjmedia_format ext_fmt; 
    366  
    367     /** 
    368      * Input latency, in milliseconds. This setting is optional, and will  
    369      * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY is set in the flags. 
    370      */ 
    371     unsigned input_latency_ms; 
    372  
    373     /** 
    374      * Input latency, in milliseconds. This setting is optional, and will  
    375      * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY is set in the flags. 
    376      */ 
    377     unsigned output_latency_ms; 
    378  
    379     /** 
    380      * Input volume setting, in percent. This setting is optional, and will  
    381      * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING is set in  
    382      * the flags. 
    383      */ 
    384     unsigned input_vol; 
    385  
    386     /** 
    387      * Output volume setting, in percent. This setting is optional, and will  
    388      * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING is set in  
    389      * the flags. 
    390      */ 
    391     unsigned output_vol; 
    392  
    393     /**  
    394      * Set the audio input route. This setting is optional, and will only be 
    395      * used if PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE is set in the flags. 
    396      */ 
    397     pjmedia_aud_dev_route input_route; 
    398  
    399     /**  
    400      * Set the audio output route. This setting is optional, and will only be 
    401      * used if PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE is set in the flags. 
    402      */ 
    403     pjmedia_aud_dev_route output_route; 
    404  
    405     /** 
    406      * Enable/disable echo canceller, if the device supports it. This setting 
    407      * is optional, and will only be used if PJMEDIA_AUD_DEV_CAP_EC is set in 
    408      * the flags. 
    409      */ 
    410     pj_bool_t ec_enabled; 
    411  
    412     /** 
    413      * Set echo canceller tail length in milliseconds, if the device supports 
    414      * it. This setting is optional, and will only be used if 
    415      * PJMEDIA_AUD_DEV_CAP_EC_TAIL is set in the flags. 
    416      */ 
    417     unsigned ec_tail_ms; 
    418  
    419     /**  
    420      * Enable/disable PLC. This setting is optional, and will only be used 
    421      * if PJMEDIA_AUD_DEV_CAP_PLC is set in the flags. 
    422      */ 
    423     pj_bool_t plc_enabled; 
    424  
    425     /**  
    426      * Enable/disable CNG. This setting is optional, and will only be used 
    427      * if PJMEDIA_AUD_DEV_CAP_CNG is set in the flags. 
    428      */ 
    429     pj_bool_t cng_enabled; 
    430  
    431     /**  
    432      * Enable/disable VAD. This setting is optional, and will only be used 
    433      * if PJMEDIA_AUD_DEV_CAP_VAD is set in the flags. 
    434      */ 
    435     pj_bool_t vad_enabled; 
    436  
    437 } pjmedia_aud_param; 
    438  
    439  
    440 /** Forward declaration for pjmedia_aud_stream */ 
    441 typedef struct pjmedia_aud_stream pjmedia_aud_stream; 
    442  
    443 /** Forward declaration for audio device factory */ 
    444 typedef struct pjmedia_aud_dev_factory pjmedia_aud_dev_factory; 
    445  
    446 /* typedef for factory creation function */ 
    447 typedef pjmedia_aud_dev_factory* 
    448 (*pjmedia_aud_dev_factory_create_func_ptr)(pj_pool_factory*); 
    449  
    450  
    451 /** 
    452  * Get string info for the specified capability. 
    453  * 
    454  * @param cap           The capability ID. 
    455  * @param p_desc        Optional pointer which will be filled with longer  
    456  *                      description about the capability. 
    457  * 
    458  * @return              Capability name. 
    459  */ 
    460 PJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap, 
    461                                               const char **p_desc); 
    462  
    463  
    464 /** 
    465  * Set a capability field value in #pjmedia_aud_param structure. This will 
    466  * also set the flags field for the specified capability in the structure. 
    467  * 
    468  * @param param         The structure. 
    469  * @param cap           The audio capability which value is to be set. 
    470  * @param pval          Pointer to value. Please see the type of value to 
    471  *                      be supplied in the pjmedia_aud_dev_cap documentation. 
    472  * 
    473  * @return              PJ_SUCCESS on successful operation or the appropriate 
    474  *                      error code. 
    475  */ 
    476 PJ_DECL(pj_status_t) pjmedia_aud_param_set_cap(pjmedia_aud_param *param, 
    477                                                pjmedia_aud_dev_cap cap, 
    478                                                const void *pval); 
    479  
    480  
    481 /** 
    482  * Get a capability field value from #pjmedia_aud_param structure. This 
    483  * function will return PJMEDIA_EAUD_INVCAP error if the flag for that 
    484  * capability is not set in the flags field in the structure. 
    485  * 
    486  * @param param         The structure. 
    487  * @param cap           The audio capability which value is to be retrieved. 
    488  * @param pval          Pointer to value. Please see the type of value to 
    489  *                      be supplied in the pjmedia_aud_dev_cap documentation. 
    490  * 
    491  * @return              PJ_SUCCESS on successful operation or the appropriate 
    492  *                      error code. 
    493  */ 
    494 PJ_DECL(pj_status_t) pjmedia_aud_param_get_cap(const pjmedia_aud_param *param, 
    495                                                pjmedia_aud_dev_cap cap, 
    496                                                void *pval); 
    49740 
    49841/** 
     
    559102 
    560103/** 
    561  * Refresh the list of sound devices installed in the system. This function 
    562  * will only refresh the list of audio device so all active audio streams will 
    563  * be unaffected. After refreshing the device list, application MUST make sure 
    564  * to update all index references to audio devices (i.e. all variables of type 
    565  * pjmedia_aud_dev_index) before calling any function that accepts audio device 
    566  * index as its parameter. 
    567  * 
    568  * @return              PJ_SUCCESS on successful operation or the appropriate 
    569  *                      error code. 
    570  */ 
    571 PJ_DECL(pj_status_t) pjmedia_aud_dev_refresh(void); 
    572  
    573  
    574 /** 
    575  * Get the number of sound devices installed in the system. 
    576  * 
    577  * @return              The number of sound devices installed in the system. 
    578  */ 
    579 PJ_DECL(unsigned) pjmedia_aud_dev_count(void); 
    580  
    581  
    582 /** 
    583  * Get device information. 
    584  * 
    585  * @param id            The audio device ID. 
    586  * @param info          The device information which will be filled in by this 
    587  *                      function once it returns successfully. 
    588  * 
    589  * @return              PJ_SUCCESS on successful operation or the appropriate 
    590  *                      error code. 
    591  */ 
    592 PJ_DECL(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id, 
    593                                               pjmedia_aud_dev_info *info); 
    594  
    595  
    596 /** 
    597  * Lookup device index based on the driver and device name. 
    598  * 
    599  * @param drv_name      The driver name. 
    600  * @param dev_name      The device name. 
    601  * @param id            Pointer to store the returned device ID. 
    602  * 
    603  * @return              PJ_SUCCESS if the device can be found. 
    604  */ 
    605 PJ_DECL(pj_status_t) pjmedia_aud_dev_lookup(const char *drv_name, 
    606                                             const char *dev_name, 
    607                                             pjmedia_aud_dev_index *id); 
    608  
    609  
    610 /** 
    611  * Initialize the audio device parameters with default values for the 
    612  * specified device. 
    613  * 
    614  * @param id            The audio device ID. 
    615  * @param param         The audio device parameters which will be initialized 
    616  *                      by this function once it returns successfully. 
    617  * 
    618  * @return              PJ_SUCCESS on successful operation or the appropriate 
    619  *                      error code. 
    620  */ 
    621 PJ_DECL(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id, 
    622                                                    pjmedia_aud_param *param); 
    623  
    624  
    625 /** 
    626  * Open audio stream object using the specified parameters. 
    627  * 
    628  * @param param         Sound device parameters to be used for the stream. 
    629  * @param rec_cb        Callback to be called on every input frame captured. 
    630  * @param play_cb       Callback to be called everytime the sound device needs 
    631  *                      audio frames to be played back. 
    632  * @param user_data     Arbitrary user data, which will be given back in the 
    633  *                      callbacks. 
    634  * @param p_strm        Pointer to receive the audio stream. 
    635  * 
    636  * @return              PJ_SUCCESS on successful operation or the appropriate 
    637  *                      error code. 
    638  */ 
    639 PJ_DECL(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *param, 
    640                                                pjmedia_aud_rec_cb rec_cb, 
    641                                                pjmedia_aud_play_cb play_cb, 
    642                                                void *user_data, 
    643                                                pjmedia_aud_stream **p_strm); 
    644  
    645 /** 
    646  * Get the running parameters for the specified audio stream. 
    647  * 
    648  * @param strm          The audio stream. 
    649  * @param param         Audio stream parameters to be filled in by this  
    650  *                      function once it returns successfully. 
    651  * 
    652  * @return              PJ_SUCCESS on successful operation or the appropriate 
    653  *                      error code. 
    654  */ 
    655 PJ_DECL(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm, 
    656                                                   pjmedia_aud_param *param); 
    657  
    658 /** 
    659  * Get the value of a specific capability of the audio stream. 
    660  * 
    661  * @param strm          The audio stream. 
    662  * @param cap           The audio capability which value is to be retrieved. 
    663  * @param value         Pointer to value to be filled in by this function  
    664  *                      once it returns successfully.  Please see the type  
    665  *                      of value to be supplied in the pjmedia_aud_dev_cap 
    666  *                      documentation. 
    667  * 
    668  * @return              PJ_SUCCESS on successful operation or the appropriate 
    669  *                      error code. 
    670  */ 
    671 PJ_DECL(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm, 
    672                                                 pjmedia_aud_dev_cap cap, 
    673                                                 void *value); 
    674  
    675 /** 
    676  * Set the value of a specific capability of the audio stream. 
    677  * 
    678  * @param strm          The audio stream. 
    679  * @param cap           The audio capability which value is to be set. 
    680  * @param value         Pointer to value. Please see the type of value to 
    681  *                      be supplied in the pjmedia_aud_dev_cap documentation. 
    682  * 
    683  * @return              PJ_SUCCESS on successful operation or the appropriate 
    684  *                      error code. 
    685  */ 
    686 PJ_DECL(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm, 
    687                                                 pjmedia_aud_dev_cap cap, 
    688                                                 const void *value); 
    689  
    690 /** 
    691  * Start the stream. 
    692  * 
    693  * @param strm          The audio stream. 
    694  * 
    695  * @return              PJ_SUCCESS on successful operation or the appropriate 
    696  *                      error code. 
    697  */ 
    698 PJ_DECL(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm); 
    699  
    700 /** 
    701  * Stop the stream. 
    702  * 
    703  * @param strm          The audio stream. 
    704  * 
    705  * @return              PJ_SUCCESS on successful operation or the appropriate 
    706  *                      error code. 
    707  */ 
    708 PJ_DECL(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm); 
    709  
    710 /** 
    711  * Destroy the stream. 
    712  * 
    713  * @param strm          The audio stream. 
    714  * 
    715  * @return              PJ_SUCCESS on successful operation or the appropriate 
    716  *                      error code. 
    717  */ 
    718 PJ_DECL(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm); 
    719  
    720  
    721 /** 
    722104 * @} 
    723105 */ 
  • pjproject/trunk/pjmedia/include/pjmedia-videodev/videodev.h

    r5125 r5255  
    2424 * @brief Video device API. 
    2525 */ 
    26 #include <pjmedia-videodev/config.h> 
    27 #include <pjmedia-videodev/errno.h> 
    28 #include <pjmedia/event.h> 
    29 #include <pjmedia/frame.h> 
    30 #include <pjmedia/format.h> 
    31 #include <pj/pool.h> 
     26#include <pjmedia/videodev.h> 
    3227 
    3328 
     
    3530 
    3631/** 
    37  * @defgroup video_device_reference Video Device API Reference 
    38  * @ingroup video_device_api 
     32 * @defgroup video_device_reference Video Subsystem API Reference 
     33 * @ingroup video_subsystem_api 
    3934 * @brief API Reference 
    4035 * @{ 
    4136 */ 
    4237  
    43 /** 
    44  * Type for device index. 
    45  */ 
    46 typedef pj_int32_t pjmedia_vid_dev_index; 
    47  
    48 /** 
    49  * Enumeration of window handle type. 
    50  */ 
    51 typedef enum pjmedia_vid_dev_hwnd_type 
    52 { 
    53     /** 
    54      * Type none. 
    55      */ 
    56     PJMEDIA_VID_DEV_HWND_TYPE_NONE, 
    57  
    58     /** 
    59      * Native window handle on Windows. 
    60      */ 
    61     PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS, 
    62  
    63     /** 
    64      * Native view on iOS. 
    65      */ 
    66     PJMEDIA_VID_DEV_HWND_TYPE_IOS, 
    67  
    68     /** 
    69      * Native window handle on Android. 
    70      */ 
    71     PJMEDIA_VID_DEV_HWND_TYPE_ANDROID 
    72  
    73 } pjmedia_vid_dev_hwnd_type; 
    74  
    75 /** 
    76  * Type for window handle. 
    77  */ 
    78 typedef struct pjmedia_vid_dev_hwnd 
    79 { 
    80     /** 
    81      * The window handle type. 
    82      */ 
    83     pjmedia_vid_dev_hwnd_type type; 
    84  
    85     /** 
    86      * The window handle. 
    87      */ 
    88     union 
    89     { 
    90         struct { 
    91             void    *hwnd;      /**< HWND       */ 
    92         } win; 
    93         struct { 
    94             void    *window;    /**< Window     */ 
    95             void    *display;   /**< Display    */ 
    96         } x11; 
    97         struct { 
    98             void    *window;    /**< Window     */ 
    99         } cocoa; 
    100         struct { 
    101             void    *window;    /**< Window     */ 
    102         } ios; 
    103         struct { 
    104             void    *window;    /**< Native window */ 
    105         } android; 
    106         void        *window; 
    107     } info; 
    108  
    109 } pjmedia_vid_dev_hwnd; 
    110  
    111 /** 
    112  * Parameter for switching device with PJMEDIA_VID_DEV_CAP_SWITCH capability. 
    113  * Initialize this with pjmedia_vid_dev_switch_param_default() 
    114  */ 
    115 typedef struct pjmedia_vid_dev_switch_param 
    116 { 
    117     /** 
    118      * Target device ID to switch to. Once the switching is successful, the 
    119      * video stream will use this device and the old device will be closed. 
    120      */ 
    121     pjmedia_vid_dev_index target_id; 
    122  
    123 } pjmedia_vid_dev_switch_param; 
    124  
    125  
    126 /** 
    127  * Enumeration of window flags. 
    128  */ 
    129 typedef enum pjmedia_vid_dev_wnd_flag 
    130 { 
    131     /** 
    132      * Window with border. 
    133      */ 
    134     PJMEDIA_VID_DEV_WND_BORDER = 1, 
    135  
    136     /** 
    137      * Window can be resized. 
    138      */ 
    139     PJMEDIA_VID_DEV_WND_RESIZABLE = 2 
    140  
    141 } pjmedia_vid_dev_wnd_flag; 
    142  
    143  
    144 /** 
    145  * Device index constants. 
    146  */ 
    147 enum pjmedia_vid_dev_std_index 
    148 { 
    149     /** 
    150      * Constant to denote default capture device 
    151      */ 
    152     PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1, 
    153  
    154     /** 
    155      * Constant to denote default render device 
    156      */ 
    157     PJMEDIA_VID_DEFAULT_RENDER_DEV = -2, 
    158  
    159     /** 
    160      * Constant to denote invalid device index. 
    161      */ 
    162     PJMEDIA_VID_INVALID_DEV = -3 
    163 }; 
    164  
    165  
    166 /** 
    167  * This enumeration identifies various video device capabilities. These video 
    168  * capabilities indicates what features are supported by the underlying 
    169  * video device implementation. 
    170  * 
    171  * Applications get these capabilities in the #pjmedia_vid_dev_info structure. 
    172  * 
    173  * Application can also set the specific features/capabilities when opening 
    174  * the video stream by setting the \a flags member of #pjmedia_vid_dev_param 
    175  * structure. 
    176  * 
    177  * Once video stream is running, application can also retrieve or set some 
    178  * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and 
    179  * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The 
    180  * value of the capability is specified as pointer, and application needs to 
    181  * supply the pointer with the correct value, according to the documentation 
    182  * of each of the capability. 
    183  */ 
    184 typedef enum pjmedia_vid_dev_cap 
    185 { 
    186     /** 
    187      * Support for video formats. The value of this capability 
    188      * is represented by #pjmedia_format structure. 
    189      */ 
    190     PJMEDIA_VID_DEV_CAP_FORMAT = 1, 
    191  
    192     /** 
    193      * Support for video input scaling 
    194      */ 
    195     PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2, 
    196  
    197     /** 
    198      * Support for returning the native window handle of the video window. 
    199      * For renderer, this means the window handle of the renderer window, 
    200      * while for capture, this means the window handle of the native preview, 
    201      * only if the device supports  PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW 
    202      * capability. 
    203      * 
    204      * The value of this capability is pointer to pjmedia_vid_dev_hwnd 
    205      * structure. 
    206      */ 
    207     PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4, 
    208  
    209     /** 
    210      * Support for resizing video output. This capability SHOULD be  
    211      * implemented by renderer, to alter the video output dimension on the fly. 
    212      * Value is pjmedia_rect_size.  
    213      */ 
    214     PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8, 
    215  
    216     /** 
    217      * Support for setting the video window's position. 
    218      * Value is pjmedia_coord specifying the window's new coordinate. 
    219      */ 
    220     PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16, 
    221  
    222     /** 
    223      * Support for setting the video output's visibility. 
    224      * The value of this capability is a pj_bool_t containing boolean 
    225      * PJ_TRUE or PJ_FALSE. 
    226      */ 
    227     PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32, 
    228  
    229     /** 
    230      * Support for native preview capability in capture devices. Value is 
    231      * pj_bool_t. With native preview, capture device can be instructed to 
    232      * show or hide a preview window showing video directly from the camera 
    233      * by setting this capability to PJ_TRUE or PJ_FALSE. Once the preview 
    234      * is started, application may use PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW 
    235      * capability to query the video window. 
    236      * 
    237      * The value of this capability is a pj_bool_t containing boolean 
    238      * PJ_TRUE or PJ_FALSE. 
    239      */ 
    240     PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW = 64, 
    241  
    242     /** 
    243      * Support for changing video orientation. For a renderer device, 
    244      * changing video orientation in will potentially affect the size of 
    245      * render window, i.e: width and height swap. For a capture device, 
    246      * the video will be rotated but the size of the video frame 
    247      * will stay the same, so the video may be resized or stretched. 
    248      * 
    249      * The value of this capability is pjmedia_orient. 
    250      */ 
    251     PJMEDIA_VID_DEV_CAP_ORIENTATION = 128, 
    252  
    253     /** 
    254      * Support for fast switching to another device. A video stream with this 
    255      * capability allows replacing of its underlying device with another 
    256      * device, saving the user from opening a new video stream and gets a much 
    257      * faster and smoother switching action. 
    258      * 
    259      * Note that even when this capability is supported by a device, it may 
    260      * not be able to switch to arbitrary device. Application must always 
    261      * check the return value of the operation to verify that switching has 
    262      * occurred. 
    263      * 
    264      * This capability is currently write-only (i.e. set-only). 
    265      * 
    266      * The value of this capability is pointer to pjmedia_vid_dev_switch_param 
    267      * structure. 
    268      */ 
    269     PJMEDIA_VID_DEV_CAP_SWITCH = 256, 
    270  
    271     /** 
    272      * Support for setting the output video window's flags. 
    273      * The value of this capability is a bitmask combination of 
    274      * #pjmedia_vid_dev_wnd_flag. 
    275      */ 
    276     PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS = 512, 
    277  
    278     /** 
    279      * End of standard capability 
    280      */ 
    281     PJMEDIA_VID_DEV_CAP_MAX = 16384 
    282  
    283 } pjmedia_vid_dev_cap; 
    284  
    285 /** 
    286  * Device information structure returned by #pjmedia_vid_dev_get_info(). 
    287  */ 
    288 typedef struct pjmedia_vid_dev_info 
    289 { 
    290     /** The device ID */ 
    291     pjmedia_vid_dev_index id; 
    292  
    293     /** The device name */ 
    294     char name[64]; 
    295  
    296     /** The underlying driver name */ 
    297     char driver[32]; 
    298  
    299     /**  
    300      * The supported direction of the video device, i.e. whether it supports  
    301      * capture only, render only, or both. 
    302      */ 
    303     pjmedia_dir dir; 
    304  
    305     /** 
    306      * Specify whether the device supports callback. Devices that implement 
    307      * "active interface" will actively call the callbacks to give or ask for 
    308      * video frames. If the device doesn't support callback, application 
    309      * must actively request or give video frames from/to the device by using 
    310      * pjmedia_vid_dev_stream_get_frame()/pjmedia_vid_dev_stream_put_frame(). 
    311      */ 
    312     pj_bool_t has_callback; 
    313  
    314     /** Device capabilities, as bitmask combination of #pjmedia_vid_dev_cap */ 
    315     unsigned caps; 
    316  
    317     /** Number of video formats supported by this device */ 
    318     unsigned fmt_cnt; 
    319  
    320     /**  
    321      * Array of supported video formats. Some fields in each supported video 
    322      * format may be set to zero or of "unknown" value, to indicate that the 
    323      * value is unknown or should be ignored. When these value are not set 
    324      * to zero, it indicates that the exact format combination is being used.  
    325      */ 
    326     pjmedia_format fmt[PJMEDIA_VID_DEV_INFO_FMT_CNT]; 
    327  
    328 } pjmedia_vid_dev_info; 
    329  
    330  
    331 /** Forward declaration for pjmedia_vid_dev_stream */ 
    332 typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream; 
    333  
    334 typedef struct pjmedia_vid_dev_cb 
    335 { 
    336     /** 
    337     * This callback is called by capturer stream when it has captured the 
    338     * whole packet worth of video samples. 
    339     * 
    340     * @param stream        The video stream. 
    341     * @param user_data     User data associated with the stream. 
    342     * @param frame         Captured frame. 
    343     * 
    344     * @return              Returning non-PJ_SUCCESS will cause the video 
    345     *                      stream to stop 
    346     */ 
    347     pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream, 
    348                               void *user_data, 
    349                               pjmedia_frame *frame); 
    350  
    351     /** 
    352     * This callback is called by renderer stream when it needs additional 
    353     * data to be rendered by the device. Application must fill in the whole 
    354     * of output buffer with video samples. 
    355     * 
    356     * The frame argument contains the following values: 
    357     *  - timestamp         Rendering timestamp, in samples. 
    358     *  - buf               Buffer to be filled out by application. 
    359     *  - size              The size requested in bytes, which will be equal 
    360     *                      to the size of one whole packet. 
    361     * 
    362     * @param stream        The video stream. 
    363     * @param user_data     User data associated with the stream. 
    364     * @param frame         Video frame, which buffer is to be filled in by 
    365     *                      the application. 
    366     * 
    367     * @return              Returning non-PJ_SUCCESS will cause the video  
    368     *                      stream to stop 
    369     */ 
    370     pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream, 
    371                              void *user_data, 
    372                              pjmedia_frame *frame); 
    373  
    374 } pjmedia_vid_dev_cb; 
    375  
    376  
    377 /** 
    378  * This structure specifies the parameters to open the video stream. 
    379  */ 
    380 typedef struct pjmedia_vid_dev_param 
    381 { 
    382     /** 
    383      * The video direction. This setting is mandatory. 
    384      */ 
    385     pjmedia_dir dir; 
    386  
    387     /** 
    388      * The video capture device ID. This setting is mandatory if the video 
    389      * direction includes input/capture direction. 
    390      */ 
    391     pjmedia_vid_dev_index cap_id; 
    392  
    393     /** 
    394      * The video render device ID. This setting is mandatory if the video 
    395      * direction includes output/render direction. 
    396      */ 
    397     pjmedia_vid_dev_index rend_id; 
    398  
    399     /**  
    400      * Video clock rate. This setting is mandatory if the video 
    401      * direction includes input/capture direction 
    402      */ 
    403     unsigned clock_rate; 
    404  
    405     /** 
    406      * Video frame rate. This setting is mandatory if the video 
    407      * direction includes input/capture direction 
    408      */ 
    409 //    pjmedia_ratio frame_rate; 
    410  
    411     /** 
    412      * This flags specifies which of the optional settings are valid in this 
    413      * structure. The flags is bitmask combination of pjmedia_vid_dev_cap. 
    414      */ 
    415     unsigned flags; 
    416  
    417     /** 
    418      * Set the video format. This setting is mandatory. 
    419      */ 
    420     pjmedia_format fmt; 
    421  
    422     /** 
    423      * Window for the renderer to display the video. This setting is optional, 
    424      * and will only be used if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW is set in  
    425      * the flags. 
    426      */ 
    427     pjmedia_vid_dev_hwnd window; 
    428  
    429     /** 
    430      * Video display size. This setting is optional, and will only be used  
    431      * if PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE is set in the flags. 
    432      */ 
    433     pjmedia_rect_size disp_size; 
    434  
    435     /** 
    436      * Video window position. This setting is optional, and will only be used 
    437      * if PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION is set in the flags. 
    438      */ 
    439     pjmedia_coord window_pos; 
    440  
    441     /** 
    442      * Video window's visibility. This setting is optional, and will only be 
    443      * used if PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE is set in the flags. 
    444      */ 
    445     pj_bool_t window_hide; 
    446  
    447     /** 
    448      * Enable built-in preview. This setting is optional and is only used 
    449      * if PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW capability is supported and 
    450      * set in the flags. 
    451      */ 
    452     pj_bool_t native_preview; 
    453  
    454     /** 
    455      * Video orientation. This setting is optional and is only used if 
    456      * PJMEDIA_VID_DEV_CAP_ORIENTATION capability is supported and is 
    457      * set in the flags. 
    458      */ 
    459     pjmedia_orient orient; 
    460  
    461     /** 
    462      * Video window flags. This setting is optional, and will only be used 
    463      * if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS is set in the flags. 
    464      */ 
    465     unsigned window_flags; 
    466  
    467 } pjmedia_vid_dev_param; 
    468  
    469  
    470 /** Forward declaration for video device factory */ 
    471 typedef struct pjmedia_vid_dev_factory pjmedia_vid_dev_factory; 
    472  
    473 /* typedef for factory creation function */ 
    474 typedef pjmedia_vid_dev_factory* 
    475 (*pjmedia_vid_dev_factory_create_func_ptr)(pj_pool_factory*); 
    476  
    477 /** 
    478  * Initialize pjmedia_vid_dev_switch_param. 
    479  * 
    480  * @param p         Parameter to be initialized. 
    481  */ 
    482 PJ_INLINE(void) 
    483 pjmedia_vid_dev_switch_param_default(pjmedia_vid_dev_switch_param *p) 
    484 { 
    485     pj_bzero(p, sizeof(*p)); 
    486     p->target_id = PJMEDIA_VID_INVALID_DEV; 
    487 } 
    488  
    489 /** 
    490  * Get string info for the specified capability. 
    491  * 
    492  * @param cap       The capability ID. 
    493  * @param p_desc    Optional pointer which will be filled with longer 
    494  *                  description about the capability. 
    495  * 
    496  * @return          Capability name. 
    497  */ 
    498 PJ_DECL(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap, 
    499                                               const char **p_desc); 
    500  
    501  
    502 /** 
    503  * Set a capability field value in #pjmedia_vid_dev_param structure. This will 
    504  * also set the flags field for the specified capability in the structure. 
    505  * 
    506  * @param param     The structure. 
    507  * @param cap       The video capability which value is to be set. 
    508  * @param pval      Pointer to value. Please see the type of value to 
    509  *                  be supplied in the pjmedia_vid_dev_cap documentation. 
    510  * 
    511  * @return          PJ_SUCCESS on successful operation or the appropriate 
    512  *                  error code. 
    513  */ 
    514 PJ_DECL(pj_status_t) 
    515 pjmedia_vid_dev_param_set_cap(pjmedia_vid_dev_param *param, 
    516                               pjmedia_vid_dev_cap cap, 
    517                               const void *pval); 
    518  
    519  
    520 /** 
    521  * Get a capability field value from #pjmedia_vid_dev_param structure. This 
    522  * function will return PJMEDIA_EVID_INVCAP error if the flag for that 
    523  * capability is not set in the flags field in the structure. 
    524  * 
    525  * @param param     The structure. 
    526  * @param cap       The video capability which value is to be retrieved. 
    527  * @param pval      Pointer to value. Please see the type of value to 
    528  *                  be supplied in the pjmedia_vid_dev_cap documentation. 
    529  * 
    530  * @return          PJ_SUCCESS on successful operation or the appropriate 
    531  *                  error code. 
    532  */ 
    533 PJ_DECL(pj_status_t) 
    534 pjmedia_vid_dev_param_get_cap(const pjmedia_vid_dev_param *param, 
    535                               pjmedia_vid_dev_cap cap, 
    536                               void *pval); 
    53738 
    53839/** 
     
    611112 
    612113/** 
    613  * Refresh the list of video devices installed in the system. This function 
    614  * will only refresh the list of videoo device so all active video streams will 
    615  * be unaffected. After refreshing the device list, application MUST make sure 
    616  * to update all index references to video devices (i.e. all variables of type 
    617  * pjmedia_vid_dev_index) before calling any function that accepts video device 
    618  * index as its parameter. 
    619  * 
    620  * @return              PJ_SUCCESS on successful operation or the appropriate 
    621  *                      error code. 
    622  */ 
    623 PJ_DECL(pj_status_t) pjmedia_vid_dev_refresh(void); 
    624  
    625  
    626 /** 
    627  * Get the number of video devices installed in the system. 
    628  * 
    629  * @return          The number of video devices installed in the system. 
    630  */ 
    631 PJ_DECL(unsigned) pjmedia_vid_dev_count(void); 
    632  
    633  
    634 /** 
    635  * Get device information. 
    636  * 
    637  * @param id        The video device ID. 
    638  * @param info      The device information which will be filled in by this 
    639  *                  function once it returns successfully. 
    640  * 
    641  * @return          PJ_SUCCESS on successful operation or the appropriate 
    642  *                  error code. 
    643  */ 
    644 PJ_DECL(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id, 
    645                                               pjmedia_vid_dev_info *info); 
    646  
    647  
    648 /** 
    649  * Lookup device index based on the driver and device name. 
    650  * 
    651  * @param drv_name  The driver name. 
    652  * @param dev_name  The device name. 
    653  * @param id        Pointer to store the returned device ID. 
    654  * 
    655  * @return          PJ_SUCCESS if the device can be found. 
    656  */ 
    657 PJ_DECL(pj_status_t) pjmedia_vid_dev_lookup(const char *drv_name, 
    658                                             const char *dev_name, 
    659                                             pjmedia_vid_dev_index *id); 
    660  
    661  
    662 /** 
    663  * Initialize the video device parameters with default values for the 
    664  * specified device. 
    665  * 
    666  * @param id        The video device ID. 
    667  * @param param     The video device parameters which will be initialized 
    668  *                  by this function once it returns successfully. 
    669  * 
    670  * @return          PJ_SUCCESS on successful operation or the appropriate 
    671  *                  error code. 
    672  */ 
    673 PJ_DECL(pj_status_t) 
    674 pjmedia_vid_dev_default_param(pj_pool_t *pool, 
    675                               pjmedia_vid_dev_index id, 
    676                               pjmedia_vid_dev_param *param); 
    677  
    678  
    679 /** 
    680  * Open video stream object using the specified parameters. If stream is 
    681  * created successfully, this function will return PJ_SUCCESS and the 
    682  * stream pointer will be returned in the p_strm argument. 
    683  * 
    684  * The opened stream may have been opened with different size and fps 
    685  * than the requested values in the \a param argument. Application should 
    686  * check the actual size and fps that the stream was opened with by inspecting 
    687  * the values in the \a param argument and see if they have changed. Also 
    688  * if the device ID in the \a param specifies default device, it may be 
    689  * replaced with the actual device ID upon return. 
    690  * 
    691  * @param param         On input, it specifies the video device parameters 
    692  *                      to be used for the stream. On output, this will be 
    693  *                      set to the actual video device parameters used to 
    694  *                      open the stream. 
    695  * @param cb            Pointer to structure containing video stream 
    696  *                      callbacks. 
    697  * @param user_data     Arbitrary user data, which will be given back in the 
    698  *                      callbacks. 
    699  * @param p_strm        Pointer to receive the video stream. 
    700  * 
    701  * @return              PJ_SUCCESS on successful operation or the appropriate 
    702  *                      error code. 
    703  */ 
    704 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create( 
    705                                             pjmedia_vid_dev_param *param, 
    706                                             const pjmedia_vid_dev_cb *cb, 
    707                                             void *user_data, 
    708                                             pjmedia_vid_dev_stream **p_strm); 
    709  
    710 /** 
    711  * Get the running parameters for the specified video stream. 
    712  * 
    713  * @param strm      The video stream. 
    714  * @param param     Video stream parameters to be filled in by this 
    715  *                  function once it returns successfully. 
    716  * 
    717  * @return          PJ_SUCCESS on successful operation or the appropriate 
    718  *                  error code. 
    719  */ 
    720 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param( 
    721                                             pjmedia_vid_dev_stream *strm, 
    722                                             pjmedia_vid_dev_param *param); 
    723  
    724 /** 
    725  * Get the value of a specific capability of the video stream. 
    726  * 
    727  * @param strm      The video stream. 
    728  * @param cap       The video capability which value is to be retrieved. 
    729  * @param value     Pointer to value to be filled in by this function 
    730  *                  once it returns successfully.  Please see the type 
    731  *                  of value to be supplied in the pjmedia_vid_dev_cap 
    732  *                  documentation. 
    733  * 
    734  * @return          PJ_SUCCESS on successful operation or the appropriate 
    735  *                  error code. 
    736  */ 
    737 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap( 
    738                                             pjmedia_vid_dev_stream *strm, 
    739                                             pjmedia_vid_dev_cap cap, 
    740                                             void *value); 
    741  
    742 /** 
    743  * Set the value of a specific capability of the video stream. 
    744  * 
    745  * @param strm      The video stream. 
    746  * @param cap       The video capability which value is to be set. 
    747  * @param value     Pointer to value. Please see the type of value to 
    748  *                  be supplied in the pjmedia_vid_dev_cap documentation. 
    749  * 
    750  * @return          PJ_SUCCESS on successful operation or the appropriate 
    751  *                  error code. 
    752  */ 
    753 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap( 
    754                                             pjmedia_vid_dev_stream *strm, 
    755                                             pjmedia_vid_dev_cap cap, 
    756                                             const void *value); 
    757  
    758 /** 
    759  * Start the stream. 
    760  * 
    761  * @param strm      The video stream. 
    762  * 
    763  * @return          PJ_SUCCESS on successful operation or the appropriate 
    764  *                  error code. 
    765  */ 
    766 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start( 
    767                                             pjmedia_vid_dev_stream *strm); 
    768  
    769 /** 
    770  * Query whether the stream has been started. 
    771  * 
    772  * @param strm      The video stream 
    773  * 
    774  * @return          PJ_TRUE if the video stream has been started. 
    775  */ 
    776 PJ_DECL(pj_bool_t) pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm); 
    777  
    778  
    779 /** 
    780  * Request one frame from the stream. Application needs to call this function 
    781  * periodically only if the stream doesn't support "active interface", i.e. 
    782  * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE. 
    783  * 
    784  * @param strm      The video stream. 
    785  * @param frame     The video frame to be filled by the device. 
    786  * 
    787  * @return          PJ_SUCCESS on successful operation or the appropriate 
    788  *                  error code. 
    789  */ 
    790 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame( 
    791                                             pjmedia_vid_dev_stream *strm, 
    792                                             pjmedia_frame *frame); 
    793  
    794 /** 
    795  * Put one frame to the stream. Application needs to call this function 
    796  * periodically only if the stream doesn't support "active interface", i.e. 
    797  * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE. 
    798  * 
    799  * @param strm      The video stream. 
    800  * @param frame     The video frame to put to the device. 
    801  * 
    802  * @return          PJ_SUCCESS on successful operation or the appropriate 
    803  *                  error code. 
    804  */ 
    805 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame( 
    806                                             pjmedia_vid_dev_stream *strm, 
    807                                             const pjmedia_frame *frame); 
    808  
    809 /** 
    810  * Stop the stream. 
    811  * 
    812  * @param strm      The video stream. 
    813  * 
    814  * @return          PJ_SUCCESS on successful operation or the appropriate 
    815  *                  error code. 
    816  */ 
    817 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop( 
    818                                             pjmedia_vid_dev_stream *strm); 
    819  
    820 /** 
    821  * Destroy the stream. 
    822  * 
    823  * @param strm      The video stream. 
    824  * 
    825  * @return          PJ_SUCCESS on successful operation or the appropriate 
    826  *                  error code. 
    827  */ 
    828 PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy( 
    829                                             pjmedia_vid_dev_stream *strm); 
    830  
    831  
    832 /** 
    833114 * @} 
    834115 */ 
  • pjproject/trunk/pjmedia/include/pjmedia/endpoint.h

    r4474 r5255  
    4141#include <pjmedia/sdp.h> 
    4242#include <pjmedia/transport.h> 
     43#include <pjmedia-audiodev/audiodev.h> 
    4344 
    4445 
     
    8283 * @return              PJ_SUCCESS on success. 
    8384 */ 
    84 PJ_DECL(pj_status_t) pjmedia_endpt_create( pj_pool_factory *pf, 
     85PJ_DECL(pj_status_t) pjmedia_endpt_create2(pj_pool_factory *pf, 
    8586                                           pj_ioqueue_t *ioqueue, 
    8687                                           unsigned worker_cnt, 
     
    8889 
    8990/** 
     91 * Create an instance of media endpoint and initialize audio subsystem. 
     92 * 
     93 * @param pf            Pool factory, which will be used by the media endpoint 
     94 *                      throughout its lifetime. 
     95 * @param ioqueue       Optional ioqueue instance to be registered to the  
     96 *                      endpoint. The ioqueue instance is used to poll all RTP 
     97 *                      and RTCP sockets. If this argument is NULL, the  
     98 *                      endpoint will create an internal ioqueue instance. 
     99 * @param worker_cnt    Specify the number of worker threads to be created 
     100 *                      to poll the ioqueue. 
     101 * @param p_endpt       Pointer to receive the endpoint instance. 
     102 * 
     103 * @return              PJ_SUCCESS on success. 
     104 */ 
     105PJ_INLINE(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf, 
     106                                            pj_ioqueue_t *ioqueue, 
     107                                            unsigned worker_cnt, 
     108                                            pjmedia_endpt **p_endpt) 
     109{ 
     110    /* This function is inlined to avoid build problem due to circular 
     111     * dependency, i.e: this function prevents pjmedia's dependency on 
     112     * pjmedia-audiodev. 
     113     */ 
     114 
     115    pj_status_t status; 
     116 
     117    /* Sound */ 
     118    status = pjmedia_aud_subsys_init(pf); 
     119    if (status != PJ_SUCCESS) 
     120        return status; 
     121 
     122    status = pjmedia_endpt_create2(pf, ioqueue, worker_cnt, p_endpt); 
     123    if (status != PJ_SUCCESS) { 
     124        pjmedia_aud_subsys_shutdown(); 
     125    } 
     126     
     127    return status; 
     128} 
     129 
     130/** 
    90131 * Destroy media endpoint instance. 
    91132 * 
     
    94135 * @return              PJ_SUCCESS on success. 
    95136 */ 
    96 PJ_DECL(pj_status_t) pjmedia_endpt_destroy(pjmedia_endpt *endpt); 
     137PJ_DECL(pj_status_t) pjmedia_endpt_destroy2(pjmedia_endpt *endpt); 
     138 
     139/** 
     140 * Destroy media endpoint instance and shutdown audio subsystem. 
     141 * 
     142 * @param endpt         Media endpoint instance. 
     143 * 
     144 * @return              PJ_SUCCESS on success. 
     145 */ 
     146PJ_INLINE(pj_status_t) pjmedia_endpt_destroy(pjmedia_endpt *endpt) 
     147{ 
     148    /* This function is inlined to avoid build problem due to circular 
     149     * dependency, i.e: this function prevents pjmedia's dependency on 
     150     * pjmedia-audiodev. 
     151     */ 
     152     pj_status_t status = pjmedia_endpt_destroy2(endpt); 
     153     pjmedia_aud_subsys_shutdown(); 
     154     return status; 
     155} 
    97156 
    98157/** 
  • pjproject/trunk/pjmedia/include/pjmedia/sound.h

    r5201 r5255  
    141141 * @return              Zero on success. 
    142142 */ 
    143 PJ_DECL(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory); 
    144  
     143PJ_INLINE(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory) 
     144{ 
     145    /* This function is inlined to avoid pjmedia's dependency on 
     146     * pjmedia-audiodev. 
     147     */ 
     148    return pjmedia_aud_subsys_init(factory); 
     149} 
    145150 
    146151/** 
     
    324329 * @return              Zero on success. 
    325330 */ 
    326 PJ_DECL(pj_status_t) pjmedia_snd_deinit(void); 
     331PJ_INLINE(pj_status_t) pjmedia_snd_deinit(void) 
     332{ 
     333    /* This function is inlined to avoid pjmedia's dependency on 
     334     * pjmedia-audiodev. 
     335     */ 
     336    return pjmedia_aud_subsys_shutdown(); 
     337} 
    327338 
    328339 
  • pjproject/trunk/pjmedia/src/pjmedia-audiodev/audiodev.c

    r4879 r5255  
    2020#include <pjmedia-audiodev/audiodev_imp.h> 
    2121#include <pj/assert.h> 
    22 #include <pj/errno.h> 
    23 #include <pj/log.h> 
    24 #include <pj/pool.h> 
    25 #include <pj/string.h> 
    2622 
    2723#define THIS_FILE   "audiodev.c" 
    28  
    29 #define DEFINE_CAP(name, info)  {name, info} 
    30  
    31 /* Capability names */ 
    32 static struct cap_info 
    33 { 
    34     const char *name; 
    35     const char *info; 
    36 } cap_infos[] =  
    37 { 
    38     DEFINE_CAP("ext-fmt",     "Extended/non-PCM format"), 
    39     DEFINE_CAP("latency-in",  "Input latency/buffer size setting"), 
    40     DEFINE_CAP("latency-out", "Output latency/buffer size setting"), 
    41     DEFINE_CAP("vol-in",      "Input volume setting"), 
    42     DEFINE_CAP("vol-out",     "Output volume setting"), 
    43     DEFINE_CAP("meter-in",    "Input meter"), 
    44     DEFINE_CAP("meter-out",   "Output meter"), 
    45     DEFINE_CAP("route-in",    "Input routing"), 
    46     DEFINE_CAP("route-out",   "Output routing"), 
    47     DEFINE_CAP("aec",         "Accoustic echo cancellation"), 
    48     DEFINE_CAP("aec-tail",    "Tail length setting for AEC"), 
    49     DEFINE_CAP("vad",         "Voice activity detection"), 
    50     DEFINE_CAP("cng",         "Comfort noise generation"), 
    51     DEFINE_CAP("plg",         "Packet loss concealment") 
    52 }; 
    53  
    54  
    55 /* 
    56  * The device index seen by application and driver is different.  
    57  * 
    58  * At application level, device index is index to global list of device. 
    59  * At driver level, device index is index to device list on that particular 
    60  * factory only. 
    61  */ 
    62 #define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF)) 
    63 #define GET_INDEX(dev_id)          ((dev_id) & 0xFFFF) 
    64 #define GET_FID(dev_id)            ((dev_id) >> 16) 
    65 #define DEFAULT_DEV_ID              0 
    6624 
    6725 
     
    11573#endif 
    11674 
    117 #define MAX_DRIVERS     16 
    118 #define MAX_DEVS        64 
    119  
    120  
    121 /* driver structure */ 
    122 struct driver 
    123 { 
    124     /* Creation function */ 
    125     pjmedia_aud_dev_factory_create_func_ptr create; 
    126     /* Factory instance */ 
    127     pjmedia_aud_dev_factory *f; 
    128     char                     name[32];  /* Driver name                      */ 
    129     unsigned                 dev_cnt;   /* Number of devices                */ 
    130     unsigned                 start_idx; /* Start index in global list       */ 
    131     int                      rec_dev_idx;/* Default capture device.         */ 
    132     int                      play_dev_idx;/* Default playback device        */ 
    133     int                      dev_idx;   /* Default device.                  */ 
    134 }; 
    135  
    136 /* The audio subsystem */ 
    137 static struct aud_subsys 
    138 { 
    139     unsigned         init_count;        /* How many times init() is called  */ 
    140     pj_pool_factory *pf;                /* The pool factory.                */ 
    141  
    142     unsigned         drv_cnt;           /* Number of drivers.               */ 
    143     struct driver    drv[MAX_DRIVERS];  /* Array of drivers.                */ 
    144  
    145     unsigned         dev_cnt;           /* Total number of devices.         */ 
    146     pj_uint32_t      dev_list[MAX_DEVS];/* Array of device IDs.             */ 
    147  
    148 } aud_subsys; 
    149  
    150 /* API: get capability name/info */ 
    151 PJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap, 
    152                                              const char **p_desc) 
    153 { 
    154     const char *desc; 
    155     unsigned i; 
    156  
    157     if (p_desc==NULL) p_desc = &desc; 
    158  
    159     for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) { 
    160         if ((1 << i)==cap) 
    161             break; 
    162     } 
    163  
    164     if (i==PJ_ARRAY_SIZE(cap_infos)) { 
    165         *p_desc = "??"; 
    166         return "??"; 
    167     } 
    168  
    169     *p_desc = cap_infos[i].info; 
    170     return cap_infos[i].name; 
    171 } 
    172  
    173 static pj_status_t get_cap_pointer(const pjmedia_aud_param *param, 
    174                                    pjmedia_aud_dev_cap cap, 
    175                                    void **ptr, 
    176                                    unsigned *size) 
    177 { 
    178 #define FIELD_INFO(name)    *ptr = (void*)&param->name; \ 
    179                             *size = sizeof(param->name) 
    180  
    181     switch (cap) { 
    182     case PJMEDIA_AUD_DEV_CAP_EXT_FORMAT: 
    183         FIELD_INFO(ext_fmt); 
    184         break; 
    185     case PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY: 
    186         FIELD_INFO(input_latency_ms); 
    187         break; 
    188     case PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY: 
    189         FIELD_INFO(output_latency_ms); 
    190         break; 
    191     case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING: 
    192         FIELD_INFO(input_vol); 
    193         break; 
    194     case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING: 
    195         FIELD_INFO(output_vol); 
    196         break; 
    197     case PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE: 
    198         FIELD_INFO(input_route); 
    199         break; 
    200     case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE: 
    201         FIELD_INFO(output_route); 
    202         break; 
    203     case PJMEDIA_AUD_DEV_CAP_EC: 
    204         FIELD_INFO(ec_enabled); 
    205         break; 
    206     case PJMEDIA_AUD_DEV_CAP_EC_TAIL: 
    207         FIELD_INFO(ec_tail_ms); 
    208         break; 
    209     /* vad is no longer in "fmt" in 2.0. 
    210     case PJMEDIA_AUD_DEV_CAP_VAD: 
    211         FIELD_INFO(ext_fmt.vad); 
    212         break; 
    213     */ 
    214     case PJMEDIA_AUD_DEV_CAP_CNG: 
    215         FIELD_INFO(cng_enabled); 
    216         break; 
    217     case PJMEDIA_AUD_DEV_CAP_PLC: 
    218         FIELD_INFO(plc_enabled); 
    219         break; 
    220     default: 
    221         return PJMEDIA_EAUD_INVCAP; 
    222     } 
    223  
    224 #undef FIELD_INFO 
    225  
    226     return PJ_SUCCESS; 
    227 } 
    228  
    229 /* API: set cap value to param */ 
    230 PJ_DEF(pj_status_t) pjmedia_aud_param_set_cap( pjmedia_aud_param *param, 
    231                                                pjmedia_aud_dev_cap cap, 
    232                                                const void *pval) 
    233 { 
    234     void *cap_ptr; 
    235     unsigned cap_size; 
    236     pj_status_t status; 
    237  
    238     status = get_cap_pointer(param, cap, &cap_ptr, &cap_size); 
    239     if (status != PJ_SUCCESS) 
    240         return status; 
    241  
    242     pj_memcpy(cap_ptr, pval, cap_size); 
    243     param->flags |= cap; 
    244  
    245     return PJ_SUCCESS; 
    246 } 
    247  
    248 /* API: get cap value from param */ 
    249 PJ_DEF(pj_status_t) pjmedia_aud_param_get_cap( const pjmedia_aud_param *param, 
    250                                                pjmedia_aud_dev_cap cap, 
    251                                                void *pval) 
    252 { 
    253     void *cap_ptr; 
    254     unsigned cap_size; 
    255     pj_status_t status; 
    256  
    257     status = get_cap_pointer(param, cap, &cap_ptr, &cap_size); 
    258     if (status != PJ_SUCCESS) 
    259         return status; 
    260  
    261     if ((param->flags & cap) == 0) { 
    262         pj_bzero(cap_ptr, cap_size); 
    263         return PJMEDIA_EAUD_INVCAP; 
    264     } 
    265  
    266     pj_memcpy(pval, cap_ptr, cap_size); 
    267     return PJ_SUCCESS; 
    268 } 
    269  
    270 /* Internal: init driver */ 
    271 static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh) 
    272 { 
    273     struct driver *drv = &aud_subsys.drv[drv_idx]; 
    274     pjmedia_aud_dev_factory *f; 
    275     unsigned i, dev_cnt; 
    276     pj_status_t status; 
    277  
    278     if (!refresh && drv->create) { 
    279         /* Create the factory */ 
    280         f = (*drv->create)(aud_subsys.pf); 
    281         if (!f) 
    282             return PJ_EUNKNOWN; 
    283  
    284         /* Call factory->init() */ 
    285         status = f->op->init(f); 
    286         if (status != PJ_SUCCESS) { 
    287             f->op->destroy(f); 
    288             return status; 
    289         } 
    290     } else { 
    291         f = drv->f; 
    292     } 
    293  
    294     if (!f) 
    295         return PJ_EUNKNOWN; 
    296  
    297     /* Get number of devices */ 
    298     dev_cnt = f->op->get_dev_count(f); 
    299     if (dev_cnt + aud_subsys.dev_cnt > MAX_DEVS) { 
    300         PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because" 
    301                               " there are too many devices", 
    302                               aud_subsys.dev_cnt + dev_cnt - MAX_DEVS)); 
    303         dev_cnt = MAX_DEVS - aud_subsys.dev_cnt; 
    304     } 
    305  
    306     /* enabling this will cause pjsua-lib initialization to fail when there 
    307      * is no sound device installed in the system, even when pjsua has been 
    308      * run with --null-audio 
    309      * 
    310     if (dev_cnt == 0) { 
    311         f->op->destroy(f); 
    312         return PJMEDIA_EAUD_NODEV; 
    313     } 
    314     */ 
    315  
    316     /* Fill in default devices */ 
    317     drv->play_dev_idx = drv->rec_dev_idx = 
    318                         drv->dev_idx = PJMEDIA_AUD_INVALID_DEV; 
    319     for (i=0; i<dev_cnt; ++i) { 
    320         pjmedia_aud_dev_info info; 
    321  
    322         status = f->op->get_dev_info(f, i, &info); 
    323         if (status != PJ_SUCCESS) { 
    324             f->op->destroy(f); 
    325             return status; 
    326         } 
    327  
    328         if (drv->name[0]=='\0') { 
    329             /* Set driver name */ 
    330             pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name)); 
    331             drv->name[sizeof(drv->name)-1] = '\0'; 
    332         } 
    333  
    334         if (drv->play_dev_idx < 0 && info.output_count) { 
    335             /* Set default playback device */ 
    336             drv->play_dev_idx = i; 
    337         } 
    338         if (drv->rec_dev_idx < 0 && info.input_count) { 
    339             /* Set default capture device */ 
    340             drv->rec_dev_idx = i; 
    341         } 
    342         if (drv->dev_idx < 0 && info.input_count && 
    343             info.output_count) 
    344         { 
    345             /* Set default capture and playback device */ 
    346             drv->dev_idx = i; 
    347         } 
    348  
    349         if (drv->play_dev_idx >= 0 && drv->rec_dev_idx >= 0 &&  
    350             drv->dev_idx >= 0)  
    351         { 
    352             /* Done. */ 
    353             break; 
    354         } 
    355     } 
    356  
    357     /* Register the factory */ 
    358     drv->f = f; 
    359     drv->f->sys.drv_idx = drv_idx; 
    360     drv->start_idx = aud_subsys.dev_cnt; 
    361     drv->dev_cnt = dev_cnt; 
    362  
    363     /* Register devices to global list */ 
    364     for (i=0; i<dev_cnt; ++i) { 
    365         aud_subsys.dev_list[aud_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i); 
    366     } 
    367  
    368     return PJ_SUCCESS; 
    369 } 
    370  
    371 /* Internal: deinit driver */ 
    372 static void deinit_driver(unsigned drv_idx) 
    373 { 
    374     struct driver *drv = &aud_subsys.drv[drv_idx]; 
    375  
    376     if (drv->f) { 
    377         drv->f->op->destroy(drv->f); 
    378         drv->f = NULL; 
    379     } 
    380  
    381     pj_bzero(drv, sizeof(*drv)); 
    382     drv->play_dev_idx = drv->rec_dev_idx =  
    383                         drv->dev_idx = PJMEDIA_AUD_INVALID_DEV; 
    384 } 
    38575 
    38676/* API: Initialize the audio subsystem. */ 
     
    38979    unsigned i; 
    39080    pj_status_t status; 
     81    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys(); 
    39182 
    39283    /* Allow init() to be called multiple times as long as there is matching 
    39384     * number of shutdown(). 
    39485     */ 
    395     if (aud_subsys.init_count++ != 0) { 
     86    if (aud_subsys->init_count++ != 0) { 
    39687        return PJ_SUCCESS; 
    39788    } 
     
    40495 
    40596    /* Init */ 
    406     aud_subsys.pf = pf; 
    407     aud_subsys.drv_cnt = 0; 
    408     aud_subsys.dev_cnt = 0; 
     97    aud_subsys->pf = pf; 
     98    aud_subsys->drv_cnt = 0; 
     99    aud_subsys->dev_cnt = 0; 
    409100 
    410101    /* Register creation functions */ 
    411102#if PJMEDIA_AUDIO_DEV_HAS_OPENSL 
    412     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_opensl_factory; 
     103    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_opensl_factory; 
    413104#endif 
    414105#if PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI 
    415     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_android_factory; 
     106    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_android_factory; 
    416107#endif 
    417108#if PJMEDIA_AUDIO_DEV_HAS_BB10 
    418     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_bb10_factory; 
     109    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_bb10_factory; 
    419110#endif 
    420111#if PJMEDIA_AUDIO_DEV_HAS_ALSA 
    421     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_alsa_factory; 
     112    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_alsa_factory; 
    422113#endif 
    423114#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO 
    424     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_coreaudio_factory; 
     115    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_coreaudio_factory; 
    425116#endif 
    426117#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 
    427     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_pa_factory; 
     118    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_pa_factory; 
    428119#endif 
    429120#if PJMEDIA_AUDIO_DEV_HAS_WMME 
    430     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_wmme_factory; 
     121    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_wmme_factory; 
    431122#endif 
    432123#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD 
    433     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_bdimad_factory; 
     124    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_bdimad_factory; 
    434125#endif 
    435126#if PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 
    436     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_symb_vas_factory; 
     127    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_symb_vas_factory; 
    437128#endif 
    438129#if PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 
    439     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_aps_factory; 
     130    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_aps_factory; 
    440131#endif 
    441132#if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 
    442     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_symb_mda_factory; 
     133    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_symb_mda_factory; 
    443134#endif 
    444135#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO 
    445     aud_subsys.drv[aud_subsys.drv_cnt++].create = &pjmedia_null_audio_factory; 
     136    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_null_audio_factory; 
    446137#endif 
    447138 
    448139    /* Initialize each factory and build the device ID list */ 
    449     for (i=0; i<aud_subsys.drv_cnt; ++i) { 
    450         status = init_driver(i, PJ_FALSE); 
     140    for (i=0; i<aud_subsys->drv_cnt; ++i) { 
     141        status = pjmedia_aud_driver_init(i, PJ_FALSE); 
    451142        if (status != PJ_SUCCESS) { 
    452             deinit_driver(i); 
     143            pjmedia_aud_driver_deinit(i); 
    453144            continue; 
    454145        } 
    455146    } 
    456147 
    457     return aud_subsys.dev_cnt ? PJ_SUCCESS : status; 
     148    return aud_subsys->dev_cnt ? PJ_SUCCESS : status; 
    458149} 
    459150 
     
    463154{ 
    464155    pj_status_t status; 
    465  
    466     if (aud_subsys.init_count == 0) 
     156    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys(); 
     157 
     158    if (aud_subsys->init_count == 0) 
    467159        return PJMEDIA_EAUD_INIT; 
    468160 
    469     aud_subsys.drv[aud_subsys.drv_cnt].create = adf; 
    470     status = init_driver(aud_subsys.drv_cnt, PJ_FALSE); 
     161    aud_subsys->drv[aud_subsys->drv_cnt].create = adf; 
     162    status = pjmedia_aud_driver_init(aud_subsys->drv_cnt, PJ_FALSE); 
    471163    if (status == PJ_SUCCESS) { 
    472         aud_subsys.drv_cnt++; 
     164        aud_subsys->drv_cnt++; 
    473165    } else { 
    474         deinit_driver(aud_subsys.drv_cnt); 
     166        pjmedia_aud_driver_deinit(aud_subsys->drv_cnt); 
    475167    } 
    476168 
     
    483175{ 
    484176    unsigned i, j; 
    485  
    486     if (aud_subsys.init_count == 0) 
     177    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys(); 
     178 
     179    if (aud_subsys->init_count == 0) 
    487180        return PJMEDIA_EAUD_INIT; 
    488181 
    489     for (i=0; i<aud_subsys.drv_cnt; ++i) { 
    490         struct driver *drv = &aud_subsys.drv[i]; 
     182    for (i=0; i<aud_subsys->drv_cnt; ++i) { 
     183        pjmedia_aud_driver *drv = &aud_subsys->drv[i]; 
    491184 
    492185        if (drv->create == adf) { 
    493186            for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++) 
    494187            { 
    495                 aud_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_AUD_INVALID_DEV; 
     188                aud_subsys->dev_list[j] = (pj_uint32_t)PJMEDIA_AUD_INVALID_DEV; 
    496189            } 
    497190 
    498             deinit_driver(i); 
     191            pjmedia_aud_driver_deinit(i); 
    499192            return PJ_SUCCESS; 
    500193        } 
     
    507200PJ_DEF(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void) 
    508201{ 
    509     return aud_subsys.pf; 
     202    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys(); 
     203    return aud_subsys->pf; 
    510204} 
    511205 
     
    514208{ 
    515209    unsigned i; 
     210    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys(); 
    516211 
    517212    /* Allow shutdown() to be called multiple times as long as there is matching 
    518213     * number of init(). 
    519214     */ 
    520     if (aud_subsys.init_count == 0) { 
     215    if (aud_subsys->init_count == 0) { 
    521216        return PJ_SUCCESS; 
    522217    } 
    523     --aud_subsys.init_count; 
    524  
    525     if (aud_subsys.init_count == 0) { 
    526         for (i=0; i<aud_subsys.drv_cnt; ++i) { 
    527             deinit_driver(i); 
     218    --aud_subsys->init_count; 
     219 
     220    if (aud_subsys->init_count == 0) { 
     221        for (i=0; i<aud_subsys->drv_cnt; ++i) { 
     222            pjmedia_aud_driver_deinit(i); 
    528223        } 
    529224 
    530         aud_subsys.pf = NULL; 
     225        aud_subsys->pf = NULL; 
    531226    } 
    532227    return PJ_SUCCESS; 
    533228} 
    534  
    535 /* API: Refresh the list of sound devices installed in the system. */ 
    536 PJ_DEF(pj_status_t) pjmedia_aud_dev_refresh(void) 
    537 { 
    538     unsigned i; 
    539      
    540     aud_subsys.dev_cnt = 0; 
    541     for (i=0; i<aud_subsys.drv_cnt; ++i) { 
    542         struct driver *drv = &aud_subsys.drv[i]; 
    543          
    544         if (drv->f && drv->f->op->refresh) { 
    545             pj_status_t status = drv->f->op->refresh(drv->f); 
    546             if (status != PJ_SUCCESS) { 
    547                 PJ_PERROR(4, (THIS_FILE, status, "Unable to refresh device " 
    548                                                  "list for %s", drv->name)); 
    549             } 
    550         } 
    551         init_driver(i, PJ_TRUE); 
    552     } 
    553     return PJ_SUCCESS; 
    554 } 
    555  
    556 /* API: Get the number of sound devices installed in the system. */ 
    557 PJ_DEF(unsigned) pjmedia_aud_dev_count(void) 
    558 { 
    559     return aud_subsys.dev_cnt; 
    560 } 
    561  
    562 /* Internal: convert local index to global device index */ 
    563 static pj_status_t make_global_index(unsigned drv_idx,  
    564                                      pjmedia_aud_dev_index *id) 
    565 { 
    566     if (*id < 0) { 
    567         return PJ_SUCCESS; 
    568     } 
    569  
    570     /* Check that factory still exists */ 
    571     PJ_ASSERT_RETURN(aud_subsys.drv[drv_idx].f, PJ_EBUG); 
    572  
    573     /* Check that device index is valid */ 
    574     PJ_ASSERT_RETURN(*id>=0 && *id<(int)aud_subsys.drv[drv_idx].dev_cnt,  
    575                      PJ_EBUG); 
    576  
    577     *id += aud_subsys.drv[drv_idx].start_idx; 
    578     return PJ_SUCCESS; 
    579 } 
    580  
    581 /* Internal: lookup device id */ 
    582 static pj_status_t lookup_dev(pjmedia_aud_dev_index id, 
    583                               pjmedia_aud_dev_factory **p_f, 
    584                               unsigned *p_local_index) 
    585 { 
    586     int f_id, index; 
    587  
    588     if (id < 0) { 
    589         unsigned i; 
    590  
    591         if (id == PJMEDIA_AUD_INVALID_DEV) 
    592             return PJMEDIA_EAUD_INVDEV; 
    593  
    594         for (i=0; i<aud_subsys.drv_cnt; ++i) { 
    595             struct driver *drv = &aud_subsys.drv[i]; 
    596             if (drv->dev_idx >= 0) { 
    597                 id = drv->dev_idx; 
    598                 make_global_index(i, &id); 
    599                 break; 
    600             } else if (id==PJMEDIA_AUD_DEFAULT_CAPTURE_DEV &&  
    601                 drv->rec_dev_idx >= 0)  
    602             { 
    603                 id = drv->rec_dev_idx; 
    604                 make_global_index(i, &id); 
    605                 break; 
    606             } else if (id==PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV &&  
    607                 drv->play_dev_idx >= 0)  
    608             { 
    609                 id = drv->play_dev_idx; 
    610                 make_global_index(i, &id); 
    611                 break; 
    612             } 
    613         } 
    614  
    615         if (id < 0) { 
    616             return PJMEDIA_EAUD_NODEFDEV; 
    617         } 
    618     } 
    619  
    620     f_id = GET_FID(aud_subsys.dev_list[id]); 
    621     index = GET_INDEX(aud_subsys.dev_list[id]); 
    622  
    623     if (f_id < 0 || f_id >= (int)aud_subsys.drv_cnt) 
    624         return PJMEDIA_EAUD_INVDEV; 
    625  
    626     if (index < 0 || index >= (int)aud_subsys.drv[f_id].dev_cnt) 
    627         return PJMEDIA_EAUD_INVDEV; 
    628  
    629     *p_f = aud_subsys.drv[f_id].f; 
    630     *p_local_index = (unsigned)index; 
    631  
    632     return PJ_SUCCESS; 
    633  
    634 } 
    635  
    636 /* API: Get device information. */ 
    637 PJ_DEF(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id, 
    638                                              pjmedia_aud_dev_info *info) 
    639 { 
    640     pjmedia_aud_dev_factory *f; 
    641     unsigned index; 
    642     pj_status_t status; 
    643  
    644     PJ_ASSERT_RETURN(info && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL); 
    645     PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 
    646  
    647     status = lookup_dev(id, &f, &index); 
    648     if (status != PJ_SUCCESS) 
    649         return status; 
    650  
    651     return f->op->get_dev_info(f, index, info); 
    652 } 
    653  
    654 /* API: find device */ 
    655 PJ_DEF(pj_status_t) pjmedia_aud_dev_lookup( const char *drv_name, 
    656                                             const char *dev_name, 
    657                                             pjmedia_aud_dev_index *id) 
    658 { 
    659     pjmedia_aud_dev_factory *f = NULL; 
    660     unsigned drv_idx, dev_idx; 
    661  
    662     PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL); 
    663     PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 
    664  
    665     for (drv_idx=0; drv_idx<aud_subsys.drv_cnt; ++drv_idx) { 
    666         if (!pj_ansi_stricmp(drv_name, aud_subsys.drv[drv_idx].name)) { 
    667             f = aud_subsys.drv[drv_idx].f; 
    668             break; 
    669         } 
    670     } 
    671  
    672     if (!f) 
    673         return PJ_ENOTFOUND; 
    674  
    675     for (dev_idx=0; dev_idx<aud_subsys.drv[drv_idx].dev_cnt; ++dev_idx) { 
    676         pjmedia_aud_dev_info info; 
    677         pj_status_t status; 
    678  
    679         status = f->op->get_dev_info(f, dev_idx, &info); 
    680         if (status != PJ_SUCCESS) 
    681             return status; 
    682  
    683         if (!pj_ansi_stricmp(dev_name, info.name)) 
    684             break; 
    685     } 
    686  
    687     if (dev_idx==aud_subsys.drv[drv_idx].dev_cnt) 
    688         return PJ_ENOTFOUND; 
    689  
    690     *id = dev_idx; 
    691     make_global_index(drv_idx, id); 
    692  
    693     return PJ_SUCCESS; 
    694 } 
    695  
    696 /* API: Initialize the audio device parameters with default values for the 
    697  * specified device. 
    698  */ 
    699 PJ_DEF(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id, 
    700                                                   pjmedia_aud_param *param) 
    701 { 
    702     pjmedia_aud_dev_factory *f; 
    703     unsigned index; 
    704     pj_status_t status; 
    705  
    706     PJ_ASSERT_RETURN(param && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL); 
    707     PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 
    708  
    709     status = lookup_dev(id, &f, &index); 
    710     if (status != PJ_SUCCESS) 
    711         return status; 
    712  
    713     status = f->op->default_param(f, index, param); 
    714     if (status != PJ_SUCCESS) 
    715         return status; 
    716  
    717     /* Normalize device IDs */ 
    718     make_global_index(f->sys.drv_idx, &param->rec_id); 
    719     make_global_index(f->sys.drv_idx, &param->play_id); 
    720  
    721     return PJ_SUCCESS; 
    722 } 
    723  
    724 /* API: Open audio stream object using the specified parameters. */ 
    725 PJ_DEF(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *prm, 
    726                                               pjmedia_aud_rec_cb rec_cb, 
    727                                               pjmedia_aud_play_cb play_cb, 
    728                                               void *user_data, 
    729                                               pjmedia_aud_stream **p_aud_strm) 
    730 { 
    731     pjmedia_aud_dev_factory *rec_f=NULL, *play_f=NULL, *f=NULL; 
    732     pjmedia_aud_param param; 
    733     pj_status_t status; 
    734  
    735     PJ_ASSERT_RETURN(prm && prm->dir && p_aud_strm, PJ_EINVAL); 
    736     PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 
    737     PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE || 
    738                      prm->dir==PJMEDIA_DIR_PLAYBACK || 
    739                      prm->dir==PJMEDIA_DIR_CAPTURE_PLAYBACK, 
    740                      PJ_EINVAL); 
    741  
    742     /* Must make copy of param because we're changing device ID */ 
    743     pj_memcpy(&param, prm, sizeof(param)); 
    744  
    745     /* Normalize rec_id */ 
    746     if (param.dir & PJMEDIA_DIR_CAPTURE) { 
    747         unsigned index; 
    748  
    749         if (param.rec_id < 0) 
    750             param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV; 
    751  
    752         status = lookup_dev(param.rec_id, &rec_f, &index); 
    753         if (status != PJ_SUCCESS) 
    754             return status; 
    755  
    756         param.rec_id = index; 
    757         f = rec_f; 
    758     } 
    759  
    760     /* Normalize play_id */ 
    761     if (param.dir & PJMEDIA_DIR_PLAYBACK) { 
    762         unsigned index; 
    763  
    764         if (param.play_id < 0) 
    765             param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV; 
    766  
    767         status = lookup_dev(param.play_id, &play_f, &index); 
    768         if (status != PJ_SUCCESS) 
    769             return status; 
    770  
    771         param.play_id = index; 
    772         f = play_f; 
    773     } 
    774  
    775     PJ_ASSERT_RETURN(f != NULL, PJ_EBUG); 
    776  
    777     /* For now, rec_id and play_id must belong to the same factory */ 
    778     PJ_ASSERT_RETURN((param.dir != PJMEDIA_DIR_CAPTURE_PLAYBACK) ||  
    779                      (rec_f == play_f), 
    780                      PJMEDIA_EAUD_INVDEV); 
    781  
    782     /* Create the stream */ 
    783     status = f->op->create_stream(f, &param, rec_cb, play_cb, 
    784                                   user_data, p_aud_strm); 
    785     if (status != PJ_SUCCESS) 
    786         return status; 
    787  
    788     /* Assign factory id to the stream */ 
    789     (*p_aud_strm)->sys.drv_idx = f->sys.drv_idx; 
    790     return PJ_SUCCESS; 
    791 } 
    792  
    793 /* API: Get the running parameters for the specified audio stream. */ 
    794 PJ_DEF(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm, 
    795                                                  pjmedia_aud_param *param) 
    796 { 
    797     pj_status_t status; 
    798  
    799     PJ_ASSERT_RETURN(strm && param, PJ_EINVAL); 
    800     PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 
    801  
    802     status = strm->op->get_param(strm, param); 
    803     if (status != PJ_SUCCESS) 
    804         return status; 
    805  
    806     /* Normalize device id's */ 
    807     make_global_index(strm->sys.drv_idx, &param->rec_id); 
    808     make_global_index(strm->sys.drv_idx, &param->play_id); 
    809  
    810     return PJ_SUCCESS; 
    811 } 
    812  
    813 /* API: Get the value of a specific capability of the audio stream. */ 
    814 PJ_DEF(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm, 
    815                                                pjmedia_aud_dev_cap cap, 
    816                                                void *value) 
    817 { 
    818     return strm->op->get_cap(strm, cap, value); 
    819 } 
    820  
    821 /* API: Set the value of a specific capability of the audio stream. */ 
    822 PJ_DEF(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm, 
    823                                                pjmedia_aud_dev_cap cap, 
    824                                                const void *value) 
    825 { 
    826     return strm->op->set_cap(strm, cap, value); 
    827 } 
    828  
    829 /* API: Start the stream. */ 
    830 PJ_DEF(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm) 
    831 { 
    832     return strm->op->start(strm); 
    833 } 
    834  
    835 /* API: Stop the stream. */ 
    836 PJ_DEF(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm) 
    837 { 
    838     return strm->op->stop(strm); 
    839 } 
    840  
    841 /* API: Destroy the stream. */ 
    842 PJ_DEF(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm) 
    843 { 
    844     return strm->op->destroy(strm); 
    845 } 
    846  
    847  
  • pjproject/trunk/pjmedia/src/pjmedia-videodev/videodev.c

    r5125 r5255  
    1919#include <pjmedia-videodev/videodev_imp.h> 
    2020#include <pj/assert.h> 
    21 #include <pj/errno.h> 
    22 #include <pj/log.h> 
    23 #include <pj/pool.h> 
    24 #include <pj/string.h> 
    2521 
    2622 
     
    2925 
    3026#define THIS_FILE   "videodev.c" 
    31  
    32 #define DEFINE_CAP(name, info)  {name, info} 
    33  
    34 /* Capability names */ 
    35 static struct cap_info 
    36 { 
    37     const char *name; 
    38     const char *info; 
    39 } cap_infos[] =  
    40 { 
    41     DEFINE_CAP("format",        "Video format"), 
    42     DEFINE_CAP("scale",         "Input dimension"), 
    43     DEFINE_CAP("window",        "Window handle"), 
    44     DEFINE_CAP("resize",        "Renderer resize"), 
    45     DEFINE_CAP("position",      "Renderer position"), 
    46     DEFINE_CAP("hide",          "Renderer hide"), 
    47     DEFINE_CAP("preview",       "Input preview"), 
    48     DEFINE_CAP("orientation",   "Video orientation"), 
    49     DEFINE_CAP("switch",        "Switch device"), 
    50     DEFINE_CAP("wndflags",      "Window flags") 
    51 }; 
    52  
    53  
    54 /* 
    55  * The device index seen by application and driver is different.  
    56  * 
    57  * At application level, device index is index to global list of device. 
    58  * At driver level, device index is index to device list on that particular 
    59  * factory only. 
    60  */ 
    61 #define MAKE_DEV_ID(f_id, index)   (((f_id & 0xFFFF) << 16) | (index & 0xFFFF)) 
    62 #define GET_INDEX(dev_id)          ((dev_id) & 0xFFFF) 
    63 #define GET_FID(dev_id)            ((dev_id) >> 16) 
    64 #define DEFAULT_DEV_ID              0 
    6527 
    6628 
     
    11072 
    11173 
    112 /* driver structure */ 
    113 struct driver 
    114 { 
    115     /* Creation function */ 
    116     pjmedia_vid_dev_factory_create_func_ptr create; 
    117     /* Factory instance */ 
    118     pjmedia_vid_dev_factory *f; 
    119     char                     name[32];      /* Driver name                  */ 
    120     unsigned                 dev_cnt;       /* Number of devices            */ 
    121     unsigned                 start_idx;     /* Start index in global list   */ 
    122     int                      cap_dev_idx;   /* Default capture device.      */ 
    123     int                      rend_dev_idx;  /* Default render device        */ 
    124 }; 
    125  
    126 /* The video device subsystem */ 
    127 static struct vid_subsys 
    128 { 
    129     unsigned         init_count;        /* How many times init() is called  */ 
    130     pj_pool_factory *pf;                /* The pool factory.                */ 
    131  
    132     unsigned         drv_cnt;           /* Number of drivers.               */ 
    133     struct driver    drv[MAX_DRIVERS];  /* Array of drivers.                */ 
    134  
    135     unsigned         dev_cnt;           /* Total number of devices.         */ 
    136     pj_uint32_t      dev_list[MAX_DEVS];/* Array of device IDs.             */ 
    137  
    138 } vid_subsys; 
    139  
    140 /* API: get capability name/info */ 
    141 PJ_DEF(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap, 
    142                                              const char **p_desc) 
    143 { 
    144     const char *desc; 
    145     unsigned i; 
    146  
    147     if (p_desc==NULL) p_desc = &desc; 
    148  
    149     for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) { 
    150         if ((1 << i)==cap) 
    151             break; 
    152     } 
    153  
    154     if (i==PJ_ARRAY_SIZE(cap_infos)) { 
    155         *p_desc = "??"; 
    156         return "??"; 
    157     } 
    158  
    159     *p_desc = cap_infos[i].info; 
    160     return cap_infos[i].name; 
    161 } 
    162  
    163 static pj_status_t get_cap_pointer(const pjmedia_vid_dev_param *param, 
    164                                    pjmedia_vid_dev_cap cap, 
    165                                    void **ptr, 
    166                                    unsigned *size) 
    167 { 
    168 #define FIELD_INFO(name)    *ptr = (void*)&param->name; \ 
    169                             *size = sizeof(param->name) 
    170  
    171     switch (cap) { 
    172     case PJMEDIA_VID_DEV_CAP_FORMAT: 
    173         FIELD_INFO(fmt); 
    174         break; 
    175     case PJMEDIA_VID_DEV_CAP_INPUT_SCALE: 
    176         FIELD_INFO(disp_size); 
    177         break; 
    178     case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW: 
    179         FIELD_INFO(window); 
    180         break; 
    181     case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE: 
    182         FIELD_INFO(disp_size); 
    183         break; 
    184     case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION: 
    185         FIELD_INFO(window_pos); 
    186         break; 
    187     case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE: 
    188         FIELD_INFO(window_hide); 
    189         break; 
    190     case PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW: 
    191         FIELD_INFO(native_preview); 
    192         break; 
    193     case PJMEDIA_VID_DEV_CAP_ORIENTATION: 
    194         FIELD_INFO(orient); 
    195         break; 
    196     /* The PJMEDIA_VID_DEV_CAP_SWITCH does not have an entry in the 
    197      * param (it doesn't make sense to open a stream and tell it 
    198      * to switch immediately). 
    199      */ 
    200     case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS: 
    201         FIELD_INFO(window_flags); 
    202         break; 
    203     default: 
    204         return PJMEDIA_EVID_INVCAP; 
    205     } 
    206  
    207 #undef FIELD_INFO 
    208  
    209     return PJ_SUCCESS; 
    210 } 
    211  
    212 /* API: set cap value to param */ 
    213 PJ_DEF(pj_status_t) 
    214 pjmedia_vid_dev_param_set_cap( pjmedia_vid_dev_param *param, 
    215                                pjmedia_vid_dev_cap cap, 
    216                                const void *pval) 
    217 { 
    218     void *cap_ptr; 
    219     unsigned cap_size; 
    220     pj_status_t status; 
    221  
    222     status = get_cap_pointer(param, cap, &cap_ptr, &cap_size); 
    223     if (status != PJ_SUCCESS) 
    224         return status; 
    225  
    226     pj_memcpy(cap_ptr, pval, cap_size); 
    227     param->flags |= cap; 
    228  
    229     return PJ_SUCCESS; 
    230 } 
    231  
    232 /* API: get cap value from param */ 
    233 PJ_DEF(pj_status_t) 
    234 pjmedia_vid_dev_param_get_cap( const pjmedia_vid_dev_param *param, 
    235                                pjmedia_vid_dev_cap cap, 
    236                                void *pval) 
    237 { 
    238     void *cap_ptr; 
    239     unsigned cap_size; 
    240     pj_status_t status; 
    241  
    242     status = get_cap_pointer(param, cap, &cap_ptr, &cap_size); 
    243     if (status != PJ_SUCCESS) 
    244         return status; 
    245  
    246     if ((param->flags & cap) == 0) { 
    247         pj_bzero(cap_ptr, cap_size); 
    248         return PJMEDIA_EVID_INVCAP; 
    249     } 
    250  
    251     pj_memcpy(pval, cap_ptr, cap_size); 
    252     return PJ_SUCCESS; 
    253 } 
    254  
    255 /* Internal: init driver */ 
    256 static pj_status_t init_driver(unsigned drv_idx, pj_bool_t refresh) 
    257 { 
    258     struct driver *drv = &vid_subsys.drv[drv_idx]; 
    259     pjmedia_vid_dev_factory *f; 
    260     unsigned i, dev_cnt; 
    261     pj_status_t status; 
    262  
    263     if (!refresh) { 
    264         /* Create the factory */ 
    265         f = (*drv->create)(vid_subsys.pf); 
    266         if (!f) 
    267             return PJ_EUNKNOWN; 
    268  
    269         /* Call factory->init() */ 
    270         status = f->op->init(f); 
    271         if (status != PJ_SUCCESS) { 
    272             f->op->destroy(f); 
    273             return status; 
    274         } 
    275     } else { 
    276         f = drv->f; 
    277     } 
    278  
    279     /* Get number of devices */ 
    280     dev_cnt = f->op->get_dev_count(f); 
    281     if (dev_cnt + vid_subsys.dev_cnt > MAX_DEVS) { 
    282         PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because" 
    283                               " there are too many devices", 
    284                               vid_subsys.dev_cnt + dev_cnt - MAX_DEVS)); 
    285         dev_cnt = MAX_DEVS - vid_subsys.dev_cnt; 
    286     } 
    287  
    288     /* enabling this will cause pjsua-lib initialization to fail when there 
    289      * is no video device installed in the system, even when pjsua has been 
    290      * run with --null-video 
    291      * 
    292     if (dev_cnt == 0) { 
    293         f->op->destroy(f); 
    294         return PJMEDIA_EVID_NODEV; 
    295     } 
    296     */ 
    297  
    298     /* Fill in default devices */ 
    299     drv->rend_dev_idx = drv->cap_dev_idx = -1; 
    300     for (i=0; i<dev_cnt; ++i) { 
    301         pjmedia_vid_dev_info info; 
    302  
    303         status = f->op->get_dev_info(f, i, &info); 
    304         if (status != PJ_SUCCESS) { 
    305             f->op->destroy(f); 
    306             return status; 
    307         } 
    308  
    309         if (drv->name[0]=='\0') { 
    310             /* Set driver name */ 
    311             pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name)); 
    312             drv->name[sizeof(drv->name)-1] = '\0'; 
    313         } 
    314  
    315         if (drv->rend_dev_idx < 0 && (info.dir & PJMEDIA_DIR_RENDER)) { 
    316             /* Set default render device */ 
    317             drv->rend_dev_idx = i; 
    318         } 
    319         if (drv->cap_dev_idx < 0 && (info.dir & PJMEDIA_DIR_CAPTURE)) { 
    320             /* Set default capture device */ 
    321             drv->cap_dev_idx = i; 
    322         } 
    323  
    324         if (drv->rend_dev_idx >= 0 && drv->cap_dev_idx >= 0) { 
    325             /* Done. */ 
    326             break; 
    327         } 
    328     } 
    329  
    330     /* Register the factory */ 
    331     drv->f = f; 
    332     drv->f->sys.drv_idx = drv_idx; 
    333     drv->start_idx = vid_subsys.dev_cnt; 
    334     drv->dev_cnt = dev_cnt; 
    335  
    336     /* Register devices to global list */ 
    337     for (i=0; i<dev_cnt; ++i) { 
    338         vid_subsys.dev_list[vid_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i); 
    339     } 
    340  
    341     return PJ_SUCCESS; 
    342 } 
    343  
    344 /* Internal: deinit driver */ 
    345 static void deinit_driver(unsigned drv_idx) 
    346 { 
    347     struct driver *drv = &vid_subsys.drv[drv_idx]; 
    348  
    349     if (drv->f) { 
    350         drv->f->op->destroy(drv->f); 
    351         drv->f = NULL; 
    352     } 
    353  
    354     drv->dev_cnt = 0; 
    355     drv->rend_dev_idx = drv->cap_dev_idx = -1; 
    356 } 
    357  
    35874/* API: Initialize the video device subsystem. */ 
    35975PJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf) 
     
    36177    unsigned i; 
    36278    pj_status_t status = PJ_SUCCESS; 
     79    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys(); 
    36380 
    36481    /* Allow init() to be called multiple times as long as there is matching 
    36582     * number of shutdown(). 
    36683     */ 
    367     if (vid_subsys.init_count++ != 0) { 
     84    if (vid_subsys->init_count++ != 0) { 
    36885        return PJ_SUCCESS; 
    36986    } 
     
    37592 
    37693    /* Init */ 
    377     vid_subsys.pf = pf; 
    378     vid_subsys.drv_cnt = 0; 
    379     vid_subsys.dev_cnt = 0; 
     94    vid_subsys->pf = pf; 
     95    vid_subsys->drv_cnt = 0; 
     96    vid_subsys->dev_cnt = 0; 
    38097 
    38198    /* Register creation functions */ 
    38299#if PJMEDIA_VIDEO_DEV_HAS_V4L2 
    383     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_v4l2_factory; 
     100    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_v4l2_factory; 
    384101#endif 
    385102#if PJMEDIA_VIDEO_DEV_HAS_QT 
    386     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_qt_factory; 
     103    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_qt_factory; 
    387104#endif 
    388105#if PJMEDIA_VIDEO_DEV_HAS_OPENGL 
    389     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_opengl_factory; 
     106    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_opengl_factory; 
    390107#endif 
    391108#if PJMEDIA_VIDEO_DEV_HAS_IOS 
    392     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ios_factory; 
     109    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_ios_factory; 
    393110#endif 
    394111#if PJMEDIA_VIDEO_DEV_HAS_DSHOW 
    395     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_dshow_factory; 
     112    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_dshow_factory; 
    396113#endif 
    397114#if PJMEDIA_VIDEO_DEV_HAS_FFMPEG 
    398     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_ffmpeg_factory; 
     115    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_ffmpeg_factory; 
    399116#endif 
    400117#if PJMEDIA_VIDEO_DEV_HAS_SDL 
    401     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_sdl_factory; 
     118    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_sdl_factory; 
    402119#endif 
    403120#if PJMEDIA_VIDEO_DEV_HAS_ANDROID 
    404     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_and_factory; 
     121    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_and_factory; 
    405122#endif 
    406123#if PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC 
     
    408125     * a real capturer, if any. 
    409126     */ 
    410     vid_subsys.drv[vid_subsys.drv_cnt++].create = &pjmedia_cbar_factory; 
     127    vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_cbar_factory; 
    411128#endif 
    412129 
    413130    /* Initialize each factory and build the device ID list */ 
    414     for (i=0; i<vid_subsys.drv_cnt; ++i) { 
    415         status = init_driver(i, PJ_FALSE); 
     131    for (i=0; i<vid_subsys->drv_cnt; ++i) { 
     132        status = pjmedia_vid_driver_init(i, PJ_FALSE); 
    416133        if (status != PJ_SUCCESS) { 
    417             deinit_driver(i); 
     134            pjmedia_vid_driver_deinit(i); 
    418135            continue; 
    419136        } 
    420137    } 
    421138 
    422     return vid_subsys.dev_cnt ? PJ_SUCCESS : status; 
     139    return vid_subsys->dev_cnt ? PJ_SUCCESS : status; 
    423140} 
    424141 
     
    430147    pj_bool_t refresh = PJ_FALSE; 
    431148    pj_status_t status; 
    432  
    433     if (vid_subsys.init_count == 0) 
     149    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys(); 
     150 
     151    if (vid_subsys->init_count == 0) 
    434152        return PJMEDIA_EVID_INIT; 
    435153 
    436     vid_subsys.drv[vid_subsys.drv_cnt].create = adf; 
    437     vid_subsys.drv[vid_subsys.drv_cnt].f = factory; 
     154    vid_subsys->drv[vid_subsys->drv_cnt].create = adf; 
     155    vid_subsys->drv[vid_subsys->drv_cnt].f = factory; 
    438156 
    439157    if (factory) { 
     
    447165    } 
    448166 
    449     status = init_driver(vid_subsys.drv_cnt, refresh); 
     167    status = pjmedia_vid_driver_init(vid_subsys->drv_cnt, refresh); 
    450168    if (status == PJ_SUCCESS) { 
    451         vid_subsys.drv_cnt++; 
     169        vid_subsys->drv_cnt++; 
    452170    } else { 
    453         deinit_driver(vid_subsys.drv_cnt); 
     171        pjmedia_vid_driver_deinit(vid_subsys->drv_cnt); 
    454172    } 
    455173 
     
    463181{ 
    464182    unsigned i, j; 
    465  
    466     if (vid_subsys.init_count == 0) 
     183    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys(); 
     184 
     185    if (vid_subsys->init_count == 0) 
    467186        return PJMEDIA_EVID_INIT; 
    468187 
    469     for (i=0; i<vid_subsys.drv_cnt; ++i) { 
    470         struct driver *drv = &vid_subsys.drv[i]; 
     188    for (i=0; i<vid_subsys->drv_cnt; ++i) { 
     189        pjmedia_vid_driver *drv = &vid_subsys->drv[i]; 
    471190 
    472191        if ((factory && drv->f==factory) || (adf && drv->create == adf)) { 
    473192            for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++) 
    474193            { 
    475                 vid_subsys.dev_list[j] = (pj_uint32_t)PJMEDIA_VID_INVALID_DEV; 
     194                vid_subsys->dev_list[j] = (pj_uint32_t)PJMEDIA_VID_INVALID_DEV; 
    476195            } 
    477196 
    478             deinit_driver(i); 
     197            pjmedia_vid_driver_deinit(i); 
    479198            pj_bzero(drv, sizeof(*drv)); 
    480199            return PJ_SUCCESS; 
     
    488207PJ_DEF(pj_pool_factory*) pjmedia_vid_dev_subsys_get_pool_factory(void) 
    489208{ 
    490     return vid_subsys.pf; 
     209    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys(); 
     210    return vid_subsys->pf; 
    491211} 
    492212 
     
    495215{ 
    496216    unsigned i; 
     217    pjmedia_vid_subsys *vid_subsys = pjmedia_get_vid_subsys(); 
    497218 
    498219    /* Allow shutdown() to be called multiple times as long as there is 
    499220     * matching number of init(). 
    500221     */ 
    501     if (vid_subsys.init_count == 0) { 
     222    if (vid_subsys->init_count == 0) { 
    502223        return PJ_SUCCESS; 
    503224    } 
    504     --vid_subsys.init_count; 
    505  
    506     if (vid_subsys.init_count == 0) { 
    507         for (i=0; i<vid_subsys.drv_cnt; ++i) { 
    508             deinit_driver(i); 
     225    --vid_subsys->init_count; 
     226 
     227    if (vid_subsys->init_count == 0) { 
     228        for (i=0; i<vid_subsys->drv_cnt; ++i) { 
     229            pjmedia_vid_driver_deinit(i); 
    509230        } 
    510231 
    511         vid_subsys.pf = NULL; 
     232        vid_subsys->pf = NULL; 
    512233    } 
    513234    return PJ_SUCCESS; 
    514235} 
    515236 
    516 /* API: Refresh the list of video devices installed in the system. */ 
    517 PJ_DEF(pj_status_t) pjmedia_vid_dev_refresh(void) 
    518 { 
    519     unsigned i; 
    520      
    521     vid_subsys.dev_cnt = 0; 
    522     for (i=0; i<vid_subsys.drv_cnt; ++i) { 
    523         struct driver *drv = &vid_subsys.drv[i]; 
    524          
    525         if (drv->f && drv->f->op->refresh) { 
    526             pj_status_t status = drv->f->op->refresh(drv->f); 
    527             if (status != PJ_SUCCESS) { 
    528                 PJ_PERROR(4, (THIS_FILE, status, "Unable to refresh device " 
    529                                                  "list for %s", drv->name)); 
    530             } 
    531         } 
    532         init_driver(i, PJ_TRUE); 
    533     } 
    534     return PJ_SUCCESS; 
    535 } 
    536  
    537 /* API: Get the number of video devices installed in the system. */ 
    538 PJ_DEF(unsigned) pjmedia_vid_dev_count(void) 
    539 { 
    540     return vid_subsys.dev_cnt; 
    541 } 
    542  
    543 /* Internal: convert local index to global device index */ 
    544 static pj_status_t make_global_index(unsigned drv_idx,  
    545                                      pjmedia_vid_dev_index *id) 
    546 { 
    547     if (*id < 0) { 
    548         return PJ_SUCCESS; 
    549     } 
    550  
    551     /* Check that factory still exists */ 
    552     PJ_ASSERT_RETURN(vid_subsys.drv[drv_idx].f, PJ_EBUG); 
    553  
    554     /* Check that device index is valid */ 
    555     PJ_ASSERT_RETURN(*id>=0 && *id<(int)vid_subsys.drv[drv_idx].dev_cnt,  
    556                      PJ_EBUG); 
    557  
    558     *id += vid_subsys.drv[drv_idx].start_idx; 
    559     return PJ_SUCCESS; 
    560 } 
    561  
    562 /* Internal: lookup device id */ 
    563 static pj_status_t lookup_dev(pjmedia_vid_dev_index id, 
    564                               pjmedia_vid_dev_factory **p_f, 
    565                               unsigned *p_local_index) 
    566 { 
    567     int f_id, index; 
    568  
    569     if (id < 0) { 
    570         unsigned i; 
    571  
    572         if (id <= PJMEDIA_VID_INVALID_DEV) 
    573             return PJMEDIA_EVID_INVDEV; 
    574  
    575         for (i=0; i<vid_subsys.drv_cnt; ++i) { 
    576             struct driver *drv = &vid_subsys.drv[i]; 
    577             if (id==PJMEDIA_VID_DEFAULT_CAPTURE_DEV &&  
    578                 drv->cap_dev_idx >= 0)  
    579             { 
    580                 id = drv->cap_dev_idx; 
    581                 make_global_index(i, &id); 
    582                 break; 
    583             } else if (id==PJMEDIA_VID_DEFAULT_RENDER_DEV &&  
    584                 drv->rend_dev_idx >= 0)  
    585             { 
    586                 id = drv->rend_dev_idx; 
    587                 make_global_index(i, &id); 
    588                 break; 
    589             } 
    590         } 
    591  
    592         if (id < 0) { 
    593             return PJMEDIA_EVID_NODEFDEV; 
    594         } 
    595     } 
    596  
    597     f_id = GET_FID(vid_subsys.dev_list[id]); 
    598     index = GET_INDEX(vid_subsys.dev_list[id]); 
    599  
    600     if (f_id < 0 || f_id >= (int)vid_subsys.drv_cnt) 
    601         return PJMEDIA_EVID_INVDEV; 
    602  
    603     if (index < 0 || index >= (int)vid_subsys.drv[f_id].dev_cnt) 
    604         return PJMEDIA_EVID_INVDEV; 
    605  
    606     *p_f = vid_subsys.drv[f_id].f; 
    607     *p_local_index = (unsigned)index; 
    608  
    609     return PJ_SUCCESS; 
    610  
    611 } 
    612  
    613 /* API: lookup device id */ 
    614 PJ_DEF(pj_status_t) 
    615 pjmedia_vid_dev_get_local_index(pjmedia_vid_dev_index id, 
    616                                 pjmedia_vid_dev_factory **p_f, 
    617                                 unsigned *p_local_index) 
    618 { 
    619     return lookup_dev(id, p_f, p_local_index); 
    620 } 
    621  
    622 /* API: from factory and local index, get global index */ 
    623 PJ_DEF(pj_status_t) 
    624 pjmedia_vid_dev_get_global_index(const pjmedia_vid_dev_factory *f, 
    625                                  unsigned local_idx, 
    626                                  pjmedia_vid_dev_index *pid) 
    627 { 
    628     PJ_ASSERT_RETURN(f->sys.drv_idx >= 0 && f->sys.drv_idx < MAX_DRIVERS, 
    629                      PJ_EINVALIDOP); 
    630     *pid = local_idx; 
    631     return make_global_index(f->sys.drv_idx, pid); 
    632 } 
    633  
    634 /* API: Get device information. */ 
    635 PJ_DEF(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id, 
    636                                              pjmedia_vid_dev_info *info) 
    637 { 
    638     pjmedia_vid_dev_factory *f; 
    639     unsigned index; 
    640     pj_status_t status; 
    641  
    642     PJ_ASSERT_RETURN(info, PJ_EINVAL); 
    643     PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT); 
    644  
    645     if (id <= PJMEDIA_VID_INVALID_DEV) 
    646         return PJMEDIA_EVID_INVDEV; 
    647  
    648     status = lookup_dev(id, &f, &index); 
    649     if (status != PJ_SUCCESS) 
    650         return status; 
    651  
    652     status = f->op->get_dev_info(f, index, info); 
    653  
    654     /* Make sure device ID is the real ID (not PJMEDIA_VID_DEFAULT_*_DEV) */ 
    655     info->id = index; 
    656     make_global_index(f->sys.drv_idx, &info->id); 
    657  
    658     return status; 
    659 } 
    660  
    661 /* API: find device */ 
    662 PJ_DEF(pj_status_t) pjmedia_vid_dev_lookup( const char *drv_name, 
    663                                             const char *dev_name, 
    664                                             pjmedia_vid_dev_index *id) 
    665 { 
    666     pjmedia_vid_dev_factory *f = NULL; 
    667     unsigned drv_idx, dev_idx; 
    668  
    669     PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL); 
    670     PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT); 
    671  
    672     for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) { 
    673         if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name)) 
    674         { 
    675             f = vid_subsys.drv[drv_idx].f; 
    676             break; 
    677         } 
    678     } 
    679  
    680     if (!f) 
    681         return PJ_ENOTFOUND; 
    682  
    683     for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx) 
    684     { 
    685         pjmedia_vid_dev_info info; 
    686         pj_status_t status; 
    687  
    688         status = f->op->get_dev_info(f, dev_idx, &info); 
    689         if (status != PJ_SUCCESS) 
    690             return status; 
    691  
    692         if (!pj_ansi_stricmp(dev_name, info.name)) 
    693             break; 
    694     } 
    695  
    696     if (dev_idx==vid_subsys.drv[drv_idx].dev_cnt) 
    697         return PJ_ENOTFOUND; 
    698  
    699     *id = dev_idx; 
    700     make_global_index(drv_idx, id); 
    701  
    702     return PJ_SUCCESS; 
    703 } 
    704  
    705 /* API: Initialize the video device parameters with default values for the 
    706  * specified device. 
    707  */ 
    708 PJ_DEF(pj_status_t) pjmedia_vid_dev_default_param(pj_pool_t *pool, 
    709                                                   pjmedia_vid_dev_index id, 
    710                                                   pjmedia_vid_dev_param *param) 
    711 { 
    712     pjmedia_vid_dev_factory *f; 
    713     unsigned index; 
    714     pj_status_t status; 
    715  
    716     PJ_ASSERT_RETURN(param, PJ_EINVAL); 
    717     PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT); 
    718  
    719     if (id <= PJMEDIA_VID_INVALID_DEV) 
    720         return PJMEDIA_EVID_INVDEV; 
    721  
    722     status = lookup_dev(id, &f, &index); 
    723     if (status != PJ_SUCCESS) 
    724         return status; 
    725  
    726     status = f->op->default_param(pool, f, index, param); 
    727     if (status != PJ_SUCCESS) 
    728         return status; 
    729  
    730     /* Normalize device IDs */ 
    731     make_global_index(f->sys.drv_idx, &param->cap_id); 
    732     make_global_index(f->sys.drv_idx, &param->rend_id); 
    733  
    734     return PJ_SUCCESS; 
    735 } 
    736  
    737 /* API: Open video stream object using the specified parameters. */ 
    738 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_create( 
    739                                         pjmedia_vid_dev_param *prm, 
    740                                         const pjmedia_vid_dev_cb *cb, 
    741                                         void *user_data, 
    742                                         pjmedia_vid_dev_stream **p_vid_strm) 
    743 { 
    744     pjmedia_vid_dev_factory *cap_f=NULL, *rend_f=NULL, *f=NULL; 
    745     pj_status_t status; 
    746  
    747     PJ_ASSERT_RETURN(prm && prm->dir && p_vid_strm, PJ_EINVAL); 
    748     PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT); 
    749     PJ_ASSERT_RETURN(prm->dir==PJMEDIA_DIR_CAPTURE || 
    750                      prm->dir==PJMEDIA_DIR_RENDER || 
    751                      prm->dir==PJMEDIA_DIR_CAPTURE_RENDER, 
    752                      PJ_EINVAL); 
    753  
    754     /* Normalize cap_id */ 
    755     if (prm->dir & PJMEDIA_DIR_CAPTURE) { 
    756         unsigned index; 
    757  
    758         if (prm->cap_id < 0) 
    759             prm->cap_id = PJMEDIA_VID_DEFAULT_CAPTURE_DEV; 
    760  
    761         status = lookup_dev(prm->cap_id, &cap_f, &index); 
    762         if (status != PJ_SUCCESS) 
    763             return status; 
    764  
    765         prm->cap_id = index; 
    766         f = cap_f; 
    767     } 
    768  
    769     /* Normalize rend_id */ 
    770     if (prm->dir & PJMEDIA_DIR_RENDER) { 
    771         unsigned index; 
    772  
    773         if (prm->rend_id < 0) 
    774             prm->rend_id = PJMEDIA_VID_DEFAULT_RENDER_DEV; 
    775  
    776         status = lookup_dev(prm->rend_id, &rend_f, &index); 
    777         if (status != PJ_SUCCESS) 
    778             return status; 
    779  
    780         prm->rend_id = index; 
    781         f = rend_f; 
    782     } 
    783  
    784     PJ_ASSERT_RETURN(f != NULL, PJ_EBUG); 
    785  
    786     /* For now, cap_id and rend_id must belong to the same factory */ 
    787     PJ_ASSERT_RETURN((prm->dir != PJMEDIA_DIR_CAPTURE_RENDER) || 
    788                      (cap_f == rend_f), 
    789                      PJMEDIA_EVID_INVDEV); 
    790  
    791     /* Create the stream */ 
    792     status = f->op->create_stream(f, prm, cb, 
    793                                   user_data, p_vid_strm); 
    794     if (status != PJ_SUCCESS) 
    795         return status; 
    796  
    797     /* Assign factory id to the stream */ 
    798     (*p_vid_strm)->sys.drv_idx = f->sys.drv_idx; 
    799     return PJ_SUCCESS; 
    800 } 
    801  
    802 /* API: Get the running parameters for the specified video stream. */ 
    803 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_param( 
    804                                             pjmedia_vid_dev_stream *strm, 
    805                                             pjmedia_vid_dev_param *param) 
    806 { 
    807     pj_status_t status; 
    808  
    809     PJ_ASSERT_RETURN(strm && param, PJ_EINVAL); 
    810     PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT); 
    811  
    812     status = strm->op->get_param(strm, param); 
    813     if (status != PJ_SUCCESS) 
    814         return status; 
    815  
    816     /* Normalize device id's */ 
    817     make_global_index(strm->sys.drv_idx, &param->cap_id); 
    818     make_global_index(strm->sys.drv_idx, &param->rend_id); 
    819  
    820     return PJ_SUCCESS; 
    821 } 
    822  
    823 /* API: Get the value of a specific capability of the video stream. */ 
    824 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_cap( 
    825                                             pjmedia_vid_dev_stream *strm, 
    826                                             pjmedia_vid_dev_cap cap, 
    827                                             void *value) 
    828 { 
    829     return strm->op->get_cap(strm, cap, value); 
    830 } 
    831  
    832 /* API: Set the value of a specific capability of the video stream. */ 
    833 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_set_cap( 
    834                                             pjmedia_vid_dev_stream *strm, 
    835                                             pjmedia_vid_dev_cap cap, 
    836                                             const void *value) 
    837 { 
    838     /* For fast switching, device global index needs to be converted to 
    839      * local index before forwarding the request to the device stream. 
    840      */ 
    841     if (cap == PJMEDIA_VID_DEV_CAP_SWITCH) { 
    842         pjmedia_vid_dev_factory *f; 
    843         unsigned local_idx; 
    844         pj_status_t status; 
    845         pjmedia_vid_dev_switch_param p = *(pjmedia_vid_dev_switch_param*)value; 
    846  
    847         status = lookup_dev(p.target_id, &f, &local_idx); 
    848         if (status != PJ_SUCCESS) 
    849             return status; 
    850  
    851         /* Make sure that current & target devices share the same factory */ 
    852         if (f->sys.drv_idx != strm->sys.drv_idx) 
    853             return PJMEDIA_EVID_INVDEV; 
    854  
    855         p.target_id = local_idx; 
    856         return strm->op->set_cap(strm, cap, &p); 
    857     } 
    858  
    859     return strm->op->set_cap(strm, cap, value); 
    860 } 
    861  
    862 /* API: Start the stream. */ 
    863 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_start(pjmedia_vid_dev_stream *strm) 
    864 { 
    865     pj_status_t status; 
    866  
    867     if (pjmedia_vid_dev_stream_is_running(strm)) 
    868         return PJ_SUCCESS; 
    869  
    870     status = strm->op->start(strm); 
    871     if (status == PJ_SUCCESS) 
    872         strm->sys.is_running = PJ_TRUE; 
    873     return status; 
    874 } 
    875  
    876 /* API: has it been started? */ 
    877 PJ_DEF(pj_bool_t) 
    878 pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm) 
    879 { 
    880     return strm->sys.is_running; 
    881 } 
    882  
    883 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_get_frame( 
    884                                             pjmedia_vid_dev_stream *strm, 
    885                                             pjmedia_frame *frame) 
    886 { 
    887     pj_assert(strm->op->get_frame); 
    888     return strm->op->get_frame(strm, frame); 
    889 } 
    890  
    891 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_put_frame( 
    892                                             pjmedia_vid_dev_stream *strm, 
    893                                             const pjmedia_frame *frame) 
    894 { 
    895     pj_assert(strm->op->put_frame); 
    896     return strm->op->put_frame(strm, frame); 
    897 } 
    898  
    899 /* API: Stop the stream. */ 
    900 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_stop(pjmedia_vid_dev_stream *strm) 
    901 { 
    902     strm->sys.is_running = PJ_FALSE; 
    903     return strm->op->stop(strm); 
    904 } 
    905  
    906 /* API: Destroy the stream. */ 
    907 PJ_DEF(pj_status_t) pjmedia_vid_dev_stream_destroy( 
    908                                                 pjmedia_vid_dev_stream *strm) 
    909 { 
    910     strm->sys.is_running = PJ_FALSE; 
    911     return strm->op->destroy(strm); 
    912 } 
    913  
    914237 
    915238#endif /* PJMEDIA_HAS_VIDEO */ 
  • pjproject/trunk/pjmedia/src/pjmedia/endpoint.c

    r5242 r5255  
    106106 * Initialize and get the instance of media endpoint. 
    107107 */ 
    108 PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf, 
    109                                          pj_ioqueue_t *ioqueue, 
    110                                          unsigned worker_cnt, 
    111                                          pjmedia_endpt **p_endpt) 
     108PJ_DEF(pj_status_t) pjmedia_endpt_create2(pj_pool_factory *pf, 
     109                                          pj_ioqueue_t *ioqueue, 
     110                                          unsigned worker_cnt, 
     111                                          pjmedia_endpt **p_endpt) 
    112112{ 
    113113    pj_pool_t *pool; 
     
    134134    endpt->has_telephone_event = PJ_TRUE; 
    135135 
    136     /* Sound */ 
    137     status = pjmedia_aud_subsys_init(pf); 
    138     if (status != PJ_SUCCESS) 
    139         goto on_error; 
     136    /* Initialize audio subsystem. 
     137     * To avoid pjmedia's dependendy on pjmedia-audiodev, the initialization 
     138     * (and shutdown) of audio subsystem will be done in the application 
     139     * level instead, when it calls inline functions pjmedia_endpt_create() 
     140     * and pjmedia_endpt_destroy(). 
     141     */ 
     142    //status = pjmedia_aud_subsys_init(pf); 
     143    //if (status != PJ_SUCCESS) 
     144    //  goto on_error; 
    140145 
    141146    /* Init codec manager. */ 
     
    189194 
    190195    pjmedia_codec_mgr_destroy(&endpt->codec_mgr); 
    191     pjmedia_aud_subsys_shutdown(); 
     196    //pjmedia_aud_subsys_shutdown(); 
    192197    pj_pool_release(pool); 
    193198    return status; 
     
    205210 * Deinitialize media endpoint. 
    206211 */ 
    207 PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt) 
     212PJ_DEF(pj_status_t) pjmedia_endpt_destroy2 (pjmedia_endpt *endpt) 
    208213{ 
    209214    exit_cb *ecb; 
     
    220225 
    221226    pjmedia_codec_mgr_destroy(&endpt->codec_mgr); 
    222     pjmedia_aud_subsys_shutdown(); 
     227    //pjmedia_aud_subsys_shutdown(); 
    223228 
    224229    /* Call all registered exit callbacks */ 
  • pjproject/trunk/pjmedia/src/pjmedia/sound_legacy.c

    r5140 r5255  
    2828 
    2929#include <pjmedia/sound.h> 
    30 #include <pjmedia-audiodev/errno.h> 
    3130#include <pj/assert.h> 
    3231 
     
    5049}; 
    5150 
    52 PJ_DEF(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory) 
    53 { 
    54     return pjmedia_aud_subsys_init(factory); 
    55 } 
    56  
    57 PJ_DEF(pj_status_t) pjmedia_snd_deinit(void) 
    58 { 
    59     return pjmedia_aud_subsys_shutdown(); 
    60 } 
    61  
    62 PJ_DEF(int) pjmedia_snd_get_dev_count(void) 
    63 { 
    64     return pjmedia_aud_dev_count(); 
    65 } 
    6651 
    6752PJ_DEF(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index) 
     
    159144 
    160145    /* Create sound wrapper */ 
    161     pool = pj_pool_create(pjmedia_aud_subsys_get_pool_factory(), 
     146    pool = pj_pool_create(pjmedia_get_aud_subsys()->pf, 
    162147                          "legacy-snd", 512, 512, NULL); 
    163148    snd_strm = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_stream); 
Note: See TracChangeset for help on using the changeset viewer.