- Timestamp:
- Sep 29, 2011 8:31:15 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c
r3734 r3776 71 71 static pj_status_t ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 72 72 pjmedia_vid_codec_param *param); 73 static pj_status_t ffmpeg_packetize ( pjmedia_vid_codec *codec, 74 pj_uint8_t *buf, 75 pj_size_t buf_len, 76 unsigned *pos, 77 const pj_uint8_t **payload, 78 pj_size_t *payload_len); 79 static pj_status_t ffmpeg_unpacketize(pjmedia_vid_codec *codec, 80 const pj_uint8_t *payload, 81 pj_size_t payload_len, 82 pj_uint8_t *buf, 83 pj_size_t buf_len, 84 unsigned *pos); 85 static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec, 86 const pjmedia_frame *input, 87 unsigned output_buf_len, 88 pjmedia_frame *output); 89 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec, 90 const pjmedia_frame *input, 91 unsigned output_buf_len, 92 pjmedia_frame *output); 73 static pj_status_t ffmpeg_codec_encode_begin( pjmedia_vid_codec *codec, 74 const pjmedia_frame *input, 75 unsigned out_size, 76 pjmedia_frame *output, 77 pj_bool_t *has_more); 78 static pj_status_t ffmpeg_codec_encode_more(pjmedia_vid_codec *codec, 79 unsigned out_size, 80 pjmedia_frame *output, 81 pj_bool_t *has_more); 82 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec, 83 pj_size_t pkt_count, 84 pjmedia_frame packets[], 85 unsigned out_size, 86 pjmedia_frame *output); 93 87 94 88 /* Definition for FFMPEG codecs operations. */ … … 100 94 &ffmpeg_codec_modify, 101 95 &ffmpeg_codec_get_param, 102 &ffmpeg_packetize, 103 &ffmpeg_unpacketize, 104 &ffmpeg_codec_encode, 96 &ffmpeg_codec_encode_begin, 97 &ffmpeg_codec_encode_more, 105 98 &ffmpeg_codec_decode, 106 99 NULL … … 145 138 const pjmedia_video_format_info *dec_vfi; 146 139 pjmedia_video_apply_fmt_param dec_vafp; 140 141 /* Buffers, only needed for multi-packets */ 142 pj_bool_t whole; 143 void *enc_buf; 144 unsigned enc_buf_size; 145 unsigned enc_frame_len; 146 unsigned enc_processed; 147 void *dec_buf; 148 unsigned dec_buf_size; 147 149 148 150 /* The ffmpeg codec states. */ … … 236 238 237 239 /* Internal codec info */ 238 ffmpeg_codec_desc codec_desc[] =240 static ffmpeg_codec_desc codec_desc[] = 239 241 { 240 242 #if ENABLE_H264 … … 478 480 (desc->info.fmt_id == info->fmt_id) && 479 481 ((desc->info.dir & info->dir) == info->dir) && 480 (desc->info.pt == info->pt)) 482 (desc->info.pt == info->pt) && 483 (desc->info.packings & info->packings)) 481 484 { 482 485 return desc; … … 540 543 541 544 /* Enum FFMPEG codecs */ 542 for (c=av_codec_next(NULL); c; c=av_codec_next(c)) 543 { 545 for (c=av_codec_next(NULL); c; c=av_codec_next(c)) { 544 546 ffmpeg_codec_desc *desc; 545 547 pjmedia_format_id fmt_id; … … 659 661 desc->info.clock_rate = 90000; 660 662 661 /* Set RTP packetization support flag in the codec info */ 662 desc->info.has_rtp_pack = (desc->packetize != NULL) && 663 (desc->unpacketize != NULL); 663 /* Set supported packings */ 664 desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE; 665 if (desc->packetize && desc->unpacketize) 666 desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS; 667 664 668 } 665 669 … … 707 711 desc->info.dir |= copied_dir; 708 712 desc->enabled = (desc->info.dir != PJMEDIA_DIR_NONE); 709 desc->info.has_rtp_pack = (desc->packetize != NULL) && 710 (desc->unpacketize != NULL); 713 714 /* Set supported packings */ 715 desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE; 716 if (desc->packetize && desc->unpacketize) 717 desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS; 711 718 712 719 if (copied_dir != PJMEDIA_DIR_NONE) { … … 802 809 { 803 810 const ffmpeg_codec_desc *desc; 811 unsigned i; 804 812 805 813 PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); … … 812 820 813 821 pj_bzero(attr, sizeof(pjmedia_vid_codec_param)); 822 823 /* Scan the requested packings and use the lowest number */ 824 attr->packing = 0; 825 for (i=0; i<15; ++i) { 826 unsigned packing = (1 << i); 827 if ((desc->info.packings & info->packings) & packing) { 828 attr->packing = (pjmedia_vid_packing)packing; 829 break; 830 } 831 } 832 if (attr->packing == 0) { 833 /* No supported packing in info */ 834 return PJMEDIA_CODEC_EUNSUP; 835 } 814 836 815 837 /* Direction */ … … 1153 1175 } 1154 1176 1177 /* Alloc buffers if needed */ 1178 ff->whole = (ff->param.packing == PJMEDIA_VID_PACKING_WHOLE); 1179 if (!ff->whole) { 1180 ff->enc_buf_size = ff->enc_vafp.framebytes; 1181 ff->enc_buf = pj_pool_alloc(ff->pool, ff->enc_buf_size); 1182 1183 ff->dec_buf_size = ff->dec_vafp.framebytes; 1184 ff->dec_buf = pj_pool_alloc(ff->pool, ff->dec_buf_size); 1185 } 1186 1155 1187 /* Update codec attributes, e.g: encoding format may be changed by 1156 1188 * SDP fmtp negotiation. … … 1260 1292 * Encode frames. 1261 1293 */ 1262 static pj_status_t ffmpeg_codec_encode ( pjmedia_vid_codec *codec,1263 1264 unsigned output_buf_len,1265 1294 static pj_status_t ffmpeg_codec_encode_whole(pjmedia_vid_codec *codec, 1295 const pjmedia_frame *input, 1296 unsigned output_buf_len, 1297 pjmedia_frame *output) 1266 1298 { 1267 1299 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 1312 1344 } 1313 1345 1346 static pj_status_t ffmpeg_codec_encode_begin( pjmedia_vid_codec *codec, 1347 const pjmedia_frame *input, 1348 unsigned out_size, 1349 pjmedia_frame *output, 1350 pj_bool_t *has_more) 1351 { 1352 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1353 pj_status_t status; 1354 1355 *has_more = PJ_FALSE; 1356 1357 if (ff->whole) { 1358 status = ffmpeg_codec_encode_whole(codec, input, out_size, output); 1359 } else { 1360 pjmedia_frame whole_frm; 1361 const pj_uint8_t *payload; 1362 pj_size_t payload_len; 1363 1364 pj_bzero(&whole_frm, sizeof(whole_frm)); 1365 whole_frm.buf = ff->enc_buf; 1366 whole_frm.size = ff->enc_buf_size; 1367 status = ffmpeg_codec_encode_whole(codec, input, 1368 whole_frm.size, &whole_frm); 1369 if (status != PJ_SUCCESS) 1370 return status; 1371 1372 ff->enc_frame_len = (unsigned)whole_frm.size; 1373 ff->enc_processed = 0; 1374 status = ffmpeg_packetize(codec, (pj_uint8_t*)whole_frm.buf, 1375 whole_frm.size, &ff->enc_processed, 1376 &payload, &payload_len); 1377 if (status != PJ_SUCCESS) 1378 return status; 1379 1380 if (out_size < payload_len) 1381 return PJMEDIA_CODEC_EFRMTOOSHORT; 1382 1383 output->type = PJMEDIA_FRAME_TYPE_VIDEO; 1384 pj_memcpy(output->buf, payload, payload_len); 1385 output->size = payload_len; 1386 1387 *has_more = (ff->enc_processed < ff->enc_frame_len); 1388 } 1389 1390 return status; 1391 } 1392 1393 static pj_status_t ffmpeg_codec_encode_more(pjmedia_vid_codec *codec, 1394 unsigned out_size, 1395 pjmedia_frame *output, 1396 pj_bool_t *has_more) 1397 { 1398 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1399 const pj_uint8_t *payload; 1400 pj_size_t payload_len; 1401 pj_status_t status; 1402 1403 *has_more = PJ_FALSE; 1404 1405 if (ff->enc_processed >= ff->enc_frame_len) { 1406 /* No more frame */ 1407 return PJ_EEOF; 1408 } 1409 1410 status = ffmpeg_packetize(codec, (pj_uint8_t*)ff->enc_buf, 1411 ff->enc_frame_len, &ff->enc_processed, 1412 &payload, &payload_len); 1413 if (status != PJ_SUCCESS) 1414 return status; 1415 1416 if (out_size < payload_len) 1417 return PJMEDIA_CODEC_EFRMTOOSHORT; 1418 1419 output->type = PJMEDIA_FRAME_TYPE_VIDEO; 1420 pj_memcpy(output->buf, payload, payload_len); 1421 output->size = payload_len; 1422 1423 *has_more = (ff->enc_processed < ff->enc_frame_len); 1424 1425 return PJ_SUCCESS; 1426 } 1427 1428 1314 1429 /* 1315 1430 * Decode frame. 1316 1431 */ 1317 static pj_status_t ffmpeg_codec_decode ( pjmedia_vid_codec *codec,1318 1319 unsigned output_buf_len,1320 1432 static pj_status_t ffmpeg_codec_decode_whole(pjmedia_vid_codec *codec, 1433 const pjmedia_frame *input, 1434 unsigned output_buf_len, 1435 pjmedia_frame *output) 1321 1436 { 1322 1437 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; … … 1417 1532 return status; 1418 1533 1534 /* Realloc buffer if necessary */ 1535 if (ff->dec_vafp.framebytes > ff->dec_buf_size) { 1536 PJ_LOG(5,(THIS_FILE, "Reallocating decoding buffer %u --> %u", 1537 (unsigned)ff->dec_buf_size, 1538 (unsigned)ff->dec_vafp.framebytes)); 1539 ff->dec_buf_size = ff->dec_vafp.framebytes; 1540 ff->dec_buf = pj_pool_alloc(ff->pool, ff->dec_buf_size); 1541 } 1542 1419 1543 /* Broadcast event */ 1420 1544 if (pjmedia_event_publisher_has_sub(&codec->epub)) { … … 1476 1600 } 1477 1601 1602 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec, 1603 pj_size_t pkt_count, 1604 pjmedia_frame packets[], 1605 unsigned out_size, 1606 pjmedia_frame *output) 1607 { 1608 ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 1609 pj_status_t status; 1610 1611 PJ_ASSERT_RETURN(codec && pkt_count > 0 && packets && output, 1612 PJ_EINVAL); 1613 1614 if (ff->whole) { 1615 pj_assert(pkt_count==1); 1616 return ffmpeg_codec_decode_whole(codec, &packets[0], out_size, output); 1617 } else { 1618 pjmedia_frame whole_frm; 1619 unsigned whole_len = 0; 1620 unsigned i; 1621 1622 for (i=0; i<pkt_count; ++i) { 1623 if (whole_len + packets[i].size > ff->dec_buf_size) { 1624 PJ_LOG(5,(THIS_FILE, "Decoding buffer overflow")); 1625 break; 1626 } 1627 1628 status = ffmpeg_unpacketize(codec, packets[i].buf, packets[i].size, 1629 ff->dec_buf, ff->dec_buf_size, 1630 &whole_len); 1631 if (status != PJ_SUCCESS) { 1632 PJ_PERROR(5,(THIS_FILE, status, "Unpacketize error")); 1633 continue; 1634 } 1635 } 1636 1637 whole_frm.buf = ff->dec_buf; 1638 whole_frm.size = whole_len; 1639 whole_frm.timestamp = output->timestamp = packets[i].timestamp; 1640 whole_frm.bit_info = 0; 1641 1642 return ffmpeg_codec_decode_whole(codec, &whole_frm, out_size, output); 1643 } 1644 } 1645 1478 1646 1479 1647 #ifdef _MSC_VER
Note: See TracChangeset
for help on using the changeset viewer.