[FFmpeg-soc] G723.1 Frame Parser

Stefano Sabatini stefano.sabatini-lala at poste.it
Wed Mar 31 01:55:18 CEST 2010


On date Tuesday 2010-03-30 17:46:43 +0530, Mohamed Naufal encoded:
> Hi
> 
> Here is the code for a frame parser i wrote for the g723.1 codec as my GSoC
> qualification task
> 
> #include <stdint.h>
> #include "libavutil/intreadwrite.h"
> 
> #include "avcodec.h"
> #include "get_bits.h"
> 
> #define PITCH_MIN            18
> #define FRM_LEN              240
> #define SFRM_LEN             (FRM_LEN/4)
> #define AD_CB_SIZE_HIGH_RATE 85         ///< 85 entry codebook for Frame6k3s
> #define AD_CB_SIZE_LOW_RATE  170        ///< 170 entry codebook for
> Frame5k3s
> 
> /*
>  *  G723.1 frame types
>  */
> typedef enum {
>     Frame6k3,           ///< 6.3 kbps frame rate
>     Frame5k3,           ///< 5.3 kbps frame rate
>     FrameSID,            ///< silence insertion descriptor frame
>     FrameUntransmitted

vertical align
> } FrameType;
> 
> typedef enum {
>     Rate6k3,
>     Rate5k3
> } Rate;
> 
> /*
>  *  G723.1 unpacked data subframe
>  */
> typedef struct {
>     uint16_t ad_cb_lag;     ///< adaptive codebook lag
>     uint16_t pitch_lag;
>     uint16_t combined_gain;
>     uint16_t pulse_pos;
>     uint16_t pulse_sign;
>     uint16_t grid_index;
>     uint16_t amp_index;     ///< for SID frames
> } G723_1_Subframe;
> 
> /*
>  *  G723.1 unpacked data frame
>  */
> typedef struct {
>     uint32_t lsp_index;
>     G723_1_Subframe subframe[4];
> } G723_1_Frame;
> 
> typedef struct g723_1_context {
>     G723_1_Frame frame;
>     FrameType cur_frame_type;
>     Rate cur_rate;
>     int is_bad_frame;
> } G723_1_Context;
> 
> /*
>  * Unpack the frame into parameters

nit: Unpacks ... missing final dot.

>  *
>  * @param p           the context
>  * @param buf         pointer to the input buffer
>  * @param buf_size    size of the input buffer
>  */
> static void unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
>                                        int buf_size)
> {
>     GetBitContext gb;
>     G723_1_Frame *frame = &p->frame;
>     uint32_t temp;
> 
>     init_get_bits(&gb, buf, buf_size * 8);
> 
>     // Extract frame type and rate info
>     p->cur_frame_type = get_bits(&gb, 2);
> 
>     if (p->cur_frame_type == FrameUntransmitted)
>         return;
> 
>     frame->lsp_index = get_bits(&gb, 24);
> 
>     if (p->cur_frame_type == FrameSID) {
>         frame->subframe[0].amp_index = get_bits(&gb, 6);
>         return;
>     }
> 
>     // Extract the info common to both rates
>     p->cur_rate = (p->cur_frame_type == 0) ? Rate6k3 : Rate5k3;
> 
>     temp = get_bits(&gb, 7);
>     if (temp <= 123) {       // test if forbidden code
>         frame->subframe[0].pitch_lag = temp + PITCH_MIN;
>     }else {
>         p->is_bad_frame  = 1; // transmission error
>         return;
>     }
> 
>     frame->subframe[1].ad_cb_lag  = get_bits(&gb, 2);
> 
>     temp = get_bits(&gb, 7);
>     if (temp <= 123) {
>         frame->subframe[1].pitch_lag = temp + PITCH_MIN;
>     }else {

nit++: } else {

here and below.

>         p->is_bad_frame = 1;
>         return;
>     }
> 
>     frame->subframe[3].ad_cb_lag  = get_bits(&gb, 2);
> 
>     frame->subframe[0].ad_cb_lag  = 1;
>     frame->subframe[2].ad_cb_lag  = 1;
> 
>     frame->subframe[0].combined_gain = get_bits(&gb, 12);
>     frame->subframe[1].combined_gain = get_bits(&gb, 12);
>     frame->subframe[2].combined_gain = get_bits(&gb, 12);
>     frame->subframe[3].combined_gain = get_bits(&gb, 12);
> 
>     frame->subframe[0].grid_index = get_bits(&gb, 1);
>     frame->subframe[1].grid_index = get_bits(&gb, 1);
>     frame->subframe[2].grid_index = get_bits(&gb, 1);
>     frame->subframe[3].grid_index = get_bits(&gb, 1);
> 
>     if (p->cur_frame_type == Frame6k3) {
>         skip_bits(&gb, 1);  // skip reserved bit
> 
>         // Compute pulse_pos index using the 13bit combined position index
>         temp = get_bits(&gb, 13);
>         frame->subframe[0].pulse_pos = (temp / 90) / 9;
>         frame->subframe[1].pulse_pos = (temp / 90) % 9;
>         frame->subframe[2].pulse_pos = (temp % 90) / 9;
>         frame->subframe[3].pulse_pos = (temp % 90) % 9;
> 
>         frame->subframe[0].pulse_pos = (frame->subframe[0].pulse_pos << 16)
> +
>                                        get_bits(&gb, 16);
>         frame->subframe[1].pulse_pos = (frame->subframe[1].pulse_pos << 14)
> +
>                                        get_bits(&gb, 14);
>         frame->subframe[2].pulse_pos = (frame->subframe[2].pulse_pos << 16)
> +
>                                        get_bits(&gb, 16);
>         frame->subframe[3].pulse_pos = (frame->subframe[3].pulse_pos << 14)
> +
>                                        get_bits(&gb, 14);
> 
>         frame->subframe[0].pulse_sign = get_bits(&gb, 6);
>         frame->subframe[1].pulse_sign = get_bits(&gb, 5);
>         frame->subframe[2].pulse_sign = get_bits(&gb, 6);
>         frame->subframe[3].pulse_sign = get_bits(&gb, 5);
>     }else { // Frame5k3
>         frame->subframe[0].pulse_pos  = get_bits(&gb, 12);
>         frame->subframe[1].pulse_pos  = get_bits(&gb, 12);
>         frame->subframe[2].pulse_pos  = get_bits(&gb, 12);
>         frame->subframe[3].pulse_pos  = get_bits(&gb, 12);
> 
>         frame->subframe[0].pulse_sign = get_bits(&gb, 4);
>         frame->subframe[1].pulse_sign = get_bits(&gb, 4);
>         frame->subframe[2].pulse_sign = get_bits(&gb, 4);
>         frame->subframe[3].pulse_sign = get_bits(&gb, 4);
>     }
> }
> 
> static int g723_1_parse_frame(AVCodecContext *avctx, void *data,
>                                int *data_size, AVPacket *avpkt)
> {
>     G723_1_Context *p  = avctx->priv_data;
>     const uint8_t *buf = avpkt->data;
>     int buf_size       = avpkt->size;
> 
>     unpack_bitstream(p, buf, buf_size);
> 
>     if (p->is_bad_frame) {
>         av_log_error(avctx, AV_LOG_ERROR, "Bad frame\n");
>         return AVERROR_INVALIDDATA;
>     }
> 
>     return 0;
> }
> 
> AVCodec g723_1_decoder = {
>     .name           = "g723_1",
>     .type           = CODEC_TYPE_AUDIO,

AVMEDIA_TYPE_AUDIO

>     .id             = CODEC_ID_G723_1,
>     .priv_data_size = sizeof(G723_1_Context),
>     .decode         = g723_1_parse_frame,
>     .long_name      = NULL_IF_CONFIG_SMALL("G.723.1"),
> };

Regards.


More information about the FFmpeg-soc mailing list