- Timestamp:
- Feb 24, 2011 7:47:55 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/2.0-dev/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3392 r3420 28 28 #include <pj/os.h> 29 29 30 30 31 /* 31 32 * Only build this file if PJMEDIA_HAS_FFMPEG_CODEC != 0 … … 38 39 #include <libavcodec/avcodec.h> 39 40 #include <libavformat/avformat.h> 41 #include <libswscale/swscale.h> 40 42 41 43 … … 66 68 static pj_status_t ffmpeg_codec_modify(pjmedia_vid_codec *codec, 67 69 const pjmedia_vid_codec_param *attr ); 70 static pj_status_t ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 71 pjmedia_vid_codec_param *param); 68 72 static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec, 69 73 pj_uint8_t *buf, … … 96 100 &ffmpeg_codec_close, 97 101 &ffmpeg_codec_modify, 102 &ffmpeg_codec_get_param, 98 103 &ffmpeg_packetize, 99 104 &ffmpeg_unpacketize, … … 112 117 &ffmpeg_dealloc_codec 113 118 }; 114 115 116 typedef struct ffmpeg_codec_info {117 PJ_DECL_LIST_MEMBER(struct ffmpeg_codec_info);118 pjmedia_vid_codec_info info;119 AVCodec *enc;120 AVCodec *dec;121 } ffmpeg_codec_info;122 119 123 120 … … 129 126 pj_pool_t *pool; 130 127 pj_mutex_t *mutex; 131 ffmpeg_codec_info codecs;132 128 } ffmpeg_factory; 133 129 130 131 typedef struct ffmpeg_codec_desc ffmpeg_codec_desc; 132 133 /* ITU resolution ID */ 134 typedef enum itu_res_id { 135 ITU_RES_SQCIF, 136 ITU_RES_QCIF, 137 ITU_RES_CIF, 138 ITU_RES_4CIF, 139 ITU_RES_16CIF, 140 ITU_RES_CUSTOM, 141 } itu_res_id; 142 143 /* ITU resolution definition */ 144 struct itu_res { 145 itu_res_id id; 146 pj_str_t name; 147 pjmedia_rect_size size; 148 } itu_res_def [] = 149 { 150 {ITU_RES_16CIF, {"16CIF",5}, {1408,1142}}, 151 {ITU_RES_4CIF, {"4CIF",4}, {704,576}}, 152 {ITU_RES_CIF, {"CIF",3}, {352,288}}, 153 {ITU_RES_QCIF, {"QCIF",4}, {176,144}}, 154 {ITU_RES_SQCIF, {"SQCIF",5}, {88,72}}, 155 {ITU_RES_CUSTOM, {"CUSTOM",6}, {0,0}}, 156 }; 134 157 135 158 /* FFMPEG codecs private data. */ 136 159 typedef struct ffmpeg_private { 160 const ffmpeg_codec_desc *desc; 161 pjmedia_vid_codec_param param; /**< Codec param */ 162 pj_pool_t *pool; /**< Pool for each instance */ 163 pj_timestamp last_tx; /**< Timestamp of last 164 transmit */ 165 166 /* Format info and apply format param */ 167 const pjmedia_video_format_info *enc_vfi; 168 pjmedia_video_apply_fmt_param enc_vafp; 169 const pjmedia_video_format_info *dec_vfi; 170 pjmedia_video_apply_fmt_param dec_vafp; 171 172 /* The ffmpeg codec states. */ 173 AVCodec *enc; 174 AVCodec *dec; 175 AVCodecContext *enc_ctx; 176 AVCodecContext *dec_ctx; 177 178 /* The ffmpeg decoder cannot set the output format, so format conversion 179 * may be needed for post-decoding. 180 */ 181 enum PixelFormat expected_dec_fmt; 182 /**< expected output format of 183 ffmpeg decoder */ 184 struct SwsContext *sws_ctx; /**< the format converter for 185 post decoding */ 186 187 } ffmpeg_private; 188 189 190 typedef pj_status_t (*func_packetize) (pj_uint8_t *buf, 191 pj_size_t buf_len, 192 unsigned *pos, 193 int max_payload_len, 194 const pj_uint8_t **payload, 195 pj_size_t *payload_len); 196 197 typedef pj_status_t (*func_unpacketize) (const pj_uint8_t *payload, 198 pj_size_t payload_len, 199 pj_uint8_t *bits, 200 pj_size_t *bits_len); 201 202 typedef pj_status_t (*func_parse_fmtp) (ffmpeg_private *ff); 203 204 /* FFMPEG codec info */ 205 struct ffmpeg_codec_desc { 206 /* Predefined info */ 207 pjmedia_vid_codec_info info; 208 func_packetize packetize; 209 func_unpacketize unpacketize; 210 func_parse_fmtp parse_fmtp; 211 pjmedia_codec_fmtp dec_fmtp; 212 213 /* Init time defined info */ 214 pj_bool_t enabled; 137 215 AVCodec *enc; 138 216 AVCodec *dec; 139 AVCodecContext *enc_ctx; 140 AVCodecContext *dec_ctx; 141 AVCodecParserContext *dec_parser_ctx; 142 143 /* 144 pjmedia_frame *pack_frms; 145 unsigned pack_frm_cnt; 146 unsigned pack_frm_max_cnt; 147 */ 148 149 pjmedia_vid_codec_param param; /**< Codec param. */ 150 pj_pool_t *pool; /**< Pool for each instance. */ 151 pj_timestamp last_tx; /**< Timestamp of last transmit.*/ 152 const pjmedia_video_format_info *vfi; 153 pjmedia_video_apply_fmt_param vafp; 154 } ffmpeg_private; 217 }; 218 219 /* H263 packetizer */ 220 static pj_status_t h263_packetize(pj_uint8_t *buf, 221 pj_size_t buf_len, 222 unsigned *pos, 223 int max_payload_len, 224 const pj_uint8_t **payload, 225 pj_size_t *payload_len) 226 { 227 return pjmedia_h263_packetize(buf, buf_len, pos, max_payload_len, 228 payload, payload_len); 229 } 230 231 /* H263 unpacketizer */ 232 static pj_status_t h263_unpacketize(const pj_uint8_t *payload, 233 pj_size_t payload_len, 234 pj_uint8_t *bits, 235 pj_size_t *bits_len) 236 { 237 return pjmedia_h263_unpacketize(payload, payload_len, bits, bits_len); 238 } 239 240 /* H263 fmtp parser */ 241 static pj_status_t h263_parse_fmtp(ffmpeg_private *ff); 242 243 244 /* Internal codec info */ 245 ffmpeg_codec_desc codec_desc[] = 246 { 247 { 248 {PJMEDIA_FORMAT_H263, {"H263",4}, PJMEDIA_RTP_PT_H263}, 249 &h263_packetize, &h263_unpacketize, &h263_parse_fmtp, 250 {2, { {{"CIF",3}, {"2",1}}, {{"QCIF",4}, {"1",1}}, } }, 251 }, 252 { 253 {PJMEDIA_FORMAT_H261, {"H261",4}, PJMEDIA_RTP_PT_H261}, 254 }, 255 { 256 {PJMEDIA_FORMAT_MJPEG, {"JPEG",4}, PJMEDIA_RTP_PT_JPEG}, 257 }, 258 }; 259 260 /* Parse fmtp value for custom resolution, e.g: "CUSTOM=800,600,2" */ 261 static pj_status_t parse_fmtp_itu_custom_res(const pj_str_t *fmtp_val, 262 pjmedia_rect_size *size, 263 unsigned *mpi) 264 { 265 const char *p, *p_end; 266 pj_str_t token; 267 unsigned long val[3] = {0}; 268 unsigned i = 0; 269 270 p = token.ptr = fmtp_val->ptr; 271 p_end = p + fmtp_val->slen; 272 273 while (p<=p_end && i<PJ_ARRAY_SIZE(val)) { 274 if (*p==',' || p==p_end) { 275 token.slen = (char*)p - token.ptr; 276 val[i++] = pj_strtoul(&token); 277 token.ptr = (char*)p+1; 278 } 279 ++p; 280 } 281 282 if (!val[0] || !val[1]) 283 return PJ_ETOOSMALL; 284 285 if (val[2]<1 || val[2]>32) 286 return PJ_EINVAL; 287 288 size->w = val[0]; 289 size->h = val[1]; 290 *mpi = val[2]; 291 return PJ_SUCCESS; 292 } 293 294 #define CALC_ITU_CUSTOM_RES_SCORE(size, mpi) ((size)->w * (size)->h / mpi) 295 296 /* ITU codec capabilities */ 297 typedef struct itu_cap 298 { 299 /* Lowest MPI for each non-custom resolution */ 300 unsigned lowest_mpi[PJ_ARRAY_SIZE(itu_res_def)]; 301 /* For custom resolution, we use maximum processing score */ 302 unsigned custom_res_max_score; 303 } itu_cap; 304 305 306 static pj_status_t load_itu_cap(const pjmedia_codec_fmtp *fmtp, 307 itu_cap *cap) 308 { 309 unsigned i, j; 310 unsigned min_mpi = 0; 311 312 /* Get Minimum Picture Interval (MPI) for each resolution. If a resolution 313 * has no MPI setting in fmtp, the MPI setting is derived from the higher 314 * resolution. 315 */ 316 for (i=0; i<PJ_ARRAY_SIZE(itu_res_def); ++i) { 317 318 /* Init lowest MPI */ 319 cap->lowest_mpi[i] = min_mpi? min_mpi:1; 320 321 for (j=0; j<fmtp->cnt; ++j) { 322 if (pj_stricmp(&fmtp->param[j].name, &itu_res_def[i].name)==0) { 323 pjmedia_rect_size size; 324 unsigned mpi; 325 unsigned score; 326 327 if (i != ITU_RES_CUSTOM) { 328 size = itu_res_def[i].size; 329 mpi = pj_strtoul(&fmtp->param[j].val); 330 if (min_mpi) 331 min_mpi = PJ_MIN(mpi, min_mpi); 332 else 333 min_mpi = mpi; 334 335 /* Update the lowest MPI for this resolution */ 336 cap->lowest_mpi[i] = min_mpi; 337 338 /* Also update the processing score for the custom 339 * resolution. 340 */ 341 score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 342 cap->custom_res_max_score = 343 PJ_MAX(score, cap->custom_res_max_score); 344 } else { 345 346 347 if (parse_fmtp_itu_custom_res(&fmtp->param[j].val, 348 &size, &mpi) == PJ_SUCCESS) 349 { 350 score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 351 cap->custom_res_max_score = 352 PJ_MAX(score, cap->custom_res_max_score); 353 } 354 } 355 } 356 } 357 } 358 359 return PJ_SUCCESS; 360 } 361 362 /* H263 fmtp parser */ 363 static pj_status_t h263_parse_fmtp(ffmpeg_private *ff) 364 { 365 pjmedia_dir dir; 366 pj_status_t status; 367 368 dir = ff->param.dir; 369 370 if (ff->param.dir & PJMEDIA_DIR_ENCODING) { 371 pjmedia_vid_codec_param param_ref; 372 pjmedia_codec_fmtp *fmtp_rem, *fmtp_ref; 373 itu_cap local_cap; 374 pjmedia_rect_size size = {0}; 375 unsigned mpi = 0; 376 pj_bool_t got_good_res = PJ_FALSE; 377 pj_bool_t has_prefered_res = PJ_FALSE; 378 unsigned i, j; 379 380 fmtp_rem = &ff->param.enc_fmtp; 381 dir &= ~PJMEDIA_DIR_ENCODING; 382 383 /* Get default fmtp setting as the reference for local capabilities */ 384 status = pjmedia_vid_codec_mgr_get_default_param( 385 ffmpeg_factory.mgr, &ff->desc->info, ¶m_ref); 386 fmtp_ref = (status==PJ_SUCCESS)? ¶m_ref.enc_fmtp : fmtp_rem; 387 388 /* Load default local capabilities */ 389 status = load_itu_cap(fmtp_ref, &local_cap); 390 pj_assert(status == PJ_SUCCESS); 391 392 /* Negotiate resolution and MPI */ 393 for (i=0; i<fmtp_rem->cnt && !got_good_res; ++i) 394 { 395 for (j=0; j<PJ_ARRAY_SIZE(itu_res_def) && !got_good_res; ++j) 396 { 397 if (pj_stricmp(&fmtp_rem->param[i].name, &itu_res_def[j].name)) 398 continue; 399 400 has_prefered_res = PJ_TRUE; 401 if (j == ITU_RES_CUSTOM) { 402 unsigned score; 403 404 if (parse_fmtp_itu_custom_res(&fmtp_rem->param[i].val, 405 &size, &mpi) != PJ_SUCCESS) 406 { 407 /* Invalid custom resolution format, skip this 408 * custom resolution 409 */ 410 break; 411 } 412 413 score = CALC_ITU_CUSTOM_RES_SCORE(&size, mpi); 414 if (score <= local_cap.custom_res_max_score) 415 got_good_res = PJ_TRUE; 416 } else { 417 mpi = pj_strtoul(&fmtp_rem->param[i].val); 418 if (mpi>=1 && mpi<=32 && mpi>=local_cap.lowest_mpi[j]) { 419 got_good_res = PJ_TRUE; 420 size = itu_res_def[j].size; 421 } 422 } 423 } 424 } 425 426 if (has_prefered_res) { 427 if (got_good_res) { 428 pjmedia_video_format_detail *vfd; 429 430 /* Apply this size & MPI */ 431 vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 432 PJ_TRUE); 433 vfd->size = size; 434 vfd->fps.num = 30000; 435 vfd->fps.denum = 1001 * mpi; 436 got_good_res = PJ_TRUE; 437 438 PJ_TODO(NOTIFY_APP_ABOUT_THIS_NEW_ENCODING_FORMAT); 439 } else { 440 return PJ_EUNKNOWN; 441 } 442 } 443 } 444 445 return PJ_SUCCESS; 446 } 447 448 449 450 static const ffmpeg_codec_desc* find_codec_info( 451 const pjmedia_vid_codec_info *info) 452 { 453 int i; 454 455 for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) { 456 ffmpeg_codec_desc *desc = &codec_desc[i]; 457 458 if (desc->enabled && 459 (desc->info.fmt_id == info->fmt_id) && 460 ((desc->info.dir & info->dir) == info->dir) && 461 pj_stricmp(&desc->info.encoding_name, &info->encoding_name)==0) 462 { 463 return desc; 464 } 465 } 466 467 return NULL; 468 } 469 470 471 static int find_codec_info_idx_by_fmt_id(pjmedia_format_id fmt_id) 472 { 473 int i; 474 for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) { 475 if (codec_desc[i].info.fmt_id == fmt_id) 476 return i; 477 } 478 479 return -1; 480 } 155 481 156 482 … … 163 489 pj_pool_t *pool; 164 490 AVCodec *c; 165 enum CodecID last_codec_id = CODEC_ID_NONE;166 491 pj_status_t status; 167 492 … … 179 504 ffmpeg_factory.mgr = mgr; 180 505 ffmpeg_factory.pf = pf; 181 pj_list_init(&ffmpeg_factory.codecs);182 506 183 507 pool = pj_pool_create(pf, "ffmpeg codec factory", 256, 256, NULL); … … 197 521 for (c=av_codec_next(NULL); c; c=av_codec_next(c)) 198 522 { 199 ffmpeg_codec_info *ci; 523 ffmpeg_codec_desc *desc; 524 pjmedia_format_id fmt_id; 525 int codec_info_idx; 200 526 201 527 if (c->type != CODEC_TYPE_VIDEO) … … 203 529 204 530 /* Video encoder and decoder are usually implemented in separate 205 * AVCodec instances. 531 * AVCodec instances. While the codec attributes (e.g: raw formats, 532 * supported fps) are in the encoder. 206 533 */ 207 534 208 if (c->id == last_codec_id) { 209 /* This codec usually be the decoder, and not as much info as in 210 * encoder can be fetched here. 211 */ 212 pj_assert(!pj_list_empty(&ffmpeg_factory.codecs)); 213 ci = ffmpeg_factory.codecs.prev; 214 pj_assert(ci->info.dir != PJMEDIA_DIR_ENCODING_DECODING); 215 pj_assert(!ci->dec || !ci->enc); 216 } else { 217 pjmedia_format_id enc_fmt_id; 218 pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; 219 unsigned raw_fmt_cnt = 0; 220 unsigned raw_fmt_cnt_should_be = 0; 221 222 /* Get encoded format id */ 223 status = CodecID_to_pjmedia_format_id(c->id, &enc_fmt_id); 224 if (status != PJ_SUCCESS) { 225 //PJ_LOG(5, (THIS_FILE, "Unrecognized ffmpeg codec id %d, " 226 // "codec [%s/%s] ignored", 227 // c->id, c->name, c->long_name)); 228 //enc_fmt_id = PJMEDIA_FORMAT_FFMPEG_UNKNOWN; 229 230 /* Skip unrecognized encoding format ID */ 231 continue; 232 } 233 234 /* Get raw/decoded format ids */ 235 if (c->pix_fmts) { 236 const enum PixelFormat *p = c->pix_fmts; 237 for(;(p && *p != -1) && 238 (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT); 239 ++p) 240 { 241 pjmedia_format_id fmt_id; 242 243 raw_fmt_cnt_should_be++; 244 status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id); 245 if (status != PJ_SUCCESS) { 246 PJ_LOG(6, (THIS_FILE, "Unrecognized ffmpeg pixel " 247 "format %d", *p)); 248 continue; 249 } 250 raw_fmt[raw_fmt_cnt++] = fmt_id; 251 } 252 } else { 253 /* Unknown raw format, ignore this codec? */ 254 continue; 255 } 256 257 if (raw_fmt_cnt < raw_fmt_cnt_should_be) { 258 PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, " 259 "recognized only %d raw formats", 260 c->name, c->long_name, 261 raw_fmt_cnt_should_be, raw_fmt_cnt)); 262 } 263 if (raw_fmt_cnt == 0) { 264 PJ_LOG(5, (THIS_FILE, "No recognized raw format " 265 "for codec [%s/%s], codec ignored", 266 c->name, c->long_name)); 267 /* Comment this to see all ffmpeg codecs */ 268 continue; 269 } 270 271 ci = PJ_POOL_ZALLOC_T(pool, ffmpeg_codec_info); 272 ci->info.fmt_id = enc_fmt_id; 273 pj_cstr(&ci->info.encoding_name, c->name); 274 ci->info.clock_rate = 90000; 275 ci->info.dec_fmt_id_cnt = raw_fmt_cnt; 276 pj_memcpy(ci->info.dec_fmt_id, raw_fmt, 277 sizeof(raw_fmt[0])*raw_fmt_cnt); 278 279 switch (enc_fmt_id) { 280 case PJMEDIA_FORMAT_H263: 281 ci->info.pt = PJMEDIA_RTP_PT_H263; 282 break; 283 case PJMEDIA_FORMAT_H261: 284 ci->info.pt = PJMEDIA_RTP_PT_H261; 285 break; 286 default: 287 break; 288 } 289 290 if (c->supported_framerates) { 291 const AVRational *fr = c->supported_framerates; 292 while ((fr->num != 0 || fr->den != 0) && 293 ci->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT) 294 { 295 ci->info.fps[ci->info.fps_cnt].num = fr->num; 296 ci->info.fps[ci->info.fps_cnt].denum = fr->den; 297 ++ci->info.fps_cnt; 298 ++fr; 299 } 300 } 301 302 pj_list_push_back(&ffmpeg_factory.codecs, ci); 535 status = CodecID_to_pjmedia_format_id(c->id, &fmt_id); 536 /* Skip if format ID is unknown */ 537 if (status != PJ_SUCCESS) 538 continue; 539 540 codec_info_idx = find_codec_info_idx_by_fmt_id(fmt_id); 541 /* Skip if codec is unwanted by this wrapper (not listed in 542 * the codec info array) 543 */ 544 if (codec_info_idx < 0) 545 continue; 546 547 desc = &codec_desc[codec_info_idx]; 548 549 /* Skip duplicated codec implementation */ 550 if ((c->encode && (desc->info.dir & PJMEDIA_DIR_ENCODING)) || 551 (c->decode && (desc->info.dir & PJMEDIA_DIR_DECODING))) 552 { 553 continue; 554 } 555 556 /* Get raw/decoded format ids in the encoder */ 557 if (c->pix_fmts && c->encode) { 558 pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT]; 559 unsigned raw_fmt_cnt = 0; 560 unsigned raw_fmt_cnt_should_be = 0; 561 const enum PixelFormat *p = c->pix_fmts; 562 563 for(;(p && *p != -1) && 564 (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT); 565 ++p) 566 { 567 pjmedia_format_id fmt_id; 568 569 raw_fmt_cnt_should_be++; 570 status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id); 571 if (status != PJ_SUCCESS) { 572 PJ_LOG(6, (THIS_FILE, "Unrecognized ffmpeg pixel " 573 "format %d", *p)); 574 continue; 575 } 576 raw_fmt[raw_fmt_cnt++] = fmt_id; 577 } 578 579 if (raw_fmt_cnt == 0) { 580 PJ_LOG(5, (THIS_FILE, "No recognized raw format " 581 "for codec [%s/%s], codec ignored", 582 c->name, c->long_name)); 583 /* Skip this encoder */ 584 continue; 585 } 586 587 if (raw_fmt_cnt < raw_fmt_cnt_should_be) { 588 PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, " 589 "recognized only %d raw formats", 590 c->name, c->long_name, 591 raw_fmt_cnt_should_be, raw_fmt_cnt)); 592 } 593 594 desc->info.dec_fmt_id_cnt = raw_fmt_cnt; 595 pj_memcpy(desc->info.dec_fmt_id, raw_fmt, 596 sizeof(raw_fmt[0])*raw_fmt_cnt); 597 } 598 599 /* Get supported framerates */ 600 if (c->supported_framerates) { 601 const AVRational *fr = c->supported_framerates; 602 while ((fr->num != 0 || fr->den != 0) && 603 desc->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT) 604 { 605 desc->info.fps[desc->info.fps_cnt].num = fr->num; 606 desc->info.fps[desc->info.fps_cnt].denum = fr->den; 607 ++desc->info.fps_cnt; 608 ++fr; 609 } 610 } 611 612 /* Get ffmpeg encoder instance */ 613 if (c->encode && !desc->enc) { 614 desc->info.dir |= PJMEDIA_DIR_ENCODING; 615 desc->enc = c; 303 616 } 304 305 if (c->encode) { 306 ci->info.dir |= PJMEDIA_DIR_ENCODING; 307 ci->enc = c; 617 618 /* Get ffmpeg decoder instance */ 619 if (c->decode && !desc->dec) { 620 desc->info.dir |= PJMEDIA_DIR_DECODING; 621 desc->dec = c; 308 622 } 309 if (c->decode) { 310 ci->info.dir |= PJMEDIA_DIR_DECODING; 311 ci->dec = c; 312 } 313 314 last_codec_id = c->id; 623 624 /* Enable this codec when any ffmpeg codec instance are recognized 625 * and the supported raw formats info has been collected. 626 */ 627 if ((desc->dec || desc->enc) && desc->info.dec_fmt_id_cnt) 628 { 629 desc->enabled = PJ_TRUE; 630 } 631 632 /* Normalize default value of clock rate */ 633 if (desc->info.clock_rate == 0) 634 desc->info.clock_rate = 90000; 315 635 } 316 636 … … 360 680 361 681 362 static ffmpeg_codec_info* find_codec(const pjmedia_vid_codec_info *info)363 {364 ffmpeg_codec_info *ci = ffmpeg_factory.codecs.next;365 366 pj_mutex_lock(ffmpeg_factory.mutex);367 368 while (ci != &ffmpeg_factory.codecs) {369 if ((ci->info.fmt_id == info->fmt_id) &&370 ((ci->info.dir & info->dir) == info->dir) &&371 pj_stricmp(&ci->info.encoding_name, &info->encoding_name)==0)372 {373 pj_mutex_unlock(ffmpeg_factory.mutex);374 return ci;375 }376 ci = ci->next;377 }378 379 pj_mutex_unlock(ffmpeg_factory.mutex);380 381 return NULL;382 }383 384 385 682 /* 386 683 * Check if factory can allocate the specified codec. … … 389 686 const pjmedia_vid_codec_info *info ) 390 687 { 391 ffmpeg_codec_info *ci;688 const ffmpeg_codec_desc *desc; 392 689 393 690 PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); 394 691 PJ_ASSERT_RETURN(info, PJ_EINVAL); 395 692 396 ci = find_codec(info);397 if (! ci) {693 desc = find_codec_info(info); 694 if (!desc) { 398 695 return PJMEDIA_CODEC_EUNSUP; 399 696 } … … 409 706 pjmedia_vid_codec_param *attr ) 410 707 { 411 ffmpeg_codec_info *ci;708 const ffmpeg_codec_desc *desc; 412 709 413 710 PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); 414 711 PJ_ASSERT_RETURN(info && attr, PJ_EINVAL); 415 712 416 ci = find_codec(info);417 if (! ci) {713 desc = find_codec_info(info); 714 if (!desc) { 418 715 return PJMEDIA_CODEC_EUNSUP; 419 716 } 420 717 421 718 pj_bzero(attr, sizeof(pjmedia_vid_codec_param)); 422 attr->dir = ci->info.dir; 423 attr->pt = info->pt; 424 pjmedia_format_init_video(&attr->enc_fmt, ci->info.fmt_id, 425 352, 288, 25, 1); 426 pjmedia_format_init_video(&attr->dec_fmt, ci->info.dec_fmt_id[0], 427 352, 288, 25, 1); 719 720 /* Direction */ 721 attr->dir = desc->info.dir; 722 723 /* Encoded format */ 724 pjmedia_format_init_video(&attr->enc_fmt, desc->info.fmt_id, 725 352, 288, 30000, 1001); 726 727 /* Decoded format */ 728 pjmedia_format_init_video(&attr->dec_fmt, desc->info.dec_fmt_id[0], 729 352, 288, 30000, 1001); 730 731 /* Decoding fmtp */ 732 attr->dec_fmtp = desc->dec_fmtp; 428 733 429 734 return PJ_SUCCESS; … … 437 742 pjmedia_vid_codec_info codecs[]) 438 743 { 439 ffmpeg_codec_info *ci; 440 unsigned max; 744 unsigned i; 441 745 442 746 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL); 443 747 PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL); 444 748 445 max = *count; 446 *count = 0; 447 ci = ffmpeg_factory.codecs.next; 448 449 pj_mutex_lock(ffmpeg_factory.mutex); 450 while (*count < max && ci != &ffmpeg_factory.codecs) { 451 pj_memcpy(&codecs[*count], &ci->info, sizeof(pjmedia_vid_codec_info)); 452 *count = *count + 1; 453 ci = ci->next; 454 } 455 pj_mutex_unlock(ffmpeg_factory.mutex); 749 *count = PJ_MIN(*count, PJ_ARRAY_SIZE(codec_desc)); 750 751 for (i=0; i<*count; ++i) { 752 pj_memcpy(&codecs[i], &codec_desc[i].info, 753 sizeof(pjmedia_vid_codec_info)); 754 } 456 755 457 756 return PJ_SUCCESS; … … 466 765 { 467 766 ffmpeg_private *ff; 468 ffmpeg_codec_info *ci;767 const ffmpeg_codec_desc *desc; 469 768 pjmedia_vid_codec *codec; 470 769 pj_pool_t *pool = NULL; … … 474 773 PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL); 475 774 476 ci = find_codec(info);477 if (! ci) {775 desc = find_codec_info(info); 776 if (!desc) { 478 777 return PJMEDIA_CODEC_EUNSUP; 479 778 } … … 495 794 codec->codec_data = ff; 496 795 ff->pool = pool; 497 ff->enc = ci->enc; 498 ff->dec = ci->dec; 796 ff->enc = desc->enc; 797 ff->dec = desc->dec; 798 ff->desc = desc; 499 799 500 800 *p_codec = codec; … … 551 851 } 552 852 553 /* 554 static enum PixelFormat ffdec_nego_format(struct AVCodecContext *s, 853 static enum PixelFormat dec_get_format(struct AVCodecContext *s, 555 854 const enum PixelFormat * fmt) 556 855 { 557 enum PixelFormat pix_fmt;558 559 PJ_UNUSED_ARG(s); 560 PJ_UNUSED_ARG(fmt);561 562 pjmedia_format_id_to_PixelFormat(PJMEDIA_FORMAT_BGRA, &pix_fmt);563 return pix_fmt;564 }565 566 static void enc_got_payload(struct AVCodecContext *avctx, 567 void *data, int size, int mb_nb);568 */ 856 ffmpeg_private *ff = (ffmpeg_private*)s->opaque; 857 enum PixelFormat def_fmt = *fmt; 858 859 while (*fmt != -1) { 860 if (*fmt == ff->expected_dec_fmt) 861 return *fmt; 862 ++fmt; 863 } 864 865 pj_assert(!"Inconsistency in supported formats"); 866 return def_fmt; 867 } 569 868 570 869 … … 574 873 enum PixelFormat pix_fmt; 575 874 pj_status_t status; 875 pjmedia_video_format_detail *vfd; 576 876 577 877 status = pjmedia_format_id_to_PixelFormat(ff->param.dec_fmt.id, … … 579 879 if (status != PJ_SUCCESS) 580 880 return status; 881 882 vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 883 PJ_TRUE); 884 ff->expected_dec_fmt = pix_fmt; 581 885 582 886 while (((ff->param.dir & PJMEDIA_DIR_ENCODING) && ff->enc_ctx == NULL) || … … 595 899 } 596 900 901 /* Init ffmpeg codec context */ 597 902 ctx = avcodec_alloc_context(); 598 903 599 904 /* Common attributes */ 600 905 ctx->pix_fmt = pix_fmt; 601 ctx->width = ff->param.enc_fmt.det.vid.size.w;602 ctx->height = ff->param.enc_fmt.det.vid.size.h;603 906 ctx->workaround_bugs = FF_BUG_AUTODETECT; 604 907 ctx->opaque = ff; … … 608 911 609 912 /* Encoding only attributes */ 610 ctx->time_base.num = ff->param.enc_fmt.det.vid.fps.denum; 611 ctx->time_base.den = ff->param.enc_fmt.det.vid.fps.num; 612 if (ff->param.enc_fmt.det.vid.avg_bps) 613 ctx->bit_rate = ff->param.enc_fmt.det.vid.avg_bps; 614 if (ff->param.enc_fmt.det.vid.max_bps) 615 ctx->rc_max_rate = ff->param.enc_fmt.det.vid.max_bps; 616 #if 0 617 if (ff->param.enc_mtu) { 618 //ctx->rtp_payload_size = ff->param.enc_mtu; 619 //ctx->rtp_callback = &enc_got_payload; 620 621 /* Allocate frame array for RTP payload packing */ 622 if (ff->param.enc_fmt.det.vid.max_bps) 623 ff->pack_frm_max_cnt = ff->param.enc_fmt.det.vid.max_bps / 624 ff->param.enc_mtu + 1; 625 else 626 ff->pack_frm_max_cnt = 32; 627 628 ff->pack_frms = (pjmedia_frame*) 629 pj_pool_calloc(ff->pool, ff->pack_frm_max_cnt, 630 sizeof(ff->pack_frms[0])); 631 } 632 #endif 633 634 /* For encoder, should be better to be strict to the standards */ 913 ctx->width = vfd->size.w; 914 ctx->height = vfd->size.h; 915 ctx->time_base.num = vfd->fps.denum; 916 ctx->time_base.den = vfd->fps.num; 917 if (vfd->avg_bps) 918 ctx->bit_rate = vfd->avg_bps; 919 if (vfd->max_bps) 920 ctx->rc_max_rate = vfd->max_bps; 921 922 /* For encoder, should be better to be strict to the standards */ 635 923 ctx->strict_std_compliance = FF_COMPLIANCE_STRICT; 636 924 } 925 637 926 if (dir & PJMEDIA_DIR_DECODING) { 638 927 codec = ff->dec; 639 928 640 929 /* Decoding only attributes */ 641 ctx->coded_width = ctx->width; 642 ctx->coded_height = ctx->height; 930 // this setting will be automatically fetched from the bitstream. 931 //ctx->coded_width = ff->param.dec_fmt.det.vid.size.w; 932 //ctx->coded_height = ff->param.dec_fmt.det.vid.size.h; 643 933 644 934 /* For decoder, be more flexible */ 645 if (ff->param.dir!=PJMEDIA_DIR_ENCODING_DECODING || ff->enc!=ff->dec) 935 if (ff->param.dir!=PJMEDIA_DIR_ENCODING_DECODING || 936 ff->enc!=ff->dec) 937 { 646 938 ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; 647 648 //ctx->get_format = &ffdec_nego_format; 939 } 940 941 ctx->get_format = &dec_get_format; 649 942 } 650 943 … … 680 973 ff = (ffmpeg_private*)codec->codec_data; 681 974 682 ff->vfi = pjmedia_get_video_format_info(NULL, attr->dec_fmt.id);683 if (!ff->vfi) {684 status = PJ_EINVAL;685 goto on_error;686 }687 688 pj_bzero(&ff->vafp, sizeof(ff->vafp));689 ff->vafp.size = attr->dec_fmt.det.vid.size;690 ff->vafp.buffer = 0;691 status = (*ff->vfi->apply_fmt)(ff->vfi, &ff->vafp);692 if (status != PJ_SUCCESS) {693 goto on_error;694 }695 696 975 pj_memcpy(&ff->param, attr, sizeof(*attr)); 697 976 977 /* Apply SDP fmtp attribute */ 978 if (ff->desc->parse_fmtp) { 979 status = (*ff->desc->parse_fmtp)(ff); 980 if (status != PJ_SUCCESS) 981 goto on_error; 982 } 983 984 /* Open the codec */ 698 985 ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex; 699 986 status = open_ffmpeg_codec(ff, ff_mutex); … … 701 988 goto on_error; 702 989 990 /* Init format info and apply-param of decoder */ 991 ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 992 if (!ff->dec_vfi) { 993 status = PJ_EINVAL; 994 goto on_error; 995 } 996 pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp)); 997 ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size; 998 ff->dec_vafp.buffer = NULL; 999 status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp); 1000 if (status != PJ_SUCCESS) { 1001 goto on_error; 1002 } 1003 1004 /* Init format info and apply-param of encoder */ 1005 ff->enc_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 1006 if (!ff->enc_vfi) { 1007 status = PJ_EINVAL; 1008 goto on_error; 1009 } 1010 pj_bzero(&ff->enc_vafp, sizeof(ff->enc_vafp)); 1011 ff->enc_vafp.size = ff->param.enc_fmt.det.vid.size; 1012 ff->enc_vafp.buffer = NULL; 1013 status = (*ff->enc_vfi->apply_fmt)(ff->enc_vfi, &ff->enc_vafp); 1014 if (status != PJ_SUCCESS) { 1015 goto on_error; 1016 } 1017 1018 /* Update codec attributes, e.g: encoding format may be changed by 1019 * SDP fmtp negotiation. 1020 */ 1021 pj_memcpy(attr, &ff->param, sizeof(*attr)); 1022 703 1023 return PJ_SUCCESS; 704 1024 … … 729 1049 av_free(ff->dec_ctx); 730 1050 } 731 if (ff->dec_parser_ctx) { 732 av_parser_close(ff->dec_parser_ctx); 733 1051 if (ff->sws_ctx) { 1052 sws_freeContext(ff->sws_ctx); 734 1053 } 735 1054 ff->enc_ctx = NULL; 736 1055 ff->dec_ctx = NULL; 737 ff-> dec_parser_ctx = NULL;1056 ff->sws_ctx = NULL; 738 1057 pj_mutex_unlock(ff_mutex); 739 1058 … … 746 1065 */ 747 1066 static pj_status_t ffmpeg_codec_modify( pjmedia_vid_codec *codec, 748 const pjmedia_vid_codec_param *attr 1067 const pjmedia_vid_codec_param *attr) 749 1068 { 750 1069 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 755 1074 return PJ_ENOTSUP; 756 1075 } 1076 1077 static pj_status_t ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 1078 pjmedia_vid_codec_param *param) 1079 { 1080 ffmpeg_private *ff; 1081 1082 PJ_ASSERT_RETURN(codec && param, PJ_EINVAL); 1083 1084 ff = (ffmpeg_private*)codec->codec_data; 1085 pj_memcpy(param, &ff->param, sizeof(*param)); 1086 1087 return PJ_SUCCESS; 1088 } 1089 757 1090 758 1091 static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec, … … 765 1098 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 766 1099 767 switch (ff->param.enc_fmt.id) { 768 case PJMEDIA_FORMAT_H263: 769 return pjmedia_h263_packetize(buf, buf_len, pos, 770 ff->param.enc_mtu, payload, 771 payload_len); 772 break; 773 default: 774 return PJ_ENOTSUP; 775 } 1100 if (ff->desc->packetize) { 1101 return (*ff->desc->packetize)(buf, buf_len, pos, 1102 ff->param.enc_mtu, payload, 1103 payload_len); 1104 } 1105 1106 return PJ_ENOTSUP; 776 1107 } 777 1108 … … 784 1115 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 785 1116 786 switch (ff->param.enc_fmt.id) { 787 case PJMEDIA_FORMAT_H263: 788 return pjmedia_h263_unpacketize(payload, payload_len, 789 buf, buf_len); 790 break; 791 default: 792 return PJ_ENOTSUP; 793 } 794 } 795 796 #if 0 797 /* 798 * Pack encoded frame to RTP payload frames. 799 */ 800 static pj_status_t ffmpeg_codec_pack ( pjmedia_vid_codec *codec, 801 const pjmedia_frame *enc_frame, 802 unsigned *frame_cnt, 803 pjmedia_frame frames[]) 804 { 805 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 806 unsigned i; 807 808 /* Can only work when encoding MTU is set */ 809 PJ_ASSERT_RETURN(ff->param.enc_mtu, PJ_EINVALIDOP); 810 811 /* Validate available payload number */ 812 PJ_ASSERT_RETURN(ff->pack_frm_cnt <= *frame_cnt, PJ_EINVALIDOP); 813 814 /* Validate encoded bitstream */ 815 PJ_ASSERT_RETURN(ff->pack_frm_cnt==0 || 816 ff->pack_frms[0].buf == enc_frame->buf, 817 PJ_EINVAL); 818 819 /* Return the payloads */ 820 *frame_cnt = ff->pack_frm_cnt; 821 for (i = 0; i < *frame_cnt; ++i) 822 frames[i] = ff->pack_frms[i]; 823 824 return PJ_SUCCESS; 825 } 826 827 /* 828 * Get frames in the packet. 829 */ 830 static pj_status_t ffmpeg_codec_parse( pjmedia_vid_codec *codec, 831 void *pkt, 832 pj_size_t pkt_size, 833 const pj_timestamp *ts, 834 pjmedia_frame *frame) 835 { 836 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 837 pj_uint8_t *buf = frame->buf; 838 int buf_size = frame->size; 839 int processed; 840 841 842 if (!ff->dec_parser_ctx) { 843 ff->dec_parser_ctx = av_parser_init(ff->dec->id); 844 if (!ff->dec_parser_ctx) 845 return PJ_ENOTSUP; 846 } 847 848 #if LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72 849 processed = av_parser_parse2(ff->dec_parser_ctx, ff->dec_ctx, 850 &buf, &buf_size, (uint8_t*)pkt, pkt_size, 851 ts->u64, ts->u64, AV_NOPTS_VALUE); 852 #else 853 processed = av_parser_parse (ff->dec_parser_ctx, ff->dec_ctx, 854 &buf, &buf_size, (uint8_t*)pkt, pkt_size, 855 ts->u64, ts->u64); 856 #endif 857 858 if (buf_size) { 859 frame->timestamp = *ts; 860 frame->size = buf_size; 861 return PJ_SUCCESS; 862 } 863 864 return PJ_EPENDING; 865 } 866 867 static void enc_got_payload(struct AVCodecContext *avctx, 868 void *data, int size, int mb_nb) 869 { 870 ffmpeg_private *ff = (ffmpeg_private*) avctx->opaque; 871 pjmedia_frame *payload; 872 873 pj_assert(ff->pack_frm_cnt < ff->pack_frm_max_cnt); 874 payload = &ff->pack_frms[ff->pack_frm_cnt++]; 875 payload->buf = data; 876 payload->size = size; 877 payload->bit_info = mb_nb; 878 } 879 880 #endif 1117 if (ff->desc->unpacketize) { 1118 return (*ff->desc->unpacketize)(payload, payload_len, 1119 buf, buf_len); 1120 } 1121 1122 return PJ_ENOTSUP; 1123 } 881 1124 882 1125 … … 885 1128 */ 886 1129 static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec, 887 const structpjmedia_frame *input,1130 const pjmedia_frame *input, 888 1131 unsigned output_buf_len, 889 structpjmedia_frame *output)1132 pjmedia_frame *output) 890 1133 { 891 1134 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 900 1143 PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP); 901 1144 902 /*903 ff->pack_frm_cnt = 0;904 */905 1145 avcodec_get_frame_defaults(&avframe); 906 1146 907 for (i = 0; i < ff-> vfi->plane_cnt; ++i) {1147 for (i = 0; i < ff->enc_vfi->plane_cnt; ++i) { 908 1148 avframe.data[i] = p; 909 avframe.linesize[i] = ff-> vafp.strides[i];910 p += ff-> vafp.plane_bytes[i];1149 avframe.linesize[i] = ff->enc_vafp.strides[i]; 1150 p += ff->enc_vafp.plane_bytes[i]; 911 1151 } 912 1152 … … 946 1186 */ 947 1187 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec, 948 const structpjmedia_frame *input,1188 const pjmedia_frame *input, 949 1189 unsigned output_buf_len, 950 structpjmedia_frame *output)1190 pjmedia_frame *output) 951 1191 { 952 1192 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 958 1198 PJ_ASSERT_RETURN(ff->dec_ctx, PJ_EINVALIDOP); 959 1199 960 PJ_UNUSED_ARG(output_buf_len); 1200 /* Validate output buffer size */ 1201 PJ_ASSERT_RETURN(ff->dec_vafp.framebytes <= output_buf_len, PJ_ETOOSMALL); 961 1202 962 1203 /* Init frame to receive the decoded data, the ffmpeg codec context will … … 979 1220 */ 980 1221 pj_bzero(avpacket.data+avpacket.size, FF_INPUT_BUFFER_PADDING_SIZE); 1222 1223 output->bit_info = 0; 981 1224 982 1225 #if LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72 … … 997 1240 return PJ_EUNKNOWN; 998 1241 } else if (got_picture) { 999 pjmedia_video_apply_fmt_param *vafp = (pjmedia_video_apply_fmt_param*) 1000 &ff->vafp; 1242 pjmedia_video_apply_fmt_param *vafp = &ff->dec_vafp; 1001 1243 pj_uint8_t *q = (pj_uint8_t*)output->buf; 1002 unsigned i; 1003 1004 /* Get the decoded data */ 1005 for (i = 0; i < ff->vfi->plane_cnt; ++i) { 1006 pj_uint8_t *p = avframe.data[i]; 1007 1008 /* The decoded data may contain padding */ 1009 if (avframe.linesize[i]==vafp->strides[i]) { 1010 /* No padding, copy the whole plane */ 1011 pj_memcpy(q, p, vafp->plane_bytes[i]); 1012 q += vafp->plane_bytes[i]; 1013 } else { 1014 /* Padding exists, copy line by line */ 1015 pj_uint8_t *q_end; 1016 1017 q_end = q+vafp->plane_bytes[i]; 1018 while(q < q_end) { 1019 pj_memcpy(q, p, vafp->strides[i]); 1020 q += vafp->strides[i]; 1021 p += avframe.linesize[i]; 1022 } 1023 } 1024 } 1244 unsigned i; 1245 1246 /* Decoder output format is set by libavcodec, in case it is different 1247 * to the configured param. 1248 */ 1249 if (ff->dec_ctx->pix_fmt != ff->expected_dec_fmt || 1250 ff->dec_ctx->coded_width != (int)vafp->size.w || 1251 ff->dec_ctx->coded_height != (int)vafp->size.h) 1252 { 1253 #if 0 1254 // it should not be the codec responsibility to do resizing 1255 pj_uint8_t *data[PJMEDIA_MAX_VIDEO_PLANES] = {0}; 1256 unsigned i; 1257 int h; 1258 1259 if (!ff->sws_ctx) { 1260 pj_assert(sws_isSupportedInput(ff->dec_ctx->pix_fmt) > 0); 1261 pj_assert(sws_isSupportedOutput(ff->expected_dec_fmt) > 0); 1262 ff->sws_ctx = sws_getContext(ff->dec_ctx->coded_width, 1263 ff->dec_ctx->coded_height, 1264 ff->dec_ctx->pix_fmt, 1265 vafp->size.w, vafp->size.h, 1266 ff->expected_dec_fmt, 1267 SWS_BILINEAR | SWS_PRINT_INFO, 1268 NULL, NULL, NULL); 1269 if (ff->sws_ctx == NULL) { 1270 return PJ_EUNKNOWN; 1271 } 1272 } 1273 1274 for (i = 0; i < ff->vfi->plane_cnt; ++i) { 1275 data[i] = q; 1276 q += vafp->plane_bytes[i]; 1277 } 1278 h = sws_scale(ff->sws_ctx, avframe.data, avframe.linesize, 0, 1279 ff->dec_ctx->coded_height, data, vafp->strides); 1280 pj_assert((int)vafp->size.h == h); 1281 #endif 1282 1283 pjmedia_format_id new_fmt_id; 1284 pj_status_t status; 1285 1286 /* Get current raw format id from ffmpeg decoder context */ 1287 status = PixelFormat_to_pjmedia_format_id(ff->dec_ctx->pix_fmt, 1288 &new_fmt_id); 1289 if (status != PJ_SUCCESS) 1290 return status; 1291 1292 /* Update decoder format in param */ 1293 ff->param.dec_fmt.id = new_fmt_id; 1294 ff->param.dec_fmt.det.vid.size.w = ff->dec_ctx->coded_width; 1295 ff->param.dec_fmt.det.vid.size.h = ff->dec_ctx->coded_height; 1296 1297 /* Re-init format info and apply-param of decoder */ 1298 ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id); 1299 if (!ff->dec_vfi) 1300 return PJ_EUNKNOWN; 1301 pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp)); 1302 ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size; 1303 ff->dec_vafp.buffer = NULL; 1304 status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp); 1305 if (status != PJ_SUCCESS) 1306 return status; 1307 1308 /* Notify application via the bit_info field of pjmedia_frame */ 1309 output->bit_info = PJMEDIA_VID_CODEC_EVENT_FMT_CHANGED; 1310 } 1311 1312 /* Check provided buffer size after format changed */ 1313 if (vafp->framebytes > output_buf_len) 1314 return PJ_ETOOSMALL; 1315 1316 /* Get the decoded data */ 1317 for (i = 0; i < ff->dec_vfi->plane_cnt; ++i) { 1318 pj_uint8_t *p = avframe.data[i]; 1319 1320 /* The decoded data may contain padding */ 1321 if (avframe.linesize[i]!=vafp->strides[i]) { 1322 /* Padding exists, copy line by line */ 1323 pj_uint8_t *q_end; 1324 1325 q_end = q+vafp->plane_bytes[i]; 1326 while(q < q_end) { 1327 pj_memcpy(q, p, vafp->strides[i]); 1328 q += vafp->strides[i]; 1329 p += avframe.linesize[i]; 1330 } 1331 } else { 1332 /* No padding, copy the whole plane */ 1333 pj_memcpy(q, p, vafp->plane_bytes[i]); 1334 q += vafp->plane_bytes[i]; 1335 } 1336 } 1337 1025 1338 output->size = vafp->framebytes; 1026 1339 } else { … … 1036 1349 static pj_status_t ffmpeg_codec_recover( pjmedia_vid_codec *codec, 1037 1350 unsigned output_buf_len, 1038 struct pjmedia_frame *output) 1039 { 1040 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1041 1351 pjmedia_frame *output) 1352 { 1353 PJ_UNUSED_ARG(codec); 1042 1354 PJ_UNUSED_ARG(output_buf_len); 1043 1355 PJ_UNUSED_ARG(output); 1044 PJ_UNUSED_ARG(ff); 1045 1046 return PJ_SUCCESS; 1356 1357 return PJ_ENOTSUP; 1047 1358 } 1048 1359 1049 1360 #ifdef _MSC_VER 1050 1361 # pragma comment( lib, "avcodec.lib") 1362 # pragma comment( lib, "swscale.lib") 1051 1363 #endif 1052 1364
Note: See TracChangeset
for help on using the changeset viewer.