Ignore:
Timestamp:
Oct 5, 2012 10:04:54 AM (12 years ago)
Author:
ming
Message:

Re #1586: Add support for SILK multiple frames per packet

File:
1 edited

Legend:

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

    r4272 r4278  
    2121#include <pjmedia-codec/silk.h> 
    2222#include <pjmedia/codec.h> 
     23#include <pjmedia/delaybuf.h> 
    2324#include <pjmedia/endpoint.h> 
    2425#include <pjmedia/errno.h> 
     
    3435 
    3536#define THIS_FILE               "silk.c" 
     37 
     38#ifndef PJMEDIA_SILK_DELAY_BUF_OPTIONS 
     39    #define PJMEDIA_SILK_DELAY_BUF_OPTIONS PJMEDIA_DELAY_BUF_SIMPLE_FIFO 
     40#endif 
    3641 
    3742#define FRAME_LENGTH_MS         20 
     
    149154    pj_pool_t   *pool;          /**< Pool for each instance.    */ 
    150155    unsigned     samples_per_frame; 
     156    pj_uint8_t   pcm_bytes_per_sample; 
    151157 
    152158    pj_bool_t    enc_ready; 
     
    157163    SKP_SILK_SDK_DecControlStruct dec_ctl; 
    158164    void        *dec_st; 
     165 
     166    /* Buffer to hold decoded frames. */ 
     167    void        *dec_buf[SILK_MAX_FRAMES_PER_PACKET-1]; 
     168    SKP_int16    dec_buf_size[SILK_MAX_FRAMES_PER_PACKET-1]; 
     169    pj_size_t    dec_buf_sz; 
     170    unsigned     dec_buf_cnt; 
     171    pj_uint32_t  pkt_info;    /**< Packet info for buffered frames.  */ 
    159172} silk_private; 
    160173 
     
    219232    sp->pt = PJMEDIA_RTP_PT_SILK_NB; 
    220233    sp->clock_rate = 8000; 
    221     sp->max_bitrate = 20000; 
     234    sp->max_bitrate = 22000; 
    222235    sp->bitrate = CALC_BITRATE(sp->max_bitrate); 
    223236    sp->ptime = FRAME_LENGTH_MS; 
     
    228241    sp->pt = PJMEDIA_RTP_PT_SILK_MB; 
    229242    sp->clock_rate = 12000; 
    230     sp->max_bitrate = 25000; 
     243    sp->max_bitrate = 28000; 
    231244    sp->bitrate = CALC_BITRATE(sp->max_bitrate); 
    232245    sp->ptime = FRAME_LENGTH_MS; 
     
    237250    sp->pt = PJMEDIA_RTP_PT_SILK_WB; 
    238251    sp->clock_rate = 16000; 
    239     sp->max_bitrate = 30000; 
     252    sp->max_bitrate = 36000; 
    240253    sp->bitrate = CALC_BITRATE(sp->max_bitrate); 
    241254    sp->ptime = FRAME_LENGTH_MS; 
     
    246259    sp->pt = PJMEDIA_RTP_PT_SILK_SWB; 
    247260    sp->clock_rate = 24000; 
    248     sp->max_bitrate = 40000; 
     261    sp->max_bitrate = 46000; 
    249262    sp->bitrate = CALC_BITRATE(sp->max_bitrate); 
    250263    sp->ptime = FRAME_LENGTH_MS; 
     
    597610    silk->samples_per_frame = attr->setting.frm_per_pkt * FRAME_LENGTH_MS * 
    598611                              attr->info.clock_rate / 1000; 
     612    silk->pcm_bytes_per_sample = attr->info.pcm_bits_per_sample / 8; 
    599613 
    600614    silk->enc_ctl.API_sampleRate        = attr->info.clock_rate; 
     
    626640    silk->dec_ctl.framesPerPacket       = 1; /* for proper PLC at start */ 
    627641    silk->dec_ready = PJ_TRUE; 
    628  
    629     /* Increase max_bps (as the bitrate values in the table seems to be 
    630      * rounded down, and without increasing this, frame size of the jitter 
    631      * buffer has been found lower than the actual frame size, which in turn 
    632      * it causes noise as the payloads get trimmed). 
     642    silk->dec_buf_sz = attr->info.clock_rate * attr->info.channel_cnt * 
     643                       attr->info.frm_ptime / 1000 * 
     644                       silk->pcm_bytes_per_sample; 
     645 
     646    /* Inform the stream to prepare a larger buffer since we cannot parse 
     647     * SILK packets and split it into individual frames. 
    633648     */ 
    634     attr->info.max_bps *= 2; 
     649    attr->info.max_rx_frame_size = attr->info.max_bps *  
     650                                   attr->info.frm_ptime / 8 / 1000; 
     651    if ((attr->info.max_bps * attr->info.frm_ptime) % 8000 != 0) 
     652    { 
     653        ++attr->info.max_rx_frame_size; 
     654    } 
     655    attr->info.max_rx_frame_size *= SILK_MAX_FRAMES_PER_PACKET; 
    635656 
    636657    return PJ_SUCCESS; 
     
    722743{ 
    723744    silk_private *silk; 
    724     unsigned count; 
     745    SKP_Silk_TOC_struct toc; 
     746    unsigned i, count; 
    725747 
    726748    PJ_ASSERT_RETURN(codec && ts && frames && frame_cnt, PJ_EINVAL); 
    727749    silk = (silk_private*)codec->codec_data; 
    728750 
    729     PJ_TODO(support_parsing_multiple_frames_per_packet); 
    730  
    731     count = 0; 
    732     frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 
    733     frames[count].buf = pkt; 
    734     frames[count].size = pkt_size; 
    735     frames[count].timestamp.u64 = ts->u64; 
    736     ++count; 
     751    SKP_Silk_SDK_get_TOC(pkt, pkt_size, &toc); 
     752    count = toc.framesInPacket; 
     753    pj_assert(count <= SILK_MAX_FRAMES_PER_PACKET); 
     754 
     755    for (i = 0; i < count; i++) { 
     756        frames[i].type = PJMEDIA_FRAME_TYPE_AUDIO; 
     757        frames[i].bit_info = (((unsigned)ts->u64 & 0xFFFF) << 16) | 
     758                              (((unsigned)pkt & 0xFF) << 8) | i; 
     759        frames[i].buf = pkt; 
     760        frames[i].size = pkt_size; 
     761        frames[i].timestamp.u64 = ts->u64 + i * silk->samples_per_frame; 
     762    } 
    737763 
    738764    *frame_cnt = count; 
    739765    return PJ_SUCCESS; 
    740766} 
    741  
    742767 
    743768static pj_status_t silk_codec_decode(pjmedia_codec *codec, 
     
    748773    silk_private *silk; 
    749774    SKP_int16 out_size; 
    750     SKP_int err; 
     775    SKP_Silk_TOC_struct toc; 
     776    SKP_int err = 0; 
     777    unsigned pkt_info, frm_info; 
    751778 
    752779    PJ_ASSERT_RETURN(codec && input && output_buf_len && output, PJ_EINVAL); 
    753780    silk = (silk_private*)codec->codec_data; 
    754  
    755     out_size = (SKP_int16)output_buf_len; 
    756     err = SKP_Silk_SDK_Decode(silk->dec_st, &silk->dec_ctl, 
    757                               0, /* Normal frame flag */ 
    758                               input->buf, 
    759                               input->size, 
    760                               output->buf, 
    761                               &out_size); 
    762     if (err) { 
    763         PJ_LOG(3, (THIS_FILE, "Failed to decode frame (err=%d)", err)); 
    764         output->type = PJMEDIA_FRAME_TYPE_NONE; 
    765         output->buf = NULL; 
    766         output->size = 0; 
    767         return PJMEDIA_CODEC_EFAILED; 
    768     } 
    769  
    770     output->size = out_size; 
    771     output->type = PJMEDIA_FRAME_TYPE_AUDIO; 
     781    PJ_ASSERT_RETURN(output_buf_len >= silk->dec_buf_sz, PJ_ETOOSMALL); 
     782 
     783    SKP_Silk_SDK_get_TOC(input->buf, input->size, &toc); 
     784    pkt_info = input->bit_info & 0xFFFFFF00; 
     785    frm_info = input->bit_info & 0xF; 
     786 
     787    if (toc.framesInPacket == 0) { 
     788        output->size = 0; 
     789    } else if (silk->pkt_info != pkt_info || input->bit_info == 0) { 
     790        unsigned i; 
     791        SKP_int16 nsamples; 
     792 
     793        silk->pkt_info = pkt_info; 
     794        nsamples = (SKP_int16)silk->dec_buf_sz / silk->pcm_bytes_per_sample; 
     795 
     796        if (toc.framesInPacket-1 > (SKP_int)silk->dec_buf_cnt) { 
     797            /* Grow the buffer */ 
     798            for (i = silk->dec_buf_cnt+1; i < (unsigned)toc.framesInPacket; 
     799                i++) 
     800            { 
     801                silk->dec_buf[i-1] = pj_pool_alloc(silk->pool, 
     802                                                   silk->dec_buf_sz); 
     803            } 
     804            silk->dec_buf_cnt = toc.framesInPacket-1; 
     805        } 
     806 
     807        /* We need to decode all the frames in the packet. */ 
     808        for (i = 0; i < (unsigned)toc.framesInPacket;) { 
     809            void *buf; 
     810            SKP_int16 *size; 
     811 
     812            if (i == 0 || i == frm_info) { 
     813                buf = output->buf; 
     814                size = &out_size; 
     815            } else { 
     816                buf = silk->dec_buf[i-1]; 
     817                size = &silk->dec_buf_size[i-1]; 
     818            } 
     819 
     820            *size = nsamples; 
     821            err = SKP_Silk_SDK_Decode(silk->dec_st, &silk->dec_ctl, 
     822                                      0, /* Normal frame flag */ 
     823                                      input->buf, input->size, 
     824                                      buf, size); 
     825            if (err) { 
     826                PJ_LOG(3, (THIS_FILE, "Failed to decode frame (err=%d)", 
     827                                      err)); 
     828                *size = 0; 
     829            } else { 
     830                *size = *size * silk->pcm_bytes_per_sample; 
     831            } 
     832 
     833            if (i == frm_info) { 
     834                output->size = *size; 
     835            } 
     836 
     837            i++; 
     838            if (!silk->dec_ctl.moreInternalDecoderFrames && 
     839                i < (unsigned)toc.framesInPacket) 
     840            { 
     841                /* It turns out that the packet does not have 
     842                 * the number of frames as mentioned in the TOC. 
     843                 */ 
     844                for (; i < (unsigned)toc.framesInPacket; i++) { 
     845                    silk->dec_buf_size[i-1] = 0; 
     846                    if (i == frm_info) { 
     847                        output->size = 0; 
     848                    } 
     849                } 
     850            } 
     851        } 
     852    } else { 
     853        /* We have already decoded this packet. */ 
     854        if (frm_info == 0 || silk->dec_buf_size[frm_info-1] == 0) { 
     855            /* The decoding was a failure. */ 
     856            output->size = 0; 
     857        } else { 
     858            /* Copy the decoded frame from the buffer. */ 
     859            pj_assert(frm_info-1 < silk->dec_buf_cnt); 
     860            if (frm_info-1 >= silk->dec_buf_cnt) { 
     861                output->size = 0; 
     862            } else { 
     863                pj_memcpy(output->buf, silk->dec_buf[frm_info-1], 
     864                          silk->dec_buf_size[frm_info-1]); 
     865                output->size = silk->dec_buf_size[frm_info-1]; 
     866            } 
     867        } 
     868    } 
     869 
     870    if (output->size == 0) { 
     871        output->type = PJMEDIA_TYPE_NONE; 
     872        output->buf = NULL; 
     873        return PJMEDIA_CODEC_EFAILED; 
     874    } 
     875 
     876    output->type = PJMEDIA_TYPE_AUDIO; 
    772877    output->timestamp = input->timestamp; 
    773878 
     
    780885 */ 
    781886static pj_status_t  silk_codec_recover(pjmedia_codec *codec, 
    782                                       unsigned output_buf_len, 
    783                                       struct pjmedia_frame *output) 
     887                                       unsigned output_buf_len, 
     888                                       struct pjmedia_frame *output) 
    784889{ 
    785890    silk_private *silk; 
     
    790895    silk = (silk_private*)codec->codec_data; 
    791896 
    792     out_size = (SKP_int16)output_buf_len; 
     897    out_size = (SKP_int16)output_buf_len / silk->pcm_bytes_per_sample; 
    793898    err = SKP_Silk_SDK_Decode(silk->dec_st, &silk->dec_ctl, 
    794899                              1, /* Lost frame flag */ 
     
    805910    } 
    806911 
    807     output->size = out_size; 
     912    output->size = out_size * silk->pcm_bytes_per_sample; 
    808913    output->type = PJMEDIA_FRAME_TYPE_AUDIO; 
    809914 
Note: See TracChangeset for help on using the changeset viewer.