Ignore:
Timestamp:
Sep 29, 2011 8:31:15 AM (13 years ago)
Author:
bennylp
Message:

Closed #1361: codec API change. Details:

  • changed encode(), packetize(), unpacketize(), and decode() to encode_begin(), encode_more(), and decode()
  • codec has new "packing" setting
  • updated stream, aviplay, codec-test, and stream-util due to above
  • minor doxygen documentation fixes here and there
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-codec/ffmpeg_codecs.c

    r3734 r3776  
    7171static pj_status_t  ffmpeg_codec_get_param(pjmedia_vid_codec *codec, 
    7272                                           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); 
     73static 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); 
     78static 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); 
     82static 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); 
    9387 
    9488/* Definition for FFMPEG codecs operations. */ 
     
    10094    &ffmpeg_codec_modify, 
    10195    &ffmpeg_codec_get_param, 
    102     &ffmpeg_packetize, 
    103     &ffmpeg_unpacketize, 
    104     &ffmpeg_codec_encode, 
     96    &ffmpeg_codec_encode_begin, 
     97    &ffmpeg_codec_encode_more, 
    10598    &ffmpeg_codec_decode, 
    10699    NULL 
     
    145138    const pjmedia_video_format_info *dec_vfi; 
    146139    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; 
    147149 
    148150    /* The ffmpeg codec states. */ 
     
    236238 
    237239/* Internal codec info */ 
    238 ffmpeg_codec_desc codec_desc[] = 
     240static ffmpeg_codec_desc codec_desc[] = 
    239241{ 
    240242#if ENABLE_H264 
     
    478480            (desc->info.fmt_id == info->fmt_id) && 
    479481            ((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)) 
    481484        { 
    482485            return desc; 
     
    540543 
    541544    /* 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)) { 
    544546        ffmpeg_codec_desc *desc; 
    545547        pjmedia_format_id fmt_id; 
     
    659661            desc->info.clock_rate = 90000; 
    660662 
    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 
    664668    } 
    665669 
     
    707711            desc->info.dir |= copied_dir; 
    708712            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; 
    711718 
    712719            if (copied_dir != PJMEDIA_DIR_NONE) { 
     
    802809{ 
    803810    const ffmpeg_codec_desc *desc; 
     811    unsigned i; 
    804812 
    805813    PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL); 
     
    812820 
    813821    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    } 
    814836 
    815837    /* Direction */ 
     
    11531175    } 
    11541176 
     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 
    11551187    /* Update codec attributes, e.g: encoding format may be changed by 
    11561188     * SDP fmtp negotiation. 
     
    12601292 * Encode frames. 
    12611293 */ 
    1262 static pj_status_t ffmpeg_codec_encode( pjmedia_vid_codec *codec,  
    1263                                         const pjmedia_frame *input, 
    1264                                         unsigned output_buf_len,  
    1265                                         pjmedia_frame *output) 
     1294static 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) 
    12661298{ 
    12671299    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
     
    13121344} 
    13131345 
     1346static 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 
     1393static 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 
    13141429/* 
    13151430 * Decode frame. 
    13161431 */ 
    1317 static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec,  
    1318                                         const pjmedia_frame *input, 
    1319                                         unsigned output_buf_len,  
    1320                                         pjmedia_frame *output) 
     1432static 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) 
    13211436{ 
    13221437    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data; 
     
    14171532                return status; 
    14181533 
     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 
    14191543            /* Broadcast event */ 
    14201544            if (pjmedia_event_publisher_has_sub(&codec->epub)) { 
     
    14761600} 
    14771601 
     1602static 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 
    14781646 
    14791647#ifdef _MSC_VER 
Note: See TracChangeset for help on using the changeset viewer.