Changeset 4361 for pjproject/trunk/pjmedia/src/pjmedia/vid_codec_util.c
- Timestamp:
- Feb 21, 2013 2:48:53 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/vid_codec_util.c
r3995 r4361 39 39 #define H264_STRICT_SDP_NEGO 0 40 40 41 /* Default frame rate, if not specified */ 42 #define DEFAULT_H264_FPS_NUM 15 43 #define DEFAULT_H264_FPS_DENUM 1 44 45 /* Default aspect ratio, if not specified */ 46 #define DEFAULT_H264_RATIO_NUM 15 47 #define DEFAULT_H264_RATIO_DENUM 1 48 41 49 42 50 /* ITU resolution definition */ … … 54 62 {{"CIF16",5}, {1408,1142}}, 55 63 }; 64 65 66 #define CALC_H264_MB_NUM(size) (((size.w+15)/16)*((size.h+15)/16)) 67 #define CALC_H264_MBPS(size,fps) CALC_H264_MB_NUM(size)*fps.num/fps.denum 56 68 57 69 … … 292 304 293 305 306 /* Declaration of H.264 level info */ 307 typedef struct h264_level_info_t 308 { 309 unsigned id; /* Level id. */ 310 unsigned max_mbps; /* Max macroblocks per second. */ 311 unsigned max_mb; /* Max macroblocks. */ 312 unsigned max_br; /* Max bitrate (kbps). */ 313 } h264_level_info_t; 314 315 316 /* Init H264 parameters based on profile-level-id */ 317 static pj_status_t init_h264_profile(const pj_str_t *profile, 318 pjmedia_vid_codec_h264_fmtp *fmtp) 319 { 320 const h264_level_info_t level_info[] = 321 { 322 { 10, 1485, 99, 64 }, 323 { 9, 1485, 99, 128 }, /*< level 1b */ 324 { 11, 3000, 396, 192 }, 325 { 12, 6000, 396, 384 }, 326 { 13, 11880, 396, 768 }, 327 { 20, 11880, 396, 2000 }, 328 { 21, 19800, 792, 4000 }, 329 { 22, 20250, 1620, 4000 }, 330 { 30, 40500, 1620, 10000 }, 331 { 31, 108000, 3600, 14000 }, 332 { 32, 216000, 5120, 20000 }, 333 { 40, 245760, 8192, 20000 }, 334 { 41, 245760, 8192, 50000 }, 335 { 42, 522240, 8704, 50000 }, 336 { 50, 589824, 22080, 135000 }, 337 { 51, 983040, 36864, 240000 }, 338 }; 339 unsigned i, tmp; 340 pj_str_t endst; 341 const h264_level_info_t *li = NULL; 342 343 if (profile->slen != 6) 344 return PJMEDIA_SDP_EINFMTP; 345 346 tmp = pj_strtoul2(profile, &endst, 16); 347 if (endst.slen) 348 return PJMEDIA_SDP_EINFMTP; 349 350 fmtp->profile_idc = (pj_uint8_t)((tmp >> 16) & 0xFF); 351 fmtp->profile_iop = (pj_uint8_t)((tmp >> 8) & 0xFF); 352 fmtp->level = (pj_uint8_t)(tmp & 0xFF); 353 354 for (i = 0; i < PJ_ARRAY_SIZE(level_info); ++i) { 355 if (level_info[i].id == fmtp->level) { 356 li = &level_info[i]; 357 break; 358 } 359 } 360 if (li == NULL) 361 return PJMEDIA_SDP_EINFMTP; 362 363 /* Init profile level spec */ 364 if (fmtp->max_br == 0) 365 fmtp->max_br = li->max_br; 366 if (fmtp->max_mbps == 0) 367 fmtp->max_mbps = li->max_mbps; 368 if (fmtp->max_fs == 0) 369 fmtp->max_fs = li->max_mb; 370 371 return PJ_SUCCESS; 372 } 373 374 294 375 /* H264 fmtp parser */ 295 376 PJ_DEF(pj_status_t) pjmedia_vid_codec_h264_parse_fmtp( … … 306 387 const pj_str_t SPROP_PARAMETER_SETS = {"sprop-parameter-sets", 20}; 307 388 unsigned i; 389 pj_status_t status; 308 390 309 391 pj_bzero(h264_fmtp, sizeof(*h264_fmtp)); … … 312 394 unsigned tmp; 313 395 if (pj_stricmp(&fmtp->param[i].name, &PROFILE_LEVEL_ID)==0) { 314 pj_str_t endst; 315 316 if (fmtp->param[i].val.slen != 6) 317 return PJMEDIA_SDP_EINFMTP; 318 319 tmp = pj_strtoul2(&fmtp->param[i].val, &endst, 16); 320 if (endst.slen) 321 return PJMEDIA_SDP_EINFMTP; 322 323 h264_fmtp->profile_idc = (pj_uint8_t)((tmp >> 16) & 0xFF); 324 h264_fmtp->profile_iop = (pj_uint8_t)((tmp >> 8) & 0xFF); 325 h264_fmtp->level = (pj_uint8_t)(tmp & 0xFF); 396 /* Init H264 parameters based on level, if not set yet */ 397 status = init_h264_profile(&fmtp->param[i].val, h264_fmtp); 398 if (status != PJ_SUCCESS) 399 return status; 326 400 } else if (pj_stricmp(&fmtp->param[i].name, &PACKETIZATION_MODE)==0) { 327 401 tmp = pj_strtoul(&fmtp->param[i].val); … … 332 406 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_MBPS)==0) { 333 407 tmp = pj_strtoul(&fmtp->param[i].val); 334 h264_fmtp->max_mbps = tmp;408 h264_fmtp->max_mbps = PJ_MAX(tmp, h264_fmtp->max_mbps); 335 409 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_FS)==0) { 336 410 tmp = pj_strtoul(&fmtp->param[i].val); 337 h264_fmtp->max_fs = tmp;411 h264_fmtp->max_fs = PJ_MAX(tmp, h264_fmtp->max_fs); 338 412 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_CPB)==0) { 339 413 tmp = pj_strtoul(&fmtp->param[i].val); 340 h264_fmtp->max_cpb = tmp;414 h264_fmtp->max_cpb = PJ_MAX(tmp, h264_fmtp->max_cpb); 341 415 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_DPB)==0) { 342 416 tmp = pj_strtoul(&fmtp->param[i].val); 343 h264_fmtp->max_dpb = tmp;417 h264_fmtp->max_dpb = PJ_MAX(tmp, h264_fmtp->max_dpb); 344 418 } else if (pj_stricmp(&fmtp->param[i].name, &MAX_BR)==0) { 345 419 tmp = pj_strtoul(&fmtp->param[i].val); 346 h264_fmtp->max_br = tmp;420 h264_fmtp->max_br = PJ_MAX(tmp, h264_fmtp->max_br); 347 421 } else if (pj_stricmp(&fmtp->param[i].name, &SPROP_PARAMETER_SETS)==0) 348 422 { … … 508 582 509 583 510 /* Declaration of H.264 level info */ 511 typedef struct h264_level_info_t 512 { 513 unsigned id; /* Level id. */ 514 unsigned max_mbps; /* Max macroblocks per second. */ 515 unsigned max_mb; /* Max macroblocks. */ 516 unsigned bitrate; /* Max bitrate (kbps). */ 517 unsigned def_w; /* Default width. */ 518 unsigned def_h; /* Default height. */ 519 unsigned def_fps; /* Default fps. */ 520 } h264_level_info_t; 521 522 523 /* Get H.264 level info from specified level ID */ 524 static pj_status_t get_h264_level_info(unsigned id, h264_level_info_t *level) 525 { 526 unsigned i; 527 const h264_level_info_t level_info[] = 528 { 529 { 10, 1485, 99, 64, 176, 144, 15 }, 530 { 9, 1485, 99, 128, 176, 144, 15 }, /*< level 1b */ 531 { 11, 3000, 396, 192, 320, 240, 10 }, 532 { 12, 6000, 396, 384, 352, 288, 15 }, 533 { 13, 11880, 396, 768, 352, 288, 15 }, 534 { 20, 11880, 396, 2000, 352, 288, 30 }, 535 { 21, 19800, 792, 4000, 352, 288, 30 }, 536 { 22, 20250, 1620, 4000, 352, 288, 30 }, 537 { 30, 40500, 1620, 10000, 720, 480, 30 }, 538 { 31, 108000, 3600, 14000, 1280, 720, 30 }, 539 { 32, 216000, 5120, 20000, 1280, 720, 30 }, 540 { 40, 245760, 8192, 20000, 1920, 1080, 30 }, 541 { 41, 245760, 8192, 50000, 1920, 1080, 30 }, 542 { 42, 522240, 8704, 50000, 1920, 1080, 30 }, 543 { 50, 589824, 22080, 135000, 1920, 1080, 30 }, 544 { 51, 983040, 36864, 240000, 1920, 1080, 30 }, 545 }; 546 547 for (i = 0; i < PJ_ARRAY_SIZE(level_info); ++i) { 548 if (level_info[i].id == id) { 549 *level = level_info[i]; 550 return PJ_SUCCESS; 551 } 552 } 553 return PJ_ENOTFOUND; 554 } 555 556 557 #define CALC_H264_MB_NUM(size) (((size.w+15)/16)*((size.h+15)/16)) 558 #define CALC_H264_MBPS(size,fps) CALC_H264_MB_NUM(size)*fps.num/fps.denum 584 /* Find greatest common divisor (GCD) */ 585 static unsigned gcd (unsigned a, unsigned b) { 586 unsigned c; 587 while (b) { 588 c = a % b; 589 a = b; 590 b = c; 591 } 592 return a; 593 } 594 595 /* Find highest resolution possible for the specified H264 fmtp and 596 * aspect ratio. 597 */ 598 static pj_status_t find_highest_res(pjmedia_vid_codec_h264_fmtp *fmtp, 599 const pjmedia_ratio *fps, 600 const pjmedia_ratio *ratio, 601 pjmedia_rect_size *size) 602 { 603 pjmedia_ratio def_ratio = { DEFAULT_H264_RATIO_NUM, 604 DEFAULT_H264_RATIO_DENUM }; 605 pjmedia_ratio def_fps = { DEFAULT_H264_FPS_NUM, 606 DEFAULT_H264_FPS_DENUM }; 607 pjmedia_ratio asp_ratio, the_fps; 608 unsigned max_fs, g, scale; 609 610 pj_assert(size); 611 612 /* Get the ratio, or just use default if not provided. */ 613 if (ratio && ratio->num && ratio->denum) { 614 asp_ratio = *ratio; 615 } else { 616 asp_ratio = def_ratio; 617 } 618 619 /* Normalize the aspect ratio */ 620 g = gcd(asp_ratio.num, asp_ratio.denum); 621 asp_ratio.num /= g; 622 asp_ratio.denum /= g; 623 624 /* Get the frame rate, or just use default if not provided. */ 625 if (fps && fps->num && fps->denum) { 626 the_fps = *fps; 627 } else { 628 the_fps = def_fps; 629 } 630 631 /* Calculate maximum size (in macroblocks) */ 632 max_fs = fmtp->max_mbps * fps->denum / fps->num; 633 max_fs = PJ_MIN(max_fs, fmtp->max_fs); 634 635 /* Check if the specified ratio is using big numbers 636 * (not normalizable), override it with default ratio! 637 */ 638 if ((int)max_fs < asp_ratio.num * asp_ratio.denum) 639 asp_ratio = def_ratio; 640 641 /* Calculate the scale factor for size */ 642 scale = pj_isqrt(max_fs / asp_ratio.denum / asp_ratio.num); 643 644 /* Calculate the size, note that the frame size is in macroblock units */ 645 size->w = asp_ratio.num * scale * 16; 646 size->h = asp_ratio.denum * scale * 16; 647 648 return PJ_SUCCESS; 649 } 559 650 560 651 … … 562 653 pjmedia_vid_codec_param *param) 563 654 { 564 const unsigned default_fps = 30;565 566 655 if (param->dir & PJMEDIA_DIR_ENCODING) { 567 656 pjmedia_vid_codec_h264_fmtp fmtp; 568 657 pjmedia_video_format_detail *vfd; 569 h264_level_info_t level_info;570 658 pj_status_t status; 571 659 … … 576 664 return status; 577 665 578 status = get_h264_level_info(fmtp.level, &level_info); 579 if (status != PJ_SUCCESS) 580 return status; 581 582 /* Size and fps for encoding direction must conform to H.264 level 666 /* Adjust fps, size, and bitrate to conform to H.264 level 583 667 * specified by remote SDP fmtp. 584 668 */ 585 669 vfd = pjmedia_format_get_video_format_detail(¶m->enc_fmt, 586 670 PJ_TRUE); 671 672 if (vfd->fps.num == 0 || vfd->fps.denum == 0) { 673 vfd->fps.num = DEFAULT_H264_FPS_NUM; 674 vfd->fps.denum = DEFAULT_H264_FPS_DENUM; 675 } 676 587 677 if (vfd->size.w && vfd->size.h) { 588 678 unsigned mb, mbps; 589 679 590 if (vfd->fps.num == 0 || vfd->fps.denum == 0) { 591 vfd->fps.num = default_fps; 592 vfd->fps.denum = 1; 593 } 680 /* Scale down the resolution if it exceeds profile spec */ 594 681 mb = CALC_H264_MB_NUM(vfd->size); 595 682 mbps = CALC_H264_MBPS(vfd->size, vfd->fps); 596 if (mb > level_info.max_mb || mbps > level_info.max_mbps) {597 vfd->size.w = level_info.def_w;598 vfd->size.h = level_info.def_h;599 vfd->fps.num = level_info.def_fps;600 vfd->fps.denum = 1;683 if (mb > fmtp.max_fs || mbps > fmtp.max_mbps) { 684 pjmedia_ratio r; 685 r.num = vfd->size.w; 686 r.denum = vfd->size.h; 687 find_highest_res(&fmtp, &vfd->fps, &r, &vfd->size); 601 688 } 602 689 } else { 603 vfd->size.w = level_info.def_w; 604 vfd->size.h = level_info.def_h; 605 vfd->fps.num = level_info.def_fps; 606 vfd->fps.denum = 1; 607 } 690 /* When not specified, just use the highest res possible*/ 691 pjmedia_ratio r; 692 r.num = vfd->size.w; 693 r.denum = vfd->size.h; 694 find_highest_res(&fmtp, &vfd->fps, &r, &vfd->size); 695 } 696 697 /* Encoding bitrate must not be higher than H264 level spec */ 698 if (vfd->avg_bps > fmtp.max_br * 1000) 699 vfd->avg_bps = fmtp.max_br * 1000; 700 if (vfd->max_bps > fmtp.max_br * 1000) 701 vfd->max_bps = fmtp.max_br * 1000; 608 702 } 609 703 … … 614 708 pjmedia_vid_codec_h264_fmtp fmtp; 615 709 pjmedia_video_format_detail *vfd; 616 h264_level_info_t level_info; 710 pjmedia_ratio r; 711 pjmedia_rect_size highest_size; 617 712 pj_status_t status; 618 713 … … 622 717 return status; 623 718 624 status = get_h264_level_info(fmtp.level, &level_info);625 if (status != PJ_SUCCESS)626 return status;627 628 719 vfd = pjmedia_format_get_video_format_detail(¶m->dec_fmt, 629 720 PJ_TRUE); 630 721 631 if (vfd->size.w * vfd->size.h < level_info.def_w * level_info.def_h) {632 vfd->size.w = level_info.def_w;633 vfd->size.h = level_info.def_h;634 }635 636 722 if (vfd->fps.num == 0 || vfd->fps.denum == 0) { 637 vfd->fps.num = default_fps; 638 vfd->fps.denum = 1; 639 } 723 vfd->fps.num = DEFAULT_H264_FPS_NUM; 724 vfd->fps.denum = DEFAULT_H264_FPS_DENUM; 725 } 726 727 /* Normalize decoding resolution, i.e: it must not be lower than 728 * the H264 profile level setting used, as this may be used by 729 * app to allocate buffer. 730 */ 731 r.num = vfd->size.w; 732 r.denum = vfd->size.h; 733 find_highest_res(&fmtp, &vfd->fps, &r, &highest_size); 734 if (vfd->size.w * vfd->size.h < highest_size.w * highest_size.h) 735 vfd->size = highest_size; 736 737 /* Normalize decoding bitrate based on H264 level spec */ 738 if (vfd->avg_bps < fmtp.max_br * 1000) 739 vfd->avg_bps = fmtp.max_br * 1000; 740 if (vfd->max_bps < fmtp.max_br * 1000) 741 vfd->max_bps = fmtp.max_br * 1000; 640 742 } 641 743
Note: See TracChangeset
for help on using the changeset viewer.