Coverage Report

Created: 2026-03-22 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pjsip/pjmedia/src/pjmedia-audiodev/audiodev.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
3
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
#include <pjmedia-audiodev/audiodev_imp.h>
20
#include <pj/assert.h>
21
22
#define THIS_FILE   "audiodev.c"
23
24
25
/* extern functions to create factories */
26
#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
27
pjmedia_aud_dev_factory* pjmedia_pa_factory(pj_pool_factory *pf);
28
#endif
29
30
#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO
31
pjmedia_aud_dev_factory* pjmedia_coreaudio_factory(pj_pool_factory *pf);
32
#endif
33
34
#if PJMEDIA_AUDIO_DEV_HAS_ALSA
35
pjmedia_aud_dev_factory* pjmedia_alsa_factory(pj_pool_factory *pf);
36
#endif
37
38
#if PJMEDIA_AUDIO_DEV_HAS_OPENSL
39
pjmedia_aud_dev_factory* pjmedia_opensl_factory(pj_pool_factory *pf);
40
#endif
41
42
#if PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI
43
pjmedia_aud_dev_factory* pjmedia_android_factory(pj_pool_factory *pf);
44
#endif
45
46
#if PJMEDIA_AUDIO_DEV_HAS_OBOE
47
pjmedia_aud_dev_factory* pjmedia_android_oboe_factory(pj_pool_factory *pf);
48
#endif
49
50
#if PJMEDIA_AUDIO_DEV_HAS_BB10
51
pjmedia_aud_dev_factory* pjmedia_bb10_factory(pj_pool_factory *pf);
52
#endif
53
54
#if PJMEDIA_AUDIO_DEV_HAS_WMME
55
pjmedia_aud_dev_factory* pjmedia_wmme_factory(pj_pool_factory *pf);
56
#endif
57
58
#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD
59
pjmedia_aud_dev_factory* pjmedia_bdimad_factory(pj_pool_factory *pf);
60
#endif
61
62
#if PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS
63
pjmedia_aud_dev_factory* pjmedia_symb_vas_factory(pj_pool_factory *pf);
64
#endif
65
66
#if PJMEDIA_AUDIO_DEV_HAS_SYMB_APS
67
pjmedia_aud_dev_factory* pjmedia_aps_factory(pj_pool_factory *pf);
68
#endif
69
70
#if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA
71
pjmedia_aud_dev_factory* pjmedia_symb_mda_factory(pj_pool_factory *pf);
72
#endif
73
74
#if PJMEDIA_AUDIO_DEV_HAS_WASAPI
75
pjmedia_aud_dev_factory* pjmedia_wasapi_factory(pj_pool_factory *pf);
76
#endif
77
78
#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO
79
pjmedia_aud_dev_factory* pjmedia_null_audio_factory(pj_pool_factory *pf);
80
#endif
81
82
83
/* API: Initialize the audio subsystem. */
84
PJ_DEF(pj_status_t) pjmedia_aud_subsys_init(pj_pool_factory *pf)
85
329
{
86
329
    unsigned i;
87
329
    pj_status_t status;
88
329
    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
89
90
    /* Allow init() to be called multiple times as long as there is matching
91
     * number of shutdown().
92
     */
93
329
    if (aud_subsys->init_count++ != 0) {
94
0
        return PJ_SUCCESS;
95
0
    }
96
97
    /* Register error subsystem */
98
329
    status = pj_register_strerror(PJMEDIA_AUDIODEV_ERRNO_START,
99
329
                                  PJ_ERRNO_SPACE_SIZE,
100
329
                                  &pjmedia_audiodev_strerror);
101
329
    pj_assert(status == PJ_SUCCESS);
102
103
    /* Init */
104
329
    aud_subsys->pf = pf;
105
329
    aud_subsys->drv_cnt = 0;
106
329
    aud_subsys->dev_cnt = 0;
107
108
    /* Register creation functions */
109
#if PJMEDIA_AUDIO_DEV_HAS_OBOE
110
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_android_oboe_factory;
111
#endif
112
#if PJMEDIA_AUDIO_DEV_HAS_OPENSL
113
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_opensl_factory;
114
#endif
115
#if PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI
116
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_android_factory;
117
#endif
118
#if PJMEDIA_AUDIO_DEV_HAS_BB10
119
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_bb10_factory;
120
#endif
121
#if PJMEDIA_AUDIO_DEV_HAS_ALSA
122
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_alsa_factory;
123
#endif
124
#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO
125
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_coreaudio_factory;
126
#endif
127
#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
128
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_pa_factory;
129
#endif
130
#if PJMEDIA_AUDIO_DEV_HAS_WMME
131
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_wmme_factory;
132
#endif
133
#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD
134
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_bdimad_factory;
135
#endif
136
#if PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS
137
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_symb_vas_factory;
138
#endif
139
#if PJMEDIA_AUDIO_DEV_HAS_SYMB_APS
140
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_aps_factory;
141
#endif
142
#if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA
143
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_symb_mda_factory;
144
#endif
145
#if PJMEDIA_AUDIO_DEV_HAS_WASAPI
146
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_wasapi_factory;
147
#endif
148
#if PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO
149
    aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_null_audio_factory;
150
#endif
151
152
    /* Initialize each factory and build the device ID list */
153
329
    for (i=0; i<aud_subsys->drv_cnt; ++i) {
154
0
        status = pjmedia_aud_driver_init(i, PJ_FALSE);
155
0
        if (status != PJ_SUCCESS) {
156
0
            pjmedia_aud_driver_deinit(i);
157
0
            continue;
158
0
        }
159
0
    }
160
161
329
    return aud_subsys->dev_cnt ? PJ_SUCCESS : status;
162
329
}
163
164
/* API: register an audio device factory to the audio subsystem. */
165
PJ_DEF(pj_status_t)
166
pjmedia_aud_register_factory(pjmedia_aud_dev_factory_create_func_ptr adf)
167
0
{
168
0
    pj_status_t status;
169
0
    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
170
171
0
    if (aud_subsys->init_count == 0)
172
0
        return PJMEDIA_EAUD_INIT;
173
174
0
    aud_subsys->drv[aud_subsys->drv_cnt].create = adf;
175
0
    status = pjmedia_aud_driver_init(aud_subsys->drv_cnt, PJ_FALSE);
176
0
    if (status == PJ_SUCCESS) {
177
0
        aud_subsys->drv_cnt++;
178
0
    } else {
179
0
        pjmedia_aud_driver_deinit(aud_subsys->drv_cnt);
180
0
    }
181
182
0
    return status;
183
0
}
184
185
/* API: unregister an audio device factory from the audio subsystem. */
186
PJ_DEF(pj_status_t)
187
pjmedia_aud_unregister_factory(pjmedia_aud_dev_factory_create_func_ptr adf)
188
0
{
189
0
    unsigned i, j;
190
0
    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
191
192
0
    if (aud_subsys->init_count == 0)
193
0
        return PJMEDIA_EAUD_INIT;
194
195
0
    for (i=0; i<aud_subsys->drv_cnt; ++i) {
196
0
        pjmedia_aud_driver *drv = &aud_subsys->drv[i];
197
198
0
        if (drv->create == adf) {
199
0
            for (j = drv->start_idx; j < drv->start_idx + drv->dev_cnt; j++)
200
0
            {
201
0
                aud_subsys->dev_list[j] = (pj_uint32_t)PJMEDIA_AUD_INVALID_DEV;
202
0
            }
203
204
0
            pjmedia_aud_driver_deinit(i);
205
0
            return PJ_SUCCESS;
206
0
        }
207
0
    }
208
209
0
    return PJMEDIA_EAUD_ERR;
210
0
}
211
212
/* API: get the pool factory registered to the audio subsystem. */
213
PJ_DEF(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void)
214
0
{
215
0
    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
216
0
    return aud_subsys->pf;
217
0
}
218
219
/* API: Shutdown the audio subsystem. */
220
PJ_DEF(pj_status_t) pjmedia_aud_subsys_shutdown(void)
221
329
{
222
329
    unsigned i;
223
329
    pjmedia_aud_subsys *aud_subsys = pjmedia_get_aud_subsys();
224
225
    /* Allow shutdown() to be called multiple times as long as there is matching
226
     * number of init().
227
     */
228
329
    if (aud_subsys->init_count == 0) {
229
0
        return PJ_SUCCESS;
230
0
    }
231
329
    --aud_subsys->init_count;
232
233
329
    if (aud_subsys->init_count == 0) {
234
329
        for (i=0; i<aud_subsys->drv_cnt; ++i) {
235
0
            pjmedia_aud_driver_deinit(i);
236
0
        }
237
238
        aud_subsys->pf = NULL;
239
329
    }
240
329
    return PJ_SUCCESS;
241
329
}