- Timestamp:
- Oct 18, 2011 1:51:01 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3805 r3819 43 43 #include <libavcodec/avcodec.h> 44 44 #include <libavformat/avformat.h> 45 46 #define ENABLE_H264 0 45 #include <libavutil/opt.h> 46 47 47 48 48 /* Prototypes for FFMPEG codecs factory */ … … 220 220 221 221 222 #if ENABLE_H264 222 #if PJMEDIA_HAS_FFMPEG_CODEC_H264 && \ 223 (LIBAVCODEC_VERSION_MAJOR < 53 || LIBAVCODEC_VERSION_MINOR < 20) 224 # error "Must use libavcodec version 53.20 or later to enable FFMPEG H264" 225 #endif 226 223 227 /* H264 constants */ 224 228 #define PROFILE_H264_BASELINE 66 … … 230 234 static FUNC_PACKETIZE(h264_packetize); 231 235 static FUNC_UNPACKETIZE(h264_unpacketize); 232 #endif /* ENABLE_H264 */233 236 234 237 static pj_status_t h263_preopen(ffmpeg_private *ff); … … 240 243 static ffmpeg_codec_desc codec_desc[] = 241 244 { 242 #if ENABLE_H264245 #if PJMEDIA_HAS_FFMPEG_CODEC_H264 243 246 { 244 247 {PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264, {"H264",4}, … … 251 254 {{" packetization-mode",19}, {"1",1}}, } }, 252 255 }, 253 {254 {PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264_RSV1, {"H264",4},255 {"Baseline (level=30, pack=1)", 27}},256 PJMEDIA_FORMAT_H264, 128000, 1000000,257 &h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen,258 &pjmedia_vid_codec_h264_match_sdp,259 {2, { {{"profile-level-id",16}, {"42001e",6}},260 {{" packetization-mode",19}, {"1",1}}, } },261 },262 256 #endif 257 258 #if PJMEDIA_HAS_FFMPEG_CODEC_H263P 263 259 { 264 260 {PJMEDIA_FORMAT_H263P, PJMEDIA_RTP_PT_H263P, {"H263-1998",9}}, … … 268 264 {{"QCIF",4}, {"1",1}}, } }, 269 265 }, 270 #if 0 271 /* Force plain H263 to use H263-1998 RTP packetization */ 272 { 273 {PJMEDIA_FORMAT_H263, PJMEDIA_RTP_PT_H263, {"H263",4}}, 274 PJMEDIA_FORMAT_H263, 1000000, 2000000, 275 &h263_packetize, &h263_unpacketize, &h263_preopen, NULL, NULL, 276 {2, { {{"CIF",3}, {"1",1}}, 277 {{"QCIF",4}, {"1",1}}, } }, 278 }, 279 #else 266 #endif 267 280 268 { 281 269 {PJMEDIA_FORMAT_H263, PJMEDIA_RTP_PT_H263, {"H263",4}}, 282 270 }, 283 #endif284 271 { 285 272 {PJMEDIA_FORMAT_H261, PJMEDIA_RTP_PT_H261, {"H261",4}}, … … 297 284 }; 298 285 299 #if ENABLE_H264 286 #if PJMEDIA_HAS_FFMPEG_CODEC_H264 287 300 288 typedef struct h264_data 301 289 { … … 354 342 if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 355 343 AVCodecContext *ctx = ff->enc_ctx; 356 357 /* Apply profile. Note that, for x264 backend, ffmpeg doesn't seem to 358 * use this profile param field, so let's try to apply it "manually". 359 */ 344 const char *profile = NULL; 345 346 /* Apply profile. */ 360 347 ctx->profile = data->fmtp.profile_idc; 361 if (ctx->profile == PROFILE_H264_BASELINE) { 362 /* Baseline profile settings (the most used profile in 363 * conversational/real-time communications). 364 */ 365 ctx->coder_type = FF_CODER_TYPE_VLC; 366 ctx->max_b_frames = 0; 367 ctx->flags2 &= ~(CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT); 368 ctx->weighted_p_pred = 0; 369 } else if (ctx->profile == PROFILE_H264_MAIN) { 370 ctx->flags2 &= ~CODEC_FLAG2_8X8DCT; 348 switch (ctx->profile) { 349 case PROFILE_H264_BASELINE: 350 profile = "baseline"; 351 break; 352 case PROFILE_H264_MAIN: 353 profile = "main"; 354 break; 355 default: 356 break; 357 } 358 if (profile && 359 av_set_string3(ctx->priv_data, "profile", profile, 0, NULL)) 360 { 361 PJ_LOG(3, (THIS_FILE, "Failed to set H264 profile")); 371 362 } 372 363 373 364 /* Apply profile constraint bits. */ 374 // The x264 doesn't seem to support non-constrained (baseline) profile375 // so this shouldn't be a problem (for now).376 365 //PJ_TODO(set_h264_constraint_bits_properly_in_ffmpeg); 377 366 if (data->fmtp.profile_iop) { … … 384 373 ctx->level = data->fmtp.level; 385 374 386 /* Libx264 rejects the "broken" ffmpeg defaults, so just change some */ 387 ctx->me_range = 16; 388 ctx->max_qdiff = 4; 389 ctx->qmin = 20; 390 ctx->qmax = 32; 391 ctx->qcompress = 0.6f; 392 393 ctx->rtp_payload_size = ff->param.enc_mtu; 375 /* Limit NAL unit size as we prefer single NAL unit packetization */ 376 if (!av_set_int(ctx->priv_data, "slice-max-size", ff->param.enc_mtu)) 377 { 378 PJ_LOG(3, (THIS_FILE, "Failed to set H264 max NAL size to %d", 379 ff->param.enc_mtu)); 380 } 381 382 /* Apply intra-refresh */ 383 if (!av_set_int(ctx->priv_data, "intra-refresh", 1)) 384 { 385 PJ_LOG(3, (THIS_FILE, "Failed to set x264 intra-refresh")); 386 } 387 388 /* Misc x264 settings (performance, quality, latency, etc). 389 * Let's just use the x264 predefined preset & tune. 390 */ 391 if (av_set_string3(ctx->priv_data, "preset", "veryslow", 0, NULL)) 392 { 393 PJ_LOG(3, (THIS_FILE, "Failed to set x264 preset 'veryfast'")); 394 } 395 if (av_set_string3(ctx->priv_data, "tune", "animation+zerolatency", 396 0, NULL)) 397 { 398 PJ_LOG(3, (THIS_FILE, "Failed to set x264 tune 'zerolatency'")); 399 } 394 400 } 395 401 … … 416 422 } 417 423 418 419 424 static FUNC_PACKETIZE(h264_packetize) 420 425 { … … 430 435 bits, bits_len, bits_pos); 431 436 } 432 #endif /* ENABLE_H264 */ 437 438 #endif /* PJMEDIA_HAS_FFMPEG_CODEC_H264 */ 439 440 441 #if PJMEDIA_HAS_FFMPEG_CODEC_H263P 433 442 434 443 typedef struct h263_data … … 475 484 bits, bits_len, bits_pos); 476 485 } 486 487 #endif /* PJMEDIA_HAS_FFMPEG_CODEC_H263P */ 477 488 478 489 … … 990 1001 } 991 1002 992 static enum PixelFormat dec_get_format(struct AVCodecContext *s,993 const enum PixelFormat * fmt)994 {995 ffmpeg_private *ff = (ffmpeg_private*)s->opaque;996 enum PixelFormat def_fmt = *fmt;997 998 while (*fmt != -1) {999 if (*fmt == ff->expected_dec_fmt)1000 return *fmt;1001 ++fmt;1002 }1003 1004 pj_assert(!"Inconsistency in supported formats");1005 return def_fmt;1006 }1007 1008 1009 1003 static pj_status_t open_ffmpeg_codec(ffmpeg_private *ff, 1010 1004 pj_mutex_t *ff_mutex) … … 1028 1022 /* Allocate ffmpeg codec context */ 1029 1023 if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 1030 ff->enc_ctx = avcodec_alloc_context ();1024 ff->enc_ctx = avcodec_alloc_context3(ff->enc); 1031 1025 if (ff->enc_ctx == NULL) 1032 1026 goto on_error; 1033 1027 } 1034 1028 if (ff->param.dir & PJMEDIA_DIR_DECODING) { 1035 ff->dec_ctx = avcodec_alloc_context ();1029 ff->dec_ctx = avcodec_alloc_context3(ff->dec); 1036 1030 if (ff->dec_ctx == NULL) 1037 1031 goto on_error; 1038 1032 } 1039 1033 1040 /* Let the codec apply specific settings before the codec opened */ 1041 if (ff->desc->preopen) { 1042 status = (*ff->desc->preopen)(ff); 1043 if (status != PJ_SUCCESS) 1044 goto on_error; 1045 } 1046 1034 /* Init generic encoder params */ 1047 1035 if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 1048 1036 AVCodecContext *ctx = ff->enc_ctx; 1049 int err; 1050 1051 /* Init common settings */ 1037 1052 1038 ctx->pix_fmt = pix_fmt; 1053 1039 ctx->width = vfd->size.w; … … 1071 1057 ctx->rc_lookahead = 0; 1072 1058 #endif 1073 1074 /* Open ffmpeg codec */ 1075 pj_mutex_lock(ff_mutex); 1076 err = avcodec_open(ctx, ff->enc); 1059 } 1060 1061 /* Init generic decoder params */ 1062 if (ff->param.dir & PJMEDIA_DIR_DECODING) { 1063 AVCodecContext *ctx = ff->dec_ctx; 1064 1065 /* Width/height may be overriden by ffmpeg after first decoding. */ 1066 ctx->width = ctx->coded_width = ff->param.dec_fmt.det.vid.size.w; 1067 ctx->height = ctx->coded_height = ff->param.dec_fmt.det.vid.size.h; 1068 ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; 1069 ctx->workaround_bugs = FF_BUG_AUTODETECT; 1070 ctx->opaque = ff; 1071 } 1072 1073 /* Init codec override generic params or apply specific params before 1074 * the codec opened. 1075 */ 1076 if (ff->desc->preopen) { 1077 status = (*ff->desc->preopen)(ff); 1078 if (status != PJ_SUCCESS) 1079 goto on_error; 1080 } 1081 1082 /* Open encoder */ 1083 if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 1084 int err; 1085 1086 pj_mutex_lock(ff_mutex); 1087 err = avcodec_open(ff->enc_ctx, ff->enc); 1077 1088 pj_mutex_unlock(ff_mutex); 1078 1089 if (err < 0) { … … 1084 1095 } 1085 1096 1097 /* Open decoder */ 1086 1098 if (ff->param.dir & PJMEDIA_DIR_DECODING) { 1087 AVCodecContext *ctx = ff->dec_ctx;1088 1099 int err; 1089 1100 1090 /* Init common settings */ 1091 /* Width/height may be overriden by ffmpeg after first decoding. */ 1092 ctx->width = ctx->coded_width = ff->param.dec_fmt.det.vid.size.w; 1093 ctx->height = ctx->coded_height = ff->param.dec_fmt.det.vid.size.h; 1094 ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; 1095 ctx->workaround_bugs = FF_BUG_AUTODETECT; 1096 ctx->opaque = ff; 1097 ctx->get_format = &dec_get_format; 1098 1099 /* Open ffmpeg codec */ 1100 pj_mutex_lock(ff_mutex); 1101 err = avcodec_open(ctx, ff->dec); 1101 pj_mutex_lock(ff_mutex); 1102 err = avcodec_open(ff->dec_ctx, ff->dec); 1102 1103 pj_mutex_unlock(ff_mutex); 1103 1104 if (err < 0) { … … 1109 1110 } 1110 1111 1111 /* Let the codec apply specific settings after the codec opened */1112 /* Let the codec apply specific params after the codec opened */ 1112 1113 if (ff->desc->postopen) { 1113 1114 status = (*ff->desc->postopen)(ff); … … 1528 1529 ff->param.dec_fmt.det.vid.size.w = ff->dec_ctx->width; 1529 1530 ff->param.dec_fmt.det.vid.size.h = ff->dec_ctx->height; 1531 ff->expected_dec_fmt = ff->dec_ctx->pix_fmt; 1530 1532 1531 1533 /* Re-init format info and apply-param of decoder */
Note: See TracChangeset
for help on using the changeset viewer.