- Timestamp:
- Apr 12, 2011 6:24:19 PM (14 years ago)
- Location:
- pjproject/branches/projects/2.0-dev/pjmedia
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/include/pjmedia/vid_codec_util.h
r3500 r3526 140 140 141 141 142 /** 143 * Parse and apply the encoding and decoding SDP fmtp of H.264 in the 144 * specified codec parameter. This will validate size and fps to conform 145 * to H.264 level specified in SDP fmtp "profile-level-id". 146 * 147 * @param param The codec parameter. 148 * 149 * @return PJ_SUCCESS on success. 150 */ 151 PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_apply_fmtp( 152 pjmedia_vid_codec_param *param); 153 154 142 155 PJ_END_DECL 143 156 -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3522 r3526 261 261 {{"QCIF",4}, {"1",1}}, } }, 262 262 }, 263 /*264 263 { 265 264 {PJMEDIA_FORMAT_H263, PJMEDIA_RTP_PT_H263, {"H263",4}}, … … 269 268 {{"QCIF",4}, {"1",1}}, } }, 270 269 }, 271 */272 270 { 273 271 {PJMEDIA_FORMAT_H263, PJMEDIA_RTP_PT_H263, {"H263",4}}, … … 313 311 /* Create packetizer */ 314 312 pktz_cfg.mtu = ff->param.enc_mtu; 313 #if 0 315 314 if (data->fmtp.packetization_mode == 0) 316 315 pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL; … … 319 318 else 320 319 return PJ_ENOTSUP; 320 #else 321 if (data->fmtp.packetization_mode!= 322 PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL && 323 data->fmtp.packetization_mode!= 324 PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED) 325 { 326 return PJ_ENOTSUP; 327 } 328 /* Better always send in single NAL mode for better compatibility */ 329 pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL; 330 #endif 321 331 322 332 status = pjmedia_h264_packetizer_create(ff->pool, &pktz_cfg, &data->pktz); 333 if (status != PJ_SUCCESS) 334 return status; 335 336 /* Apply SDP fmtp to format in codec param */ 337 status = pjmedia_vid_codec_h264_apply_fmtp(&ff->param); 323 338 if (status != PJ_SUCCESS) 324 339 return status; … … 354 369 355 370 /* Apply profile level. */ 356 PJ_TODO(apply_h264_profile_level_in_pjmedia_vid_codec_param);357 371 ctx->level = data->fmtp.level; 358 372 … … 1246 1260 int out_buf_len = output_buf_len; 1247 1261 int err; 1248 AVRational src_timebase;1262 //AVRational src_timebase; 1249 1263 /* For some reasons (e.g: SSE/MMX usage), the avcodec_encode_video() must 1250 1264 * have stack aligned to 16 bytes. Let's try to be safe by preparing the -
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia/vid_codec_util.c
r3500 r3526 26 26 27 27 #define THIS_FILE "vid_codec_util.c" 28 29 /* If this is set to non-zero, H.264 custom negotiation will require 30 * "profile-level-id" and "packetization-mode" to be exact match to 31 * get a successful negotiation. Note that flexible answer (updating 32 * SDP answer to match remote offer) is always active regardless the 33 * value of this macro. 34 */ 35 #define H264_STRICT_SDP_NEGO 0 28 36 29 37 … … 421 429 422 430 /* Match them now */ 431 #if H264_STRICT_SDP_NEGO 423 432 if (a_fmtp.profile_idc != o_fmtp.profile_idc || 424 433 a_fmtp.profile_iop != o_fmtp.profile_iop || … … 428 437 return PJMEDIA_SDP_EFORMATNOTEQUAL; 429 438 } 439 #else 440 if (a_fmtp.profile_idc != o_fmtp.profile_idc) 441 { 442 return PJMEDIA_SDP_EFORMATNOTEQUAL; 443 } 444 #endif 430 445 431 446 /* Update the answer */ … … 447 462 } 448 463 } else { 464 #if H264_STRICT_SDP_NEGO 449 465 /* Strict negotiation */ 450 466 if (a_fmtp.profile_idc != o_fmtp.profile_idc || … … 455 471 return PJMEDIA_SDP_EFORMATNOTEQUAL; 456 472 } 473 #else 474 /* Permissive negotiation */ 475 if (a_fmtp.profile_idc != o_fmtp.profile_idc) 476 { 477 return PJMEDIA_SDP_EFORMATNOTEQUAL; 478 } 479 #endif 457 480 } 458 481 459 482 return PJ_SUCCESS; 460 483 } 484 485 486 /* Declaration of H.264 level info */ 487 typedef struct h264_level_info_t 488 { 489 unsigned id; /* Level id. */ 490 unsigned max_mbps; /* Max macroblocks per second. */ 491 unsigned max_mb; /* Max macroblocks. */ 492 unsigned bitrate; /* Max bitrate (kbps). */ 493 unsigned def_w; /* Default width. */ 494 unsigned def_h; /* Default height. */ 495 unsigned def_fps; /* Default fps. */ 496 } h264_level_info_t; 497 498 499 /* Get H.264 level info from specified level ID */ 500 static pj_status_t get_h264_level_info(unsigned id, h264_level_info_t *level) 501 { 502 unsigned i; 503 const h264_level_info_t level_info[] = 504 { 505 { 10, 1485, 99, 64, 176, 144, 15 }, 506 { 9, 1485, 99, 128, 176, 144, 15 }, /*< level 1b */ 507 { 11, 3000, 396, 192, 320, 240, 10 }, 508 { 12, 6000, 396, 384, 352, 288, 15 }, 509 { 13, 11880, 396, 768, 352, 288, 15 }, 510 { 20, 11880, 396, 2000, 352, 288, 30 }, 511 { 21, 19800, 792, 4000, 352, 288, 30 }, 512 { 22, 20250, 1620, 4000, 352, 288, 30 }, 513 { 30, 40500, 1620, 10000, 720, 480, 30 }, 514 { 31, 108000, 3600, 14000, 1280, 720, 30 }, 515 { 32, 216000, 5120, 20000, 1280, 720, 30 }, 516 { 40, 245760, 8192, 20000, 1920, 1080, 30 }, 517 { 41, 245760, 8192, 50000, 1920, 1080, 30 }, 518 { 42, 522240, 8704, 50000, 1920, 1080, 30 }, 519 { 50, 589824, 22080, 135000, 1920, 1080, 30 }, 520 { 51, 983040, 36864, 240000, 1920, 1080, 30 }, 521 }; 522 523 for (i = 0; i < PJ_ARRAY_SIZE(level_info); ++i) { 524 if (level_info[i].id == id) { 525 *level = level_info[i]; 526 return PJ_SUCCESS; 527 } 528 } 529 return PJ_ENOTFOUND; 530 } 531 532 533 #define CALC_H264_MB_NUM(size) (((size.w+15)/16)*((size.h+15)/16)) 534 #define CALC_H264_MBPS(size,fps) CALC_H264_MB_NUM(size)*fps.num/fps.denum 535 536 537 PJ_DEF(pj_status_t) pjmedia_vid_codec_h264_apply_fmtp( 538 pjmedia_vid_codec_param *param) 539 { 540 const unsigned default_fps = 30; 541 542 if (param->dir & PJMEDIA_DIR_ENCODING) { 543 pjmedia_vid_codec_h264_fmtp fmtp; 544 pjmedia_video_format_detail *vfd; 545 h264_level_info_t level_info; 546 pj_status_t status; 547 548 /* Get remote param */ 549 status = pjmedia_vid_codec_h264_parse_fmtp(¶m->enc_fmtp, 550 &fmtp); 551 if (status != PJ_SUCCESS) 552 return status; 553 554 status = get_h264_level_info(fmtp.level, &level_info); 555 if (status != PJ_SUCCESS) 556 return status; 557 558 /* Size and fps for encoding direction must conform to H.264 level 559 * specified by remote SDP fmtp. 560 */ 561 vfd = pjmedia_format_get_video_format_detail(¶m->enc_fmt, 562 PJ_TRUE); 563 if (vfd->size.w && vfd->size.h) { 564 unsigned mb, mbps; 565 566 if (vfd->fps.num == 0 || vfd->fps.denum == 0) { 567 vfd->fps.num = default_fps; 568 vfd->fps.denum = 1; 569 } 570 mb = CALC_H264_MB_NUM(vfd->size); 571 mbps = CALC_H264_MBPS(vfd->size, vfd->fps); 572 if (mb > level_info.max_mb || mbps > level_info.max_mbps) { 573 vfd->size.w = level_info.def_w; 574 vfd->size.h = level_info.def_h; 575 vfd->fps.num = level_info.def_fps; 576 vfd->fps.denum = 1; 577 } 578 } else { 579 vfd->size.w = level_info.def_w; 580 vfd->size.h = level_info.def_h; 581 vfd->fps.num = level_info.def_fps; 582 vfd->fps.denum = 1; 583 } 584 } 585 586 if (param->dir & PJMEDIA_DIR_DECODING) { 587 /* Here we just want to find the highest resolution possible from the 588 * fmtp and set it as the decoder param. 589 */ 590 pjmedia_vid_codec_h264_fmtp fmtp; 591 pjmedia_video_format_detail *vfd; 592 h264_level_info_t level_info; 593 pj_status_t status; 594 595 status = pjmedia_vid_codec_h264_parse_fmtp(¶m->dec_fmtp, 596 &fmtp); 597 if (status != PJ_SUCCESS) 598 return status; 599 600 status = get_h264_level_info(fmtp.level, &level_info); 601 if (status != PJ_SUCCESS) 602 return status; 603 604 vfd = pjmedia_format_get_video_format_detail(¶m->dec_fmt, 605 PJ_TRUE); 606 607 if (vfd->size.w * vfd->size.h < level_info.def_w * level_info.def_h) { 608 vfd->size.w = level_info.def_w; 609 vfd->size.h = level_info.def_h; 610 } 611 612 if (vfd->fps.num == 0 || vfd->fps.denum == 0) { 613 vfd->fps.num = default_fps; 614 vfd->fps.denum = 1; 615 } 616 } 617 618 return PJ_SUCCESS; 619 }
Note: See TracChangeset
for help on using the changeset viewer.