Changeset 411 for pjproject/trunk/pjmedia/src/pjmedia/codec.c
- Timestamp:
- Apr 27, 2006 10:36:40 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/codec.c
r276 r411 19 19 #include <pjmedia/codec.h> 20 20 #include <pjmedia/errno.h> 21 #include <pj/array.h> 22 #include <pj/assert.h> 23 #include <pj/log.h> 21 24 #include <pj/pool.h> 22 25 #include <pj/string.h> 23 #include <pj/assert.h>24 #include <pj/log.h>25 26 26 27 #define THIS_FILE "codec.c" 27 28 28 /* 29 * Reinitialize array of supported codecs. 30 */ 31 static void enum_all_codecs (pjmedia_codec_mgr *mgr) 32 { 33 pjmedia_codec_factory *factory; 34 35 mgr->codec_cnt = 0; 36 37 factory = mgr->factory_list.next; 38 while (factory != &mgr->factory_list) { 39 unsigned count; 40 pj_status_t status; 41 42 count = PJ_ARRAY_SIZE(mgr->codecs) - mgr->codec_cnt; 43 status = factory->op->enum_info(factory, &count, 44 mgr->codecs+mgr->codec_cnt); 45 if (status == PJ_SUCCESS) 46 mgr->codec_cnt += count; 47 48 factory = factory->next; 49 } 50 } 29 30 31 32 /* Sort codecs in codec manager based on priorities */ 33 static void sort_codecs(pjmedia_codec_mgr *mgr); 34 51 35 52 36 /* … … 62 46 return PJ_SUCCESS; 63 47 } 48 64 49 65 50 /* … … 70 55 pjmedia_codec_factory *factory) 71 56 { 57 pjmedia_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS]; 58 unsigned i, count; 59 pj_status_t status; 60 72 61 PJ_ASSERT_RETURN(mgr && factory, PJ_EINVAL); 73 62 63 /* Enum codecs */ 64 count = PJ_ARRAY_SIZE(info); 65 status = factory->op->enum_info(factory, &count, info); 66 if (status != PJ_SUCCESS) 67 return status; 68 69 70 /* Check codec count */ 71 if (count + mgr->codec_cnt > PJ_ARRAY_SIZE(mgr->codec_desc)) 72 return PJ_ETOOMANY; 73 74 75 /* Save the codecs */ 76 for (i=0; i<count; ++i) { 77 pj_memcpy( &mgr->codec_desc[mgr->codec_cnt+i], 78 &info[i], sizeof(pjmedia_codec_info)); 79 mgr->codec_desc[mgr->codec_cnt+i].prio = PJMEDIA_CODEC_PRIO_NORMAL; 80 mgr->codec_desc[mgr->codec_cnt+i].factory = factory; 81 pjmedia_codec_info_to_id( &info[i], 82 mgr->codec_desc[mgr->codec_cnt+i].id, 83 sizeof(pjmedia_codec_id)); 84 } 85 86 /* Update count */ 87 mgr->codec_cnt += count; 88 89 /* Re-sort codec based on priorities */ 90 sort_codecs(mgr); 91 92 /* Add factory to the list */ 74 93 pj_list_push_back(&mgr->factory_list, factory); 75 enum_all_codecs (mgr); 94 76 95 77 96 return PJ_SUCCESS; 78 97 } 98 79 99 80 100 /* … … 85 105 pjmedia_codec_factory *factory) 86 106 { 87 107 unsigned i; 88 108 PJ_ASSERT_RETURN(mgr && factory, PJ_EINVAL); 89 109 … … 92 112 PJ_ENOTFOUND); 93 113 94 114 /* Erase factory from the factory list */ 95 115 pj_list_erase(factory); 96 enum_all_codecs (mgr); 116 117 118 /* Remove all supported codecs from the codec manager that were created 119 * by the specified factory. 120 */ 121 for (i=0; i<mgr->codec_cnt; ) { 122 123 if (mgr->codec_desc[i].factory == factory) { 124 125 pj_array_erase(mgr->codec_desc, sizeof(mgr->codec_desc[0]), 126 mgr->codec_cnt, i); 127 --mgr->codec_cnt; 128 129 } else { 130 ++i; 131 } 132 } 133 97 134 98 135 return PJ_SUCCESS; 99 136 } 137 100 138 101 139 /* … … 105 143 pjmedia_codec_mgr_enum_codecs(pjmedia_codec_mgr *mgr, 106 144 unsigned *count, 107 pjmedia_codec_info codecs[]) 108 { 145 pjmedia_codec_info codecs[], 146 unsigned *prio) 147 { 148 unsigned i; 149 109 150 PJ_ASSERT_RETURN(mgr && count && codecs, PJ_EINVAL); 110 151 … … 112 153 *count = mgr->codec_cnt; 113 154 114 pj_memcpy(codecs, mgr->codecs, *count * sizeof(pjmedia_codec_info)); 155 for (i=0; i<*count; ++i) { 156 pj_memcpy(&codecs[i], 157 &mgr->codec_desc[i].info, 158 sizeof(pjmedia_codec_info)); 159 } 160 161 if (prio) { 162 for (i=0; i < *count; ++i) 163 prio[i] = mgr->codec_desc[i].prio; 164 } 115 165 116 166 return PJ_SUCCESS; 117 167 } 118 168 169 119 170 /* 120 171 * Get codec info for static payload type. 121 172 */ 122 PJ_DEF(pj_status_t) pjmedia_codec_mgr_get_codec_info(pjmedia_codec_mgr *mgr, 123 unsigned pt, 124 pjmedia_codec_info *inf) 173 PJ_DEF(pj_status_t) 174 pjmedia_codec_mgr_get_codec_info( pjmedia_codec_mgr *mgr, 175 unsigned pt, 176 const pjmedia_codec_info **p_info) 125 177 { 126 178 unsigned i; 127 179 128 PJ_ASSERT_RETURN(mgr && inf&& pt>=0 && pt < 96, PJ_EINVAL);180 PJ_ASSERT_RETURN(mgr && p_info && pt>=0 && pt < 96, PJ_EINVAL); 129 181 130 182 for (i=0; i<mgr->codec_cnt; ++i) { 131 if (mgr->codec s[i].pt == pt) {132 pj_memcpy(inf, &mgr->codecs[i], sizeof(pjmedia_codec_info));183 if (mgr->codec_desc[i].info.pt == pt) { 184 *p_info = &mgr->codec_desc[i].info; 133 185 return PJ_SUCCESS; 134 186 } … … 137 189 return PJMEDIA_CODEC_EUNSUP; 138 190 } 191 192 193 /* 194 * Convert codec info struct into a unique codec identifier. 195 * A codec identifier looks something like "L16/44100/2". 196 */ 197 PJ_DEF(char*) pjmedia_codec_info_to_id( const pjmedia_codec_info *info, 198 char *id, unsigned max_len ) 199 { 200 int len; 201 202 PJ_ASSERT_RETURN(info && id && max_len, NULL); 203 204 len = pj_ansi_snprintf(id, max_len, "%.*s/%u/%u", 205 (int)info->encoding_name.slen, 206 info->encoding_name.ptr, 207 info->clock_rate, 208 info->channel_cnt); 209 210 if (len < 1 || len >= (int)max_len) { 211 id[0] = '\0'; 212 return NULL; 213 } 214 215 return id; 216 } 217 218 219 /* 220 * Find codecs by the unique codec identifier. This function will find 221 * all codecs that match the codec identifier prefix. For example, if 222 * "L16" is specified, then it will find "L16/8000/1", "L16/16000/1", 223 * and so on, up to the maximum count specified in the argument. 224 */ 225 PJ_DEF(pj_status_t) 226 pjmedia_codec_mgr_find_codecs_by_id( pjmedia_codec_mgr *mgr, 227 const pj_str_t *codec_id, 228 unsigned *count, 229 const pjmedia_codec_info *p_info[], 230 unsigned prio[]) 231 { 232 unsigned i, found = 0; 233 234 PJ_ASSERT_RETURN(mgr && codec_id && count && *count, PJ_EINVAL); 235 236 for (i=0; i<mgr->codec_cnt; ++i) { 237 238 if (pj_strnicmp2(codec_id, mgr->codec_desc[i].id, 239 codec_id->slen) == 0) 240 { 241 242 if (p_info) 243 p_info[found] = &mgr->codec_desc[i].info; 244 if (prio) 245 prio[found] = mgr->codec_desc[i].prio; 246 247 ++found; 248 249 if (found >= *count) 250 break; 251 } 252 253 } 254 255 *count = found; 256 257 return found ? PJ_SUCCESS : PJ_ENOTFOUND; 258 } 259 260 261 /* Swap two codecs positions in codec manager */ 262 static void swap_codec(pjmedia_codec_mgr *mgr, unsigned i, unsigned j) 263 { 264 struct pjmedia_codec_desc tmp; 265 266 pj_memcpy(&tmp, &mgr->codec_desc[i], sizeof(struct pjmedia_codec_desc)); 267 268 pj_memcpy(&mgr->codec_desc[i], &mgr->codec_desc[j], 269 sizeof(struct pjmedia_codec_desc)); 270 271 pj_memcpy(&mgr->codec_desc[j], &tmp, sizeof(struct pjmedia_codec_desc)); 272 } 273 274 275 /* Sort codecs in codec manager based on priorities */ 276 static void sort_codecs(pjmedia_codec_mgr *mgr) 277 { 278 unsigned i; 279 280 /* Re-sort */ 281 for (i=0; i<mgr->codec_cnt; ++i) { 282 unsigned j, max; 283 284 for (max=i, j=i+1; j<mgr->codec_cnt; ++j) { 285 if (mgr->codec_desc[j].prio > mgr->codec_desc[max].prio) 286 max = j; 287 } 288 289 if (max != i) 290 swap_codec(mgr, i, max); 291 } 292 293 /* Change PJMEDIA_CODEC_PRIO_HIGHEST codecs to NEXT_HIGHER */ 294 for (i=0; i<mgr->codec_cnt; ++i) { 295 if (mgr->codec_desc[i].prio == PJMEDIA_CODEC_PRIO_HIGHEST) 296 mgr->codec_desc[i].prio = PJMEDIA_CODEC_PRIO_NEXT_HIGHER; 297 else 298 break; 299 } 300 } 301 302 303 /** 304 * Set codec priority. The codec priority determines the order of 305 * the codec in the SDP created by the endpoint. If more than one codecs 306 * are found with the same codec_id prefix, then the function sets the 307 * priorities of all those codecs. 308 */ 309 PJ_DEF(pj_status_t) 310 pjmedia_codec_mgr_set_codec_priority(pjmedia_codec_mgr *mgr, 311 const pj_str_t *codec_id, 312 pjmedia_codec_priority prio) 313 { 314 unsigned i, found = 0; 315 316 PJ_ASSERT_RETURN(mgr && codec_id, PJ_EINVAL); 317 318 /* Update the priorities of affected codecs */ 319 for (i=0; i<mgr->codec_cnt; ++i) 320 { 321 if (codec_id->slen == 0 || 322 pj_strnicmp2(codec_id, mgr->codec_desc[i].id, 323 codec_id->slen) == 0) 324 { 325 mgr->codec_desc[i].prio = prio; 326 ++found; 327 } 328 } 329 330 if (!found) 331 return PJ_ENOTFOUND; 332 333 /* Re-sort codecs */ 334 sort_codecs(mgr); 335 336 337 return PJ_SUCCESS; 338 } 339 139 340 140 341 /*
Note: See TracChangeset
for help on using the changeset viewer.