- Timestamp:
- Apr 6, 2011 1:55:01 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3496 r3500 176 176 pj_size_t bits_len, unsigned *bits_pos) 177 177 178 #define FUNC_FMT_MATCH(name) \ 179 pj_status_t(name)(pj_pool_t *pool, \ 180 pjmedia_sdp_media *offer, unsigned o_fmt_idx, \ 181 pjmedia_sdp_media *answer, unsigned a_fmt_idx, \ 182 unsigned option) 183 184 185 /* Type definition of codec specific functions */ 178 186 typedef FUNC_PACKETIZE(*func_packetize); 179 187 typedef FUNC_UNPACKETIZE(*func_unpacketize); 180 188 typedef pj_status_t (*func_preopen) (ffmpeg_private *ff); 181 189 typedef pj_status_t (*func_postopen) (ffmpeg_private *ff); 190 typedef FUNC_FMT_MATCH(*func_sdp_fmt_match); 182 191 183 192 … … 187 196 /* Predefined info */ 188 197 pjmedia_vid_codec_info info; 189 pjmedia_format_id base_fmt_id; 198 pjmedia_format_id base_fmt_id; /**< Some codecs may be exactly 199 same or compatible with 200 another codec, base format 201 will tell the initializer 202 to copy this codec desc 203 from its base format */ 190 204 pj_uint32_t avg_bps; 191 205 pj_uint32_t max_bps; … … 194 208 func_preopen preopen; 195 209 func_preopen postopen; 210 func_sdp_fmt_match sdp_fmt_match; 196 211 pjmedia_codec_fmtp dec_fmtp; 197 212 … … 217 232 { 218 233 { 219 {PJMEDIA_FORMAT_H264, {"H264",4}, PJMEDIA_RTP_PT_H264}, 220 0, 500000, 1000000, 234 {PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264, {"H264",4}, 235 {"Constrained Baseline (level=30, pack=1)", 39}}, 236 0, 128000, 1000000, 221 237 &h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen, 238 &pjmedia_vid_codec_h264_match_sdp, 222 239 /* Leading space for better compatibility (strange indeed!) */ 223 {2, { {{" profile-level-id",17}, {"42e01e",6}},240 {2, { {{"profile-level-id",16}, {"42e01e",6}}, 224 241 {{" packetization-mode",19}, {"1",1}}, } }, 225 242 }, 226 243 { 227 {PJMEDIA_FORMAT_H263P, {"H263-1998",9}, PJMEDIA_RTP_PT_H263P}, 244 {PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264_RSV1, {"H264",4}, 245 {"Baseline (level=30, pack=1)", 27}}, 246 PJMEDIA_FORMAT_H264, 128000, 1000000, 247 &h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen, 248 &pjmedia_vid_codec_h264_match_sdp, 249 {2, { {{"profile-level-id",16}, {"42001e",6}}, 250 {{" packetization-mode",19}, {"1",1}}, } }, 251 }, 252 { 253 {PJMEDIA_FORMAT_H263P, PJMEDIA_RTP_PT_H263P, {"H263-1998",9}}, 228 254 PJMEDIA_FORMAT_H263, 1000000, 2000000, 229 &h263_packetize, &h263_unpacketize, &h263_preopen, NULL, 255 &h263_packetize, &h263_unpacketize, &h263_preopen, NULL, NULL, 230 256 {2, { {{"CIF",3}, {"1",1}}, 231 257 {{"QCIF",4}, {"1",1}}, } }, 232 258 }, 233 259 { 234 {PJMEDIA_FORMAT_H263, {"H263",4}, PJMEDIA_RTP_PT_H263},260 {PJMEDIA_FORMAT_H263, PJMEDIA_RTP_PT_H263, {"H263",4}}, 235 261 }, 236 262 { 237 {PJMEDIA_FORMAT_H261, {"H261",4}, PJMEDIA_RTP_PT_H261},263 {PJMEDIA_FORMAT_H261, PJMEDIA_RTP_PT_H261, {"H261",4}}, 238 264 }, 239 265 { 240 {PJMEDIA_FORMAT_MJPEG, {"JPEG",4}, PJMEDIA_RTP_PT_JPEG},266 {PJMEDIA_FORMAT_MJPEG, PJMEDIA_RTP_PT_JPEG, {"JPEG",4}}, 241 267 }, 242 268 { 243 {PJMEDIA_FORMAT_MPEG4, {"MP4V",4}},269 {PJMEDIA_FORMAT_MPEG4, 0, {"MP4V",4}}, 244 270 }, 245 271 { 246 {PJMEDIA_FORMAT_XVID, {"XVID",4}},272 {PJMEDIA_FORMAT_XVID, 0, {"XVID",4}}, 247 273 PJMEDIA_FORMAT_MPEG4, 248 274 }, … … 266 292 ff->data = data; 267 293 294 /* Parse remote fmtp */ 295 status = pjmedia_vid_codec_h264_parse_fmtp(&ff->param.enc_fmtp, 296 &data->fmtp); 297 if (status != PJ_SUCCESS) 298 return status; 299 268 300 /* Create packetizer */ 269 301 pktz_cfg.mtu = ff->param.enc_mtu; 270 pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED; 302 if (data->fmtp.packetization_mode == 0) 303 pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL; 304 else if (data->fmtp.packetization_mode == 1) 305 pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED; 306 else 307 return PJ_ENOTSUP; 308 271 309 status = pjmedia_h264_packetizer_create(ff->pool, &pktz_cfg, &data->pktz); 272 310 if (status != PJ_SUCCESS) … … 276 314 AVCodecContext *ctx = ff->enc_ctx; 277 315 278 status = pjmedia_vid_codec_parse_h264_fmtp(&ff->param.enc_fmtp, 279 &data->fmtp); 280 if (status != PJ_SUCCESS) 281 return status; 282 316 /* Apply profile. Note that, for x264 backend, ffmpeg doesn't seem to 317 * use this profile param field, so let's try to apply it "manually". 318 */ 283 319 ctx->profile = data->fmtp.profile_idc; 320 if (ctx->profile == FF_PROFILE_H264_BASELINE) { 321 /* Baseline profile settings (the most used profile in 322 * conversational/real-time communications). 323 */ 324 ctx->coder_type = FF_CODER_TYPE_VLC; 325 ctx->max_b_frames = 0; 326 ctx->flags2 &= ~(CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT); 327 ctx->weighted_p_pred = 0; 328 } else if (ctx->profile == FF_PROFILE_H264_MAIN) { 329 ctx->flags2 &= ~CODEC_FLAG2_8X8DCT; 330 } 331 332 /* Apply profile constraint bits. */ 333 // The x264 doesn't seem to support non-constrained (baseline) profile 334 // so this shouldn't be a problem (for now). 335 //PJ_TODO(set_h264_constraint_bits_properly_in_ffmpeg); 284 336 if (data->fmtp.profile_iop) { 285 337 #if defined(FF_PROFILE_H264_CONSTRAINED) … … 287 339 #endif 288 340 } 341 342 /* Apply profile level. */ 343 PJ_TODO(apply_h264_profile_level_in_pjmedia_vid_codec_param); 289 344 ctx->level = data->fmtp.level; 290 PJ_TODO(set_h264_constrain_bits_properly_in_ffmpeg);291 345 292 346 /* Libx264 rejects the "broken" ffmpeg defaults, so just change some */ … … 383 437 (desc->info.fmt_id == info->fmt_id) && 384 438 ((desc->info.dir & info->dir) == info->dir) && 385 pj_stricmp(&desc->info.encoding_name, &info->encoding_name)==0)439 (desc->info.pt == info->pt)) 386 440 { 387 441 return desc; … … 566 620 } 567 621 568 /* Init unassigned encoder/decoder description from base codec */ 622 /* Review all codecs for applying base format, registering format match for 623 * SDP negotiation, etc. 624 */ 569 625 for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) { 570 626 ffmpeg_codec_desc *desc = &codec_desc[i]; 571 627 628 /* Init encoder/decoder description from base format */ 572 629 if (desc->base_fmt_id && (!desc->dec || !desc->enc)) { 573 630 ffmpeg_codec_desc *base_desc = NULL; … … 606 663 desc->info.dir |= copied_dir; 607 664 desc->enabled = (desc->info.dir != PJMEDIA_DIR_NONE); 665 desc->info.has_rtp_pack = (desc->packetize != NULL) && 666 (desc->unpacketize != NULL); 608 667 609 668 if (copied_dir != PJMEDIA_DIR_NONE) { … … 617 676 } 618 677 } 678 679 /* Registering format match for SDP negotiation */ 680 if (desc->sdp_fmt_match) { 681 status = pjmedia_sdp_neg_register_fmt_match_cb( 682 &desc->info.encoding_name, 683 desc->sdp_fmt_match); 684 pj_assert(status == PJ_SUCCESS); 685 } 619 686 } 620 687
Note: See TracChangeset
for help on using the changeset viewer.