⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avc2avi.c.svn-base

📁 H.264 source codes
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
                return -1;        }    }    return 0;}/***************************************************************************** * h264_parser_*: *****************************************************************************/void h264_parser_init( h264_t *h ){    h->i_width = 0;    h->i_height = 0;    h->b_key = 0;    h->i_nal_type = -1;    h->i_ref_idc = -1;    h->i_idr_pic_id = -1;    h->i_frame_num = -1;    h->i_log2_max_frame_num = 0;    h->i_poc = -1;    h->i_poc_type = -1;}void h264_parser_parse( h264_t *h, nal_t *nal, int *pb_nal_start ){    bs_t s;    *pb_nal_start = 0;    if( nal->i_type == NAL_SPS || nal->i_type == NAL_PPS )        *pb_nal_start = 1;    bs_init( &s, nal->p_payload, nal->i_payload );    if( nal->i_type == NAL_SPS )    {        int i_tmp;        bs_skip( &s, 8 + 1+1+1 + 5 + 8 );        /* sps id */        bs_read_ue( &s );        /* Skip i_log2_max_frame_num */        h->i_log2_max_frame_num = bs_read_ue( &s ) + 4;        /* Read poc_type */        h->i_poc_type = bs_read_ue( &s );        if( h->i_poc_type == 0 )        {            h->i_log2_max_poc_lsb = bs_read_ue( &s ) + 4;        }        else if( h->i_poc_type == 1 )        {            int i_cycle;            /* skip b_delta_pic_order_always_zero */            bs_skip( &s, 1 );            /* skip i_offset_for_non_ref_pic */            bs_read_se( &s );            /* skip i_offset_for_top_to_bottom_field */            bs_read_se( &s );            /* read i_num_ref_frames_in_poc_cycle */            i_cycle = bs_read_ue( &s );             if( i_cycle > 256 ) i_cycle = 256;            while( i_cycle > 0 )            {                /* skip i_offset_for_ref_frame */                bs_read_se(&s );            }        }        /* i_num_ref_frames */        bs_read_ue( &s );        /* b_gaps_in_frame_num_value_allowed */        bs_skip( &s, 1 );        /* Read size */        h->i_width  = 16 * ( bs_read_ue( &s ) + 1 );        h->i_height = 16 * ( bs_read_ue( &s ) + 1 );        /* b_frame_mbs_only */        i_tmp = bs_read( &s, 1 );        if( i_tmp == 0 )        {            bs_skip( &s, 1 );        }        /* b_direct8x8_inference */        bs_skip( &s, 1 );        /* crop ? */        i_tmp = bs_read( &s, 1 );        if( i_tmp )        {            /* left */            h->i_width -= 2 * bs_read_ue( &s );            /* right */            h->i_width -= 2 * bs_read_ue( &s );            /* top */            h->i_height -= 2 * bs_read_ue( &s );            /* bottom */            h->i_height -= 2 * bs_read_ue( &s );        }        /* vui: ignored */    }    else if( nal->i_type >= NAL_SLICE && nal->i_type <= NAL_SLICE_IDR )    {        int i_tmp;        /* i_first_mb */        bs_read_ue( &s );        /* picture type */        switch( bs_read_ue( &s ) )        {            case 0: case 5: /* P */            case 1: case 6: /* B */            case 3: case 8: /* SP */                h->b_key = 0;                break;            case 2: case 7: /* I */            case 4: case 9: /* SI */                h->b_key = (nal->i_type == NAL_SLICE_IDR);                break;        }        /* pps id */        bs_read_ue( &s );        /* frame num */        i_tmp = bs_read( &s, h->i_log2_max_frame_num );        if( i_tmp != h->i_frame_num )            *pb_nal_start = 1;        h->i_frame_num = i_tmp;        if( nal->i_type == NAL_SLICE_IDR )        {            i_tmp = bs_read_ue( &s );            if( h->i_nal_type == NAL_SLICE_IDR && h->i_idr_pic_id != i_tmp )                *pb_nal_start = 1;            h->i_idr_pic_id = i_tmp;        }        if( h->i_poc_type == 0 )        {            i_tmp = bs_read( &s, h->i_log2_max_poc_lsb );            if( i_tmp != h->i_poc )                *pb_nal_start = 1;            h->i_poc = i_tmp;        }    }    h->i_nal_type = nal->i_type;    h->i_ref_idc = nal->i_ref_idc;}static int  ParseNAL( nal_t *nal, avi_t *a, h264_t *h, int *pb_slice ){    int b_flush = 0;    int b_start;    h264_parser_parse( h, nal, &b_start );    if( b_start && *pb_slice )    {        b_flush = 1;        *pb_slice = 0;    }    if( nal->i_type >= NAL_SLICE && nal->i_type <= NAL_SLICE_IDR )        *pb_slice = 1;    return b_flush;}/***************************************************************************** * vbuf: variable buffer *****************************************************************************/void vbuf_init( vbuf_t *v ){    v->i_data = 0;    v->i_data_max = 10000;    v->p_data = malloc( v->i_data_max );}void vbuf_add( vbuf_t *v, int i_data, void *p_data ){    if( i_data + v->i_data >= v->i_data_max )    {        v->i_data_max += i_data;        v->p_data = realloc( v->p_data, v->i_data_max );    }    memcpy( &v->p_data[v->i_data], p_data, i_data );    v->i_data += i_data;}void vbuf_reset( vbuf_t *v ){    v->i_data = 0;}/***************************************************************************** * avi: *****************************************************************************/void avi_write_uint16( avi_t *a, uint16_t w ){    fputc( ( w      ) & 0xff, a->f );    fputc( ( w >> 8 ) & 0xff, a->f );}void avi_write_uint32( avi_t *a, uint32_t dw ){    fputc( ( dw      ) & 0xff, a->f );    fputc( ( dw >> 8 ) & 0xff, a->f );    fputc( ( dw >> 16) & 0xff, a->f );    fputc( ( dw >> 24) & 0xff, a->f );}void avi_write_fourcc( avi_t *a, char fcc[4] ){    fputc( fcc[0], a->f );    fputc( fcc[1], a->f );    fputc( fcc[2], a->f );    fputc( fcc[3], a->f );}/* Flags in avih */#define AVIF_HASINDEX       0x00000010  // Index at end of file?#define AVIF_ISINTERLEAVED  0x00000100#define AVIF_TRUSTCKTYPE    0x00000800  // Use CKType to find key frames?#define AVIIF_KEYFRAME      0x00000010L /* this frame is a key frame.*/void avi_write_header( avi_t *a ){    avi_write_fourcc( a, "RIFF" );    avi_write_uint32( a, a->i_riff > 0 ? a->i_riff - 8 : 0xFFFFFFFF );    avi_write_fourcc( a, "AVI " );    avi_write_fourcc( a, "LIST" );    avi_write_uint32( a,  4 + 4*16 + 12 + 4*16 + 4*12 );    avi_write_fourcc( a, "hdrl" );    avi_write_fourcc( a, "avih" );    avi_write_uint32( a, 4*16 - 8 );    avi_write_uint32( a, 1000000 / a->f_fps );    avi_write_uint32( a, 0xffffffff );    avi_write_uint32( a, 0 );    avi_write_uint32( a, AVIF_HASINDEX|AVIF_ISINTERLEAVED|AVIF_TRUSTCKTYPE);    avi_write_uint32( a, a->i_frame );    avi_write_uint32( a, 0 );    avi_write_uint32( a, 1 );    avi_write_uint32( a, 1000000 );    avi_write_uint32( a, a->i_width );    avi_write_uint32( a, a->i_height );    avi_write_uint32( a, 0 );    avi_write_uint32( a, 0 );    avi_write_uint32( a, 0 );    avi_write_uint32( a, 0 );    avi_write_fourcc( a, "LIST" );    avi_write_uint32( a,  4 + 4*16 + 4*12 );    avi_write_fourcc( a, "strl" );    avi_write_fourcc( a, "strh" );    avi_write_uint32( a,  4*16 - 8 );    avi_write_fourcc( a, "vids" );    avi_write_fourcc( a, a->fcc );    avi_write_uint32( a, 0 );    avi_write_uint32( a, 0 );    avi_write_uint32( a, 0 );    avi_write_uint32( a, 1000 );    avi_write_uint32( a, a->f_fps * 1000 );    avi_write_uint32( a, 0 );    avi_write_uint32( a, a->i_frame );    avi_write_uint32( a, 1024*1024 );    avi_write_uint32( a, -1 );    avi_write_uint32( a, a->i_width * a->i_height );    avi_write_uint32( a, 0 );    avi_write_uint16( a, a->i_width );    avi_write_uint16( a, a->i_height );    avi_write_fourcc( a, "strf" );    avi_write_uint32( a,  4*12 - 8 );    avi_write_uint32( a,  4*12 - 8 );    avi_write_uint32( a,  a->i_width );    avi_write_uint32( a,  a->i_height );    avi_write_uint16( a,  1 );    avi_write_uint16( a,  24 );    avi_write_fourcc( a,  a->fcc );    avi_write_uint32( a, a->i_width * a->i_height );    avi_write_uint32( a,  0 );    avi_write_uint32( a,  0 );    avi_write_uint32( a,  0 );    avi_write_uint32( a,  0 );    avi_write_fourcc( a, "LIST" );    avi_write_uint32( a,  a->i_movi_end > 0 ? a->i_movi_end - a->i_movi + 4: 0xFFFFFFFF );    avi_write_fourcc( a, "movi" );}void avi_write_idx( avi_t *a ){    avi_write_fourcc( a, "idx1" );    avi_write_uint32( a,  a->i_frame * 16 );    fwrite( a->idx, a->i_frame * 16, 1, a->f );}void avi_init( avi_t *a, FILE *f, float f_fps, char fcc[4] ){    a->f = f;    a->f_fps = f_fps;    memcpy( a->fcc, fcc, 4 );    a->i_width = 0;    a->i_height = 0;    a->i_frame = 0;    a->i_movi = 0;    a->i_riff = 0;    a->i_movi_end = 0;    a->i_idx_max = 0;    a->idx = NULL;    avi_write_header( a );    a->i_movi = ftell( a->f );}static void avi_set_dw( void *_p, uint32_t dw ){    uint8_t *p = _p;    p[0] = ( dw      )&0xff;    p[1] = ( dw >> 8 )&0xff;    p[2] = ( dw >> 16)&0xff;    p[3] = ( dw >> 24)&0xff;}void avi_write( avi_t *a, vbuf_t *v, int b_key ){    int64_t i_pos = ftell( a->f );    /* chunk header */    avi_write_fourcc( a, "00dc" );    avi_write_uint32( a, v->i_data );    fwrite( v->p_data, v->i_data, 1, a->f );    if( v->i_data&0x01 )    {        /* pad */        fputc( 0, a->f );    }    /* Append idx chunk */    if( a->i_idx_max <= a->i_frame )    {        a->i_idx_max += 1000;        a->idx = realloc( a->idx, a->i_idx_max * 16 );    }    memcpy( &a->idx[4*a->i_frame+0], "00dc", 4 );    avi_set_dw( &a->idx[4*a->i_frame+1], b_key ? AVIIF_KEYFRAME : 0 );    avi_set_dw( &a->idx[4*a->i_frame+2], i_pos );    avi_set_dw( &a->idx[4*a->i_frame+3], v->i_data );    a->i_frame++;}void avi_end( avi_t *a ){    a->i_movi_end = ftell( a->f );    /* write index */    avi_write_idx( a );    a->i_riff = ftell( a->f );    /* Fix header */    fseek( a->f, 0, SEEK_SET );    avi_write_header( a );    fprintf( stderr, "avi file written\n" );    fprintf( stderr, "  - codec: %4.4s\n", a->fcc );    fprintf( stderr, "  - size: %dx%d\n", a->i_width, a->i_height );    fprintf( stderr, "  - fps: %.3f\n", a->f_fps );    fprintf( stderr, "  - frames: %d\n", a->i_frame );}/***************************************************************************** * nal: *****************************************************************************/int nal_decode( nal_t *nal, void *p_data, int i_data ){    uint8_t *src = p_data;    uint8_t *end = &src[i_data];    uint8_t *dst = nal->p_payload;    nal->i_type    = src[0]&0x1f;    nal->i_ref_idc = (src[0] >> 5)&0x03;    src++;    while( src < end )    {        if( src < end - 3 && src[0] == 0x00 && src[1] == 0x00  && src[2] == 0x03 )        {            *dst++ = 0x00;            *dst++ = 0x00;            src += 3;            continue;        }        *dst++ = *src++;    }    nal->i_payload = dst - (uint8_t*)p_data;    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -