- Timestamp:
- Apr 6, 2011 1:55:01 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_codec_util.c
r3493 r3500 20 20 #include <pjmedia/vid_codec_util.h> 21 21 #include <pjmedia/errno.h> 22 #include <pjmedia/stream_common.h> 22 23 #include <pjlib-util/base64.h> 24 #include <pj/ctype.h> 23 25 #include <pj/math.h> 24 26 … … 259 261 260 262 /* H264 fmtp parser */ 261 PJ_DEF(pj_status_t) pjmedia_vid_codec_ parse_h264_fmtp(263 PJ_DEF(pj_status_t) pjmedia_vid_codec_h264_parse_fmtp( 262 264 const pjmedia_codec_fmtp *fmtp, 263 265 pjmedia_vid_codec_h264_fmtp *h264_fmtp) … … 289 291 h264_fmtp->profile_idc = (pj_uint8_t)((tmp >> 16) & 0xFF); 290 292 h264_fmtp->profile_iop = (pj_uint8_t)((tmp >> 8) & 0xFF); 291 h264_fmtp-> profile_idc= (pj_uint8_t)(tmp & 0xFF);293 h264_fmtp->level = (pj_uint8_t)(tmp & 0xFF); 292 294 } else if (pj_stricmp(&fmtp->param[i].name, &PACKETIZATION_MODE)==0) { 293 295 tmp = pj_strtoul(&fmtp->param[i].val); 294 if (tmp) h264_fmtp->max_br = tmp; 296 if (tmp >= 0 && tmp <= 2) 297 h264_fmtp->packetization_mode = (pj_uint8_t)tmp; 298 else 299 return PJMEDIA_SDP_EINFMTP; 295 300 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_MBPS)==0) { 296 301 tmp = pj_strtoul(&fmtp->param[i].val); 297 if (tmp)h264_fmtp->max_mbps = tmp;302 h264_fmtp->max_mbps = tmp; 298 303 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_FS)==0) { 299 304 tmp = pj_strtoul(&fmtp->param[i].val); 300 if (tmp)h264_fmtp->max_fs = tmp;305 h264_fmtp->max_fs = tmp; 301 306 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_CPB)==0) { 302 307 tmp = pj_strtoul(&fmtp->param[i].val); 303 if (tmp)h264_fmtp->max_cpb = tmp;308 h264_fmtp->max_cpb = tmp; 304 309 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_DPB)==0) { 305 310 tmp = pj_strtoul(&fmtp->param[i].val); 306 if (tmp)h264_fmtp->max_dpb = tmp;311 h264_fmtp->max_dpb = tmp; 307 312 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_BR)==0) { 308 313 tmp = pj_strtoul(&fmtp->param[i].val); 309 if (tmp)h264_fmtp->max_br = tmp;314 h264_fmtp->max_br = tmp; 310 315 } else if (pj_stricmp(&fmtp->param[i].name, &SPROP_PARAMETER_SETS)==0) 311 316 { … … 351 356 } 352 357 358 /* When profile-level-id is not specified, use default value "42000A" */ 359 if (h264_fmtp->profile_idc == 0) { 360 h264_fmtp->profile_idc = 0x42; 361 h264_fmtp->profile_iop = 0x00; 362 h264_fmtp->level = 0x0A; 363 } 364 353 365 return PJ_SUCCESS; 354 366 } 367 368 PJ_DEF(pj_status_t) pjmedia_vid_codec_h264_match_sdp(pj_pool_t *pool, 369 pjmedia_sdp_media *offer, 370 unsigned o_fmt_idx, 371 pjmedia_sdp_media *answer, 372 unsigned a_fmt_idx, 373 unsigned option) 374 { 375 const pj_str_t PROFILE_LEVEL_ID = {"profile-level-id", 16}; 376 const pj_str_t PACKETIZATION_MODE = {"packetization-mode", 18}; 377 pjmedia_codec_fmtp o_fmtp_raw, a_fmtp_raw; 378 pjmedia_vid_codec_h264_fmtp o_fmtp, a_fmtp; 379 pj_status_t status; 380 381 PJ_UNUSED_ARG(pool); 382 383 /* Parse offer */ 384 status = pjmedia_stream_info_parse_fmtp( 385 NULL, offer, 386 pj_strtoul(&offer->desc.fmt[o_fmt_idx]), 387 &o_fmtp_raw); 388 if (status != PJ_SUCCESS) 389 return status; 390 391 status = pjmedia_vid_codec_h264_parse_fmtp(&o_fmtp_raw, &o_fmtp); 392 if (status != PJ_SUCCESS) 393 return status; 394 395 /* Parse answer */ 396 status = pjmedia_stream_info_parse_fmtp( 397 NULL, answer, 398 pj_strtoul(&answer->desc.fmt[a_fmt_idx]), 399 &a_fmtp_raw); 400 if (status != PJ_SUCCESS) 401 return status; 402 403 status = pjmedia_vid_codec_h264_parse_fmtp(&a_fmtp_raw, &a_fmtp); 404 if (status != PJ_SUCCESS) 405 return status; 406 407 if (option & PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER) { 408 unsigned i; 409 410 /* Flexible negotiation, if the answer has higher capability than 411 * the offer, adjust the answer capability to be match to the offer. 412 */ 413 if (a_fmtp.profile_idc >= o_fmtp.profile_idc) 414 a_fmtp.profile_idc = o_fmtp.profile_idc; 415 if (a_fmtp.profile_iop != o_fmtp.profile_iop) 416 a_fmtp.profile_iop = o_fmtp.profile_iop; 417 if (a_fmtp.level >= o_fmtp.level) 418 a_fmtp.level = o_fmtp.level; 419 if (a_fmtp.packetization_mode >= o_fmtp.packetization_mode) 420 a_fmtp.packetization_mode = o_fmtp.packetization_mode; 421 422 /* Match them now */ 423 if (a_fmtp.profile_idc != o_fmtp.profile_idc || 424 a_fmtp.profile_iop != o_fmtp.profile_iop || 425 a_fmtp.level != o_fmtp.level || 426 a_fmtp.packetization_mode != o_fmtp.packetization_mode) 427 { 428 return PJMEDIA_SDP_EFORMATNOTEQUAL; 429 } 430 431 /* Update the answer */ 432 for (i = 0; i < a_fmtp_raw.cnt; ++i) { 433 if (pj_stricmp(&a_fmtp_raw.param[i].name, &PROFILE_LEVEL_ID) == 0) 434 { 435 char *p = a_fmtp_raw.param[i].val.ptr; 436 pj_val_to_hex_digit(a_fmtp.profile_idc, p); 437 p += 2; 438 pj_val_to_hex_digit(a_fmtp.profile_iop, p); 439 p += 2; 440 pj_val_to_hex_digit(a_fmtp.level, p); 441 } 442 else if (pj_stricmp(&a_fmtp_raw.param[i].name, &PACKETIZATION_MODE) == 0) 443 { 444 char *p = a_fmtp_raw.param[i].val.ptr; 445 *p = '0' + a_fmtp.packetization_mode; 446 } 447 } 448 } else { 449 /* Strict negotiation */ 450 if (a_fmtp.profile_idc != o_fmtp.profile_idc || 451 a_fmtp.profile_iop != o_fmtp.profile_iop || 452 a_fmtp.level != o_fmtp.level || 453 a_fmtp.packetization_mode != o_fmtp.packetization_mode) 454 { 455 return PJMEDIA_SDP_EFORMATNOTEQUAL; 456 } 457 } 458 459 return PJ_SUCCESS; 460 }
Note: See TracChangeset
for help on using the changeset viewer.