H264 数据avi文件封装和拆解

为了提高H264的保存效率,抛弃了FFmpeg库的avi封装,直接才源码的方式封装avi文件,源码来源于网络,经改造回馈网络。废话不多说,直接上干货。

  1. /* 
  2.  * avi_writer.h 
  3.  */  
  4.   
  5. #ifndef AVI_UIILS_WRITER_H_  
  6. #define AVI_UIILS_WRITER_H_  
  7.   
  8. #ifdef VIDEO_CLIP  
  9. #include "video_clip.h"  
  10. #endif  
  11. typedef unsigned char   uint8_t;  
  12. typedef unsigned short  uint16_t;  
  13. typedef unsigned   uint32_t;  
  14. typedef long long int64_t;  
  15.   
  16.   
  17. typedef struct avi_idx{  
  18.     int  is_key;  
  19.     int pos;  
  20.     int size;  
  21. }AVI_IDX;  
  22.   
  23. typedef struct avi_idx_hwx{  
  24.     AVI_IDX idx;  
  25.     int serial;  
  26.     int64_t st;  
  27. }AVI_IDX_HWX;  
  28.   
  29.   
  30.   
  31.   
  32.   
  33. /fopen  fp IO ///  
  34.   
  35.   
  36. class avi_writer{  
  37. public :  
  38.     // open write  低级 io  
  39.     avi_writer(float fps,int width,int height);  
  40.     // fopen fwrite  高级 io  
  41.     avi_writer(int64_t offset,float fps,int width,int height);  
  42.     ~avi_writer();  
  43.   
  44.   
  45. private:  
  46.     union{  
  47.         FILE *fp;  
  48.         int fd;  
  49.     }_f_handle;  
  50.   
  51.     float _f_fps;  
  52.     char  _fcc[4];  
  53.   
  54.     int   _i_width;  
  55.     int   _i_height;  
  56.   
  57.     int64_t _i_movi;  
  58.     int64_t _i_movi_end;  
  59.     int64_t _i_riff;  
  60.   
  61.     int _i_frame;  
  62.     int      _i_idx_max;  
  63.   
  64.     AVI_IDX* _idx;  
  65.     AVI_IDX_HWX* _idx_hwx;  
  66.   
  67.     char _buff[9];  
  68.   
  69.     int _io_mode;  
  70.     int64_t _start_offset;  
  71.     int64_t _off_set;  
  72.   
  73.     int _frist_serial;  
  74.     int _cur_serial;  
  75.   
  76.     int64_t _frist_st;  
  77.     int64_t _cur_st;  
  78.   
  79. private:  
  80.     void avi_write_char(char c);  
  81.     void avi_write_uint16(uint16_t w);  
  82.     void avi_write_uint32(uint32_t dw );  
  83.     void avi_write_fourcc(char fcc[4] );  
  84.     int avi_write_buff(void* buff,int size);  
  85.     int64_t avi_tell();  
  86.     int64_t avi_seek(int64_t offset);  
  87.   
  88.     void avi_set_fourcc( void *_p, char fcc[4]);  
  89.     void avi_set_dw( void *_p, uint32_t dw );  
  90.     void avi_set_dw64( void *_p, int64_t dw );  
  91.   
  92.     void avi_write_header();  
  93.     void avi_write_idx();  
  94.     void avi_write_idx_hwx();  
  95.   
  96.   
  97.   
  98. public :  
  99.     int avi_open(const char* filename);  
  100.     int write_frame(void *data, int size, int b_key );  
  101. #ifdef VIDEO_CLIP  
  102.     int avi_write_clip(VideoClip * clip);  
  103. #endif  
  104.     int64_t get_avi_file_size();  
  105.     int64_t avi_close();  
  106.   
  107.   
  108. public:  
  109.     void avi_fflush();  
  110.     int get_frist_serial();  
  111.     int get_cur_serial();  
  112.     int64_t get_frist_st();  
  113.     int64_t get_cur_st();  
  114.     int get_cur_fream_num();  
  115.   
  116.   
  117.     //获取当前已经存盘数据的索引区  
  118.     int get_cur_idx_hwx(AVI_IDX_HWX* idx,int fream_num);  
  119.   
  120. };  
  121.   
  122.   
  123. #endif  

  1. #ifndef AVI_UTILS_READER_H_  
  2. #define AVI_UTILS_READER_H_  
  3.   
  4. typedef long long int64_t;  
  5. typedef unsigned char   uint8_t;  
  6. typedef unsigned short  uint16_t;  
  7. typedef unsigned   uint32_t;  
  8.   
  9. #include "avi_writer.h"  
  10.   
  11.   
  12. typedef struct  
  13. {  
  14.     FILE *f;  
  15.   
  16.     char fcc[4];  
  17.   
  18.     float f_fps;  
  19.   
  20.     int i_width;  
  21.     int i_height;  
  22.   
  23.     int64_t i_movi;  
  24.     int64_t i_movi_end;  
  25.     int64_t i_riff;  
  26.   
  27.     int i_frame;  
  28.     int i_idx_max;  
  29.     uint32_t *idx;  
  30.     uint32_t *idx_hwx;  
  31. } avi_read_t;  
  32.   
  33.   
  34.   
  35. typedef struct avi_idx1_hwx{  
  36.     int  is_key;  
  37.     int pos;  
  38.     int size;  
  39.     int serial;  
  40.     int64_t st;  
  41. }IDX_HWX;  
  42.   
  43.   
  44. //读取avi标准索引区  
  45. int avi_read_avi_idx1(avi_read_t* a,AVI_IDX**idx);  
  46.   
  47.   
  48.   
  49. int avi_read_idx_hwx(avi_read_t* a,IDX_HWX** idx);  
  50. int avi_read( avi_read_t *a, void *buf,IDX_HWX* idx);  
  51.   
  52.   
  53.   
  54. void avi_rd_init( avi_read_t *a, FILE *f, float *f_fps,int *width,int *height);  
  55.   
  56. int avi_read( avi_read_t *a, void *buf, int buf_size, int* b_key );  
  57. int avi_read_frame(avi_read_t *a, void *buf, int buf_size,int64_t pos);  
  58. void avi_rd_end( avi_read_t * a);  
  59.   
  60.   
  61.   
  62. #endif /* AVI_READER_H_ */  

  1. /* 
  2.  * avi_write.cpp 
  3.  *<pre name="code" class="cpp">#include <stdio.h> 
  4. #include <stdlib.h> 
  5. #include <string.h> 
  6. #include "avi_writer.h" 
  7. #include "avi_reader.h" 
  8.  
  9.  
  10.  
  11. uint16_t avi_read_uint16( avi_read_t *a) 
  12. { 
  13.     uint16_t dw; 
  14.  
  15.     dw=fgetc(a->f); 
  16.     dw|=fgetc(a->f)<<8; 
  17.  
  18.     return dw; 
  19. } 
  20.  
  21. uint32_t avi_read_uint32( avi_read_t *a) 
  22. { 
  23.     uint32_t dw(0); 
  24.  
  25.     unsigned char c = 0; 
  26.     c= fgetc(a->f); 
  27.      
  28.     dw |=(c&0x000000ff); 
  29.     c = 0; 
  30.     c= fgetc(a->f); 
  31.     dw |= (c&0x000000ff)<<8; 
  32.  
  33.     c = 0; 
  34.     c= fgetc(a->f); 
  35.     dw |= (c&0x000000ff)<<16; 
  36.     c = 0; 
  37.     c= fgetc(a->f); 
  38.     dw |= (c&0x000000ff)<<24; 
  39.     c = 0; 
  40.     /* 
  41.     dw = fgetc(a->f); 
  42.     dw |= (fgetc(a->f)&0xff)<<8; 
  43.     dw |= (fgetc(a->f)&0xff)<<16; 
  44.     dw |= (fgetc(a->f)&0xff)<<24; 
  45.     */  
  46.     return dw;  
  47. }  
  48.   
  49. int64_t avi_read_int64( avi_read_t *a)  
  50. {  
  51.     int64_t dw;  
  52.   
  53.     dw = (int64_t) fgetc(a->f);  
  54.     dw |=(int64_t) (fgetc(a->f)&0xff)<<8;  
  55.     dw |=(int64_t) (fgetc(a->f)&0xff)<<16;  
  56.     dw |=(int64_t) (fgetc(a->f)&0xff)<<24;  
  57.     dw |=(int64_t) (fgetc(a->f)&0xff)<<32;  
  58.     dw |=(int64_t) (fgetc(a->f)&0xff)<<40;  
  59.     dw |=(int64_t) (fgetc(a->f)&0xff)<<48;  
  60.     dw |=(int64_t) (fgetc(a->f)&0xff)<<56;  
  61.   
  62.     return dw;  
  63. }  
  64.   
  65. void avi_read_fourcc( avi_read_t *a, char fcc[4] )  
  66. {  
  67.     fcc[0]=fgetc(a->f);    
  68.     fcc[1]=fgetc(a->f);  
  69.     fcc[2]=fgetc(a->f);    
  70.     fcc[3]=fgetc(a->f);  
  71. }  
  72.   
  73.   
  74. static void avi_red_dw( void *_p, uint32_t dw )  
  75. {  
  76.     uint8_t *p =(uint8_t *)_p;  
  77.   
  78.     p[0] = ( dw      )&0xff;  
  79.     p[1] = ( dw >> 8 )&0xff;  
  80.     p[2] = ( dw >> 16)&0xff;  
  81.     p[3] = ( dw >> 24)&0xff;  
  82. }  
  83.   
  84.   
  85. static void avi_read_header( avi_read_t *a )  
  86. {  
  87.     char buf[8];  
  88.     unsigned int uint32_data;  
  89.   
  90.     avi_read_fourcc( a, buf );  
  91.     a->i_riff = avi_read_uint32( a);  
  92.     avi_read_fourcc( a, buf );  
  93.   
  94.     avi_read_fourcc( a, buf );  
  95.     uint32_data = avi_read_uint32( a );  
  96.     avi_read_fourcc( a, buf );  
  97.   
  98.     avi_read_fourcc( a, buf );  
  99.     uint32_data = avi_read_uint32( a );  
  100.     uint32_data = avi_read_uint32( a );  
  101.     uint32_data = avi_read_uint32( a );  
  102.     uint32_data = avi_read_uint32( a );  
  103.     uint32_data = avi_read_uint32( a);  
  104.     a->i_frame = avi_read_uint32( a );  
  105.     uint32_data = avi_read_uint32( a );  
  106.     uint32_data = avi_read_uint32( a );  
  107.     uint32_data = avi_read_uint32( a );  
  108.     a->i_width = avi_read_uint32( a );  
  109.     a->i_height = avi_read_uint32( a );  
  110.     uint32_data = avi_read_uint32( a );  
  111.     uint32_data = avi_read_uint32( a );  
  112.     uint32_data = avi_read_uint32( a );  
  113.     uint32_data = avi_read_uint32( a );  
  114.   
  115.     avi_read_fourcc( a, buf );  
  116.     uint32_data = avi_read_uint32( a );  
  117.     avi_read_fourcc( a, buf );  
  118.   
  119.     avi_read_fourcc( a, buf );  
  120.     uint32_data = avi_read_uint32( a );  
  121.     avi_read_fourcc( a, buf );  
  122.     avi_read_fourcc( a, a->fcc );  
  123.     uint32_data = avi_read_uint32( a );  
  124.     uint32_data = avi_read_uint32( a );  
  125.     uint32_data = avi_read_uint32( a );  
  126.     uint32_data = avi_read_uint32( a );  
  127.     a->f_fps = (float)(avi_read_uint32( a )/1000);  
  128.     uint32_data = avi_read_uint32( a );  
  129.     a->i_frame = avi_read_uint32( a );  
  130.     uint32_data = avi_read_uint32( a );  
  131.     uint32_data = avi_read_uint32( a );  
  132.     uint32_data = avi_read_uint32( a );  
  133.     uint32_data = avi_read_uint32( a );  
  134.     a->i_width = avi_read_uint16( a );  
  135.     a->i_height = avi_read_uint16( a );  
  136.   
  137.     avi_read_fourcc( a, buf );  
  138.     uint32_data = avi_read_uint32( a );  
  139.     uint32_data = avi_read_uint32( a );  
  140.     uint32_data = avi_read_uint32( a );  
  141.     uint32_data = avi_read_uint32( a );  
  142.     avi_read_uint16( a );  
  143.     avi_read_uint16( a );  
  144.     avi_read_fourcc( a,  a->fcc );  
  145.     uint32_data = avi_read_uint32( a );  
  146.     uint32_data = avi_read_uint32( a );  
  147.     uint32_data = avi_read_uint32( a );  
  148.     uint32_data = avi_read_uint32( a );  
  149.     uint32_data = avi_read_uint32( a );  
  150.   
  151.     avi_read_fourcc( a, buf );  
  152.     a->i_movi_end = avi_read_uint32( a ) -4;  
  153.     avi_read_fourcc( a, buf );  
  154.   
  155. #if 0  
  156.     /* Append idx chunk */  
  157.     if( a->i_idx_max <= a->i_frame )  
  158.     {  
  159.         a->i_idx_max += 1000;  
  160.         a->idx =(uint32_t*)realloc(a->idx, a->i_idx_max * 16 );  
  161.     }  
  162.   
  163.     memcpy( &a->idx[4*a->i_frame+0], "00dc", 4 );  
  164.     avi_set_dw( &a->idx[4*a->i_frame+1], b_key ? AVIIF_KEYFRAME : 0 );  
  165.     avi_set_dw( &a->idx[4*a->i_frame+2], i_pos );  
  166.     avi_set_dw( &a->idx[4*a->i_frame+3], size );  
  167. #endif  
  168. }  
  169. /* 
  170. static void avi_read_idx( avi_read_t *a ) 
  171. { 
  172.     char buf[8]; 
  173.  
  174.     avi_read_fourcc( a, buf ); 
  175.     a->i_frame = avi_read_uint32( a ) / 16; 
  176.     //fwrite( a->idx, a->i_frame * 16, 1, a->f ); 
  177. }*/  
  178.   
  179. //读取avi标准索引区  
  180. int avi_read_avi_idx1(avi_read_t* a,AVI_IDX**idx)  
  181. {  
  182.     char buf[8];  
  183.     char* idx_buff = NULL;  
  184.   
  185.     int i_movi_end = a->i_movi_end;  
  186.   
  187.     int idx_pos_start;  
  188.     int idx_pos_end;  
  189.     int idx_len;  
  190.     //int64_t riff = a->i_riff+(56*4-4);  
  191.     int64_t temp;  
  192.   
  193.     int ret;  
  194.     int frame_num =0;  
  195.     int i=0;  
  196.   
  197.     temp=fseek(a->f,i_movi_end,SEEK_SET);  
  198.   
  199.     memset(buf,0,8);  
  200.     avi_read_fourcc( a, buf );  
  201.     if(strcmp(buf,"idx1"))  
  202.     {  
  203.         printf("<<<<<<<read buf is not 'idx1'>>>>>read buf is %s\n",buf);  
  204.         return -1;  
  205.     }  
  206.   
  207.     frame_num = avi_read_uint32(a)/16;  
  208.   
  209.   
  210.     if(frame_num <=0 )  
  211.     {  
  212.         *idx = NULL;  
  213.         printf("<<<<<<<read frame num faild>>>>>\n");  
  214.         return frame_num;  
  215.     }  
  216.   
  217.     AVI_IDX* idx_tmp = (AVI_IDX*)calloc(frame_num,sizeof(AVI_IDX));  
  218.   
  219.   
  220.     for(i=0;i<frame_num;i++)  
  221.     {  
  222.         memset(buf,0,8);  
  223.         avi_read_fourcc( a, buf );  
  224.         if(strcasecmp(buf,"00dc"))  
  225.         {  
  226.             printf("<<<<<<<read idx faild>>>>>\n");  
  227.             break;  
  228.         }  
  229.         idx_tmp[i].is_key=avi_read_uint32(a);  
  230.         idx_tmp[i].pos = avi_read_uint32(a);  
  231.         idx_tmp[i].size = avi_read_uint32(a);  
  232.     }  
  233.   
  234.     if(i!=frame_num)  
  235.     {  
  236.         free(idx_tmp);  
  237.         idx_tmp = NULL;  
  238.         return 0;  
  239.     }  
  240.   
  241.     *idx = idx_tmp;  
  242.     return frame_num;  
  243. }  
  244.   
  245.   
  246.   
  247. int avi_read_idx_hwx(avi_read_t* a,IDX_HWX** idx)  
  248. {  
  249.     char buf[8];  
  250.     char* idx_buff = NULL;  
  251.   
  252.     int riff = a->i_riff+8;  
  253.     int riff2 = a->i_riff;  
  254.     int idx_pos_start;  
  255.     int idx_pos_end;  
  256.     int idx_len;  
  257.     //int64_t riff = a->i_riff+(56*4-4);  
  258.     int64_t temp;  
  259.   
  260.     int ret;  
  261.     int frame_num =0;  
  262.     int i=0;  
  263.   
  264.     temp=fseek(a->f,riff,SEEK_SET);  
  265.   
  266.     memset(buf,0,8);  
  267.     avi_read_fourcc( a, buf );  
  268.     if(strcmp(buf,"ihwx"))  
  269.     {  
  270.         // Ipnc_DbgPrintf2(_TraceError,"<<<<<<<read buf is not 'ihwx'>>>>>read buf is %s\n",buf);  
  271.         return -1;  
  272.     }  
  273.   
  274.   
  275.     idx_pos_start = ftell( a->f );  
  276.     fseek(a->f,0,SEEK_END);  
  277.     idx_pos_end  = ftell( a->f );  
  278.   
  279.     idx_len  = idx_pos_end - idx_pos_start;  
  280.     fseek(a->f,0-idx_len,SEEK_END);  
  281.   
  282.   
  283.     frame_num = avi_read_uint32(a)/28;  
  284.   
  285.     if(frame_num <=0 )  
  286.     {  
  287.         *idx = NULL;  
  288.         return frame_num;  
  289.     }  
  290.   
  291.     IDX_HWX* idx_hwx = (IDX_HWX*)calloc(frame_num,sizeof(IDX_HWX));  
  292.   
  293.   
  294.     for(i=0;i<frame_num;i++)  
  295.     {  
  296.         memset(buf,0,8);  
  297.         avi_read_fourcc( a, buf );  
  298.         if(strcasecmp(buf,"hwx0"))  
  299.         {  
  300.             break;  
  301.         }  
  302.         idx_hwx[i].is_key=avi_read_uint32(a);  
  303.         idx_hwx[i].pos = avi_read_uint32(a);  
  304.         idx_hwx[i].size = avi_read_uint32(a);  
  305.         idx_hwx[i].serial = avi_read_uint32(a);  
  306.         idx_hwx[i].st =(long long)avi_read_int64(a);  
  307.     }  
  308.   
  309.     if(i!=frame_num)  
  310.     {  
  311.         free(idx_hwx);  
  312.         idx_hwx = NULL;  
  313.         *idx = NULL;  
  314.         return 0;  
  315.     }  
  316.   
  317.     *idx = idx_hwx;  
  318.     return frame_num;  
  319. }  
  320.   
  321.   
  322. void avi_rd_init( avi_read_t *a, FILE *f, float *f_fps,int *width,int *height)  
  323. {  
  324.     char hwx_fcc[8];  
  325.     a->f = f;  
  326.     a->f_fps = 0;  
  327.     a->i_width = 0;  
  328.     a->i_height = 0;  
  329.     a->i_frame = 0;  
  330.     a->i_movi = 0;  
  331.     a->i_riff = 0;  
  332.     a->i_movi_end = 0;  
  333.     a->i_idx_max = 0;  
  334.     a->idx = NULL;  
  335.     a->idx_hwx = NULL;  
  336.     avi_read_header( a );  
  337.     *f_fps=a->f_fps;  
  338.     *width=a->i_width;  
  339.     *height=a->i_height;  
  340.   
  341.   
  342. }  
  343.   
  344. int avi_read( avi_read_t *a, void *buf, int buf_size, int* b_key )  
  345. {  
  346.     int frame_size = 0;  
  347.     int read_size = 0;  
  348.     int64_t i_pos = ftell( a->f );  
  349.     char fcc[8];  
  350.     char c;  
  351.   
  352.     if (!a || !buf || (buf_size<16))  
  353.         return 0;  
  354.       
  355.     //avi_read_idx_hwx("ihwx",hwx_fcc);  
  356.   
  357.     if (b_key) *b_key = 0;  
  358.     while ((frame_size<=0) && (!feof(a->f)))  
  359.     {  
  360.         avi_read_fourcc( a,  fcc);//  
  361.         fcc[4] = '\0';  
  362.         if (!strcmp(fcc, "00dc"))  
  363.         {  
  364.             frame_size = avi_read_uint32( a );  
  365.             if ((frame_size>16) && (frame_size<buf_size))  
  366.             {  
  367.                 read_size = fread( buf, 1, frame_size, a->f );  
  368.                 if (read_size == frame_size)  
  369.                 {  
  370.                     if (frame_size&0x01 )  
  371.                         c = fgetc( a->f );/* pad */  
  372.   
  373.                     a->i_frame++;  
  374.                 }  
  375.             }  
  376.         }  
  377.     }  
  378.   
  379.     return frame_size;  
  380. }  
  381.   
  382. /* 
  383.  * sucess return frame_size 
  384.  * faild  return -1 
  385.  */  
  386. int avi_read_frame(avi_read_t *a, void *buf, int buf_size,int64_t pos)  
  387. {  
  388.     int frame_size = 0;  
  389.     int read_size = 0;  
  390.     char fcc[8];  
  391.     char c;  
  392.     int64_t i_pos = ftell( a->f );  
  393.   
  394.     if (!a || !buf || (buf_size<16))  
  395.         return -1;  
  396.   
  397.   
  398.     if(i_pos!=pos)  
  399.         fseek(a->f,pos,SEEK_SET);  
  400.   
  401.     avi_read_fourcc( a,  fcc);//  
  402.     fcc[4] = '\0';  
  403.     if (!strcmp(fcc, "00dc"))  
  404.     {  
  405.         frame_size = avi_read_uint32( a );  
  406.         if ((frame_size>16) && (frame_size<buf_size))  
  407.         {  
  408.             read_size = fread( buf, 1, frame_size, a->f );  
  409.             if (read_size == frame_size)  
  410.             {  
  411.                 if (frame_size&0x01 )  
  412.                     c = fgetc( a->f );/* pad */  
  413.             }  
  414.             else  
  415.             {  
  416.                 return -1;  
  417.             }  
  418.         }  
  419.     }  
  420.     else  
  421.     {  
  422.         return -1;  
  423.     }  
  424.   
  425.     return frame_size;  
  426. }  
  427.   
  428. void avi_rd_end( avi_read_t * a)  
  429. {  
  430.   
  431. }  
  1. /* 
  2.  * avi_write.cpp 
  3.  * 
  4.  */  
  5.   
  6. #include <stdio.h>  
  7. #include <stdlib.h>  
  8. #include <string.h>  
  9. #include "avi_writer.h"  
  10.   
  11. #ifdef WIN32  
  12. #include "..\..\..\media_base\media_dbg.h"  
  13. #include "..\..\..\media_base\sync.h"  
  14. #else  
  15. #include "sync.h"  
  16.   
  17. #include<unistd.h>  
  18. #include<string.h>  
  19. #include<fcntl.h>  
  20. #include<errno.h>  
  21. #endif  
  22.   
  23. /* Flags in avih */  
  24. #define AVIF_HASINDEX       0x00000010  // Index at end of file?  
  25. #define AVIF_ISINTERLEAVED  0x00000100  
  26. #define AVIF_TRUSTCKTYPE    0x00000800  // Use CKType to find key frames?  
  27.   
  28. #define AVIIF_KEYFRAME      0x00000010L /* this frame is a key frame.*/  
  29.   
  30.   
  31.   
  32. avi_writer::avi_writer(int64_t offset,float fps,int width,int height)  
  33. {  
  34.     _i_width = width;  
  35.     _i_height = height;  
  36.     _f_fps = fps;  
  37.   
  38.     memcpy( _fcc,"h264",4);  
  39.     _i_width = width;  
  40.     _i_height = height;  
  41.     _i_frame = 0;  
  42.     _i_movi = 0;  
  43.     _i_riff = 0;  
  44.     _i_movi_end = 0;  
  45.     _i_idx_max = 0;  
  46.     _idx = NULL;  
  47.     _idx_hwx = NULL;  
  48.   
  49.     _io_mode = 0; // open write  
  50.     _start_offset = offset;  
  51.     _off_set = 0;  
  52.   
  53.     _frist_serial=0;  
  54.     _cur_serial=0;  
  55.   
  56.     _frist_st=0;  
  57.     _cur_st=0;  
  58. }  
  59.   
  60. avi_writer::avi_writer(float fps,int width,int height)  
  61. {  
  62.     _i_width = width;  
  63.     _i_height = height;  
  64.     _f_fps = fps;  
  65.   
  66.     memcpy( _fcc,"h264",4);  
  67.     _i_width = width;  
  68.     _i_height = height;  
  69.     _i_frame = 0;  
  70.     _i_movi = 0;  
  71.     _i_riff = 0;  
  72.     _i_movi_end = 0;  
  73.     _i_idx_max = 0;  
  74.     _idx = NULL;  
  75.     _idx_hwx = NULL;  
  76.   
  77.     _io_mode = 1;  // fopen fwrite  
  78.     _start_offset = 0;  
  79.     _off_set = 0;  
  80.   
  81.     _frist_serial=0;  
  82.     _cur_serial=0;  
  83.   
  84.     _frist_st=0;  
  85.     _cur_st=0;  
  86. }  
  87.   
  88. avi_writer::~avi_writer()  
  89. {  
  90.     if(_idx)  
  91.         free(_idx);  
  92.     _idx = NULL;  
  93.     if(_idx_hwx)  
  94.          free(_idx_hwx);  
  95.     _idx_hwx = NULL;  
  96. }  
  97.   
  98. void avi_writer::avi_write_char(char c)  
  99. {  
  100.     if(_io_mode)  
  101.     {  
  102.         fputc( c, _f_handle.fp);  
  103.     }  
  104.     else  
  105.     {  
  106.         write(_f_handle.fd,&c,1);  
  107.     }  
  108.     _off_set += 1l;  
  109.   
  110. }  
  111.   
  112. void avi_writer::avi_write_uint16(uint16_t w)  
  113. {  
  114.     if(_io_mode)  
  115.     {  
  116.         fputc( ( w      ) & 0xff, _f_handle.fp);  
  117.         fputc( ( w >> 8 ) & 0xff, _f_handle.fp );  
  118.     }  
  119.     else  
  120.     {  
  121.         _buff[0] = ( w      ) & 0xff;  
  122.         _buff[1] = ( w >> 8 ) & 0xff;  
  123.         _buff[2] = '\0';  
  124.         write(_f_handle.fd,_buff,2);  
  125.     }  
  126.   
  127.     _off_set += 2l;  
  128. }  
  129. void avi_writer::avi_write_uint32(uint32_t dw )  
  130. {  
  131.     if(_io_mode)  
  132.     {  
  133.         fputc( ( dw      ) & 0xff,_f_handle.fp );  
  134.         fputc( ( dw >> 8 ) & 0xff,_f_handle.fp);  
  135.         fputc( ( dw >> 16) & 0xff,_f_handle.fp );  
  136.         fputc( ( dw >> 24) & 0xff,_f_handle.fp);  
  137.     }  
  138.     else  
  139.     {  
  140.         _buff[0] = ( dw       ) & 0xff;  
  141.         _buff[1] = ( dw >> 8  ) & 0xff;  
  142.         _buff[2] = ( dw >> 16 ) & 0xff;  
  143.         _buff[3] = ( dw >> 24 ) & 0xff;  
  144.         _buff[4] = '\0';  
  145.   
  146.         write(_f_handle.fd,_buff,4);  
  147.     }  
  148.     _off_set += 4l;  
  149. }  
  150. void avi_writer::avi_write_fourcc(char fcc[4] )  
  151. {  
  152.     if(_io_mode)  
  153.     {  
  154.         fputc( fcc[0],_f_handle.fp);  
  155.         fputc( fcc[1],_f_handle.fp);  
  156.         fputc( fcc[2],_f_handle.fp);  
  157.         fputc( fcc[3],_f_handle.fp);  
  158.     }  
  159.     else  
  160.     {  
  161.         write(_f_handle.fd,fcc,4);  
  162.     }  
  163.     _off_set += 4l;  
  164. }  
  165.   
  166.   
  167. int avi_writer::avi_write_buff(void* buff,int size)  
  168. {  
  169.     int ret=0;  
  170.   
  171.     if(_io_mode)  
  172.     {  
  173.         ret = fwrite(buff,1,size,_f_handle.fp);  
  174.     }  
  175.     else  
  176.     {  
  177.         ret = write(_f_handle.fd,buff,size);  
  178.     }  
  179.   
  180.     if(ret!=size)  
  181.     {  
  182.         Ipnc_DbgPrintf2(_TraceInfo, "write error\n");  
  183.     }  
  184.   
  185.     _off_set +=(int64_t)ret;  
  186.   
  187.     return ret;  
  188. }  
  189.   
  190. void avi_writer::avi_write_header()  
  191. {  
  192.      avi_write_fourcc("RIFF" );  
  193.     avi_write_uint32(_i_riff > 0 ? _i_riff - 8 : 0xFFFFFFFF );  
  194.     avi_write_fourcc("AVI " );  
  195.   
  196.     avi_write_fourcc("LIST" );  
  197.     avi_write_uint32( 4 + 4*16 + 12 + 4*16 + 4*12 );  
  198.     avi_write_fourcc("hdrl" );  
  199.   
  200.     avi_write_fourcc("avih" );  
  201.     avi_write_uint32(4*16 - 8 );  
  202.     avi_write_uint32(1000000 / _f_fps );  
  203.     avi_write_uint32(0xffffffff );  
  204.     avi_write_uint32(0 );  
  205.     avi_write_uint32(AVIF_HASINDEX|AVIF_ISINTERLEAVED|AVIF_TRUSTCKTYPE);  
  206.     avi_write_uint32(_i_frame );  
  207.     avi_write_uint32(0 );  
  208.     avi_write_uint32(1 );  
  209.     avi_write_uint32(1000000 );  
  210.     avi_write_uint32(_i_width );  
  211.     avi_write_uint32(_i_height );  
  212.     avi_write_uint32(0 );  
  213.     avi_write_uint32(0 );  
  214.     avi_write_uint32(0 );  
  215.     avi_write_uint32(0 );  
  216.   
  217.     avi_write_fourcc("LIST" );  
  218.     avi_write_uint32( 4 + 4*16 + 4*12 );  
  219.     avi_write_fourcc("strl" );  
  220.   
  221.     avi_write_fourcc("strh" );  
  222.     avi_write_uint32( 4*16 - 8 );  
  223.     avi_write_fourcc("vids" );  
  224.     avi_write_fourcc(_fcc );  
  225.     avi_write_uint32(0 );  
  226.     avi_write_uint32(0 );  
  227.     avi_write_uint32(0 );  
  228.     avi_write_uint32(1000 );  
  229.     avi_write_uint32(_f_fps * 1000 );  
  230.     avi_write_uint32(0 );  
  231.     avi_write_uint32(_i_frame );  
  232.     avi_write_uint32(1024*1024 );  
  233.     avi_write_uint32(-1 );  
  234.     avi_write_uint32(_i_width * _i_height );  
  235.     avi_write_uint32(0 );  
  236.     avi_write_uint16(_i_width );  
  237.     avi_write_uint16(_i_height );  
  238.   
  239.     avi_write_fourcc("strf" );  
  240.     avi_write_uint32( 4*12 - 8 );  
  241.     avi_write_uint32( 4*12 - 8 );  
  242.     avi_write_uint32( _i_width );  
  243.     avi_write_uint32( _i_height );  
  244.     avi_write_uint16( 1 );  
  245.     avi_write_uint16( 24 );  
  246.     avi_write_fourcc( _fcc );  
  247.     avi_write_uint32(_i_width * _i_height );  
  248.     avi_write_uint32( 0 );  
  249.     avi_write_uint32( 0 );  
  250.     avi_write_uint32( 0 );  
  251.     avi_write_uint32( 0 );  
  252.   
  253.     avi_write_fourcc("LIST" );  
  254.     avi_write_uint32( _i_movi_end > 0 ? _i_movi_end - _i_movi + 4: 0xFFFFFFFF );  
  255.     avi_write_fourcc("movi" );  
  256. }  
  257.   
  258. void avi_writer::avi_set_fourcc( void *_p, char fcc[4] )  
  259. {  
  260.     uint8_t *p =(uint8_t *)_p;  
  261.     p[0] = fcc[0];  
  262.     p[1] = fcc[1];  
  263.     p[2] = fcc[2];  
  264.     p[3] = fcc[3];  
  265. }  
  266. void avi_writer::avi_set_dw( void *_p, uint32_t dw )  
  267. {  
  268.     uint8_t *p =(uint8_t *)_p;  
  269.   
  270.     p[0] = ( dw      )&0xff;  
  271.     p[1] = ( dw >> 8 )&0xff;  
  272.     p[2] = ( dw >> 16)&0xff;  
  273.     p[3] = ( dw >> 24)&0xff;  
  274. }  
  275. void avi_writer::avi_set_dw64( void *_p, int64_t dw )  
  276. {  
  277.     uint8_t *p =(uint8_t *)_p;  
  278.   
  279.     p[0] = ( dw      )&0xff;  
  280.     p[1] = ( dw >> 8 )&0xff;  
  281.     p[2] = ( dw >> 16)&0xff;  
  282.     p[3] = ( dw >> 24)&0xff;  
  283.     p[4] = ( dw >> 32)&0xff;  
  284.     p[5] = ( dw >> 40)&0xff;  
  285.     p[6] = ( dw >> 48)&0xff;  
  286.     p[7] = ( dw >> 56)&0xff;  
  287. }  
  288.   
  289. int64_t avi_writer::avi_tell()  
  290. {  
  291.     int64_t pos = 0;  
  292.   
  293.   
  294.     if(_io_mode)  
  295.     {  
  296.         pos =(int64_t)ftell(_f_handle.fp);  
  297.     }  
  298.     else  
  299.     {  
  300.         pos = _off_set;  
  301.     }  
  302.   
  303.     return pos;  
  304. }  
  305.   
  306.   
  307. int64_t avi_writer::avi_seek(int64_t offset )  
  308. {  
  309.     if(_io_mode)  
  310.         fseek(_f_handle.fp, offset, SEEK_SET);  
  311.     else  
  312.         lseek64(_f_handle.fd,_start_offset+offset,SEEK_SET);  
  313. }  
  314.   
  315. void avi_writer::avi_write_idx()  
  316. {  
  317.     int i=0;  
  318.     uint32_t* buff = NULL;  
  319.   
  320.   
  321.     avi_write_fourcc("idx1" );  
  322.     avi_write_uint32(_i_frame * 16 );  
  323.   
  324.     buff = (uint32_t*)calloc(sizeof(uint32_t),_i_frame*16);  
  325.     if(!buff)  
  326.     {  
  327.         Ipnc_DbgPrintf2(_TraceInfo, "no mem....\n");  
  328.         return ;  
  329.     }  
  330.   
  331.     for(i=0;i<_i_frame;i++)  
  332.     {  
  333.         avi_set_fourcc(&buff[4*i+0],"00dc");  
  334.         avi_set_dw(&buff[4*i+1], _idx[i].is_key);  
  335.         avi_set_dw(&buff[4*i+2], _idx[i].pos );  
  336.         avi_set_dw(&buff[4*i+3], _idx[i].size );  
  337.     }  
  338.     avi_write_buff(buff,sizeof(uint32_t)*_i_frame * 16);  
  339.     free(buff);  
  340.     free(_idx);  
  341.     _idx  = NULL;  
  342. }  
  343. void avi_writer::avi_write_idx_hwx()  
  344. {  
  345.     int i=0;  
  346.     uint32_t* buff = NULL;  
  347.   
  348.     if(!_idx_hwx)  
  349.         return;  
  350.   
  351.     avi_write_fourcc("ihwx");  
  352.     avi_write_uint32(_i_frame);  
  353.   
  354.     buff = (uint32_t*)calloc(sizeof(uint32_t),_i_frame*28);  
  355.     if(!buff)  
  356.     {  
  357.         Ipnc_DbgPrintf2(_TraceInfo, "no mem....\n");  
  358.         return ;  
  359.     }  
  360.   
  361.     Ipnc_DbgPrintf2(_TraceInfo, "frist serial:%d end serial:%d frist st:%lld cur st:%lld\n",  
  362.         _frist_serial,_cur_serial,_frist_st,_cur_st);  
  363.   
  364.     for(i=0;i<_i_frame;i++)  
  365.     {  
  366.         avi_set_fourcc(&buff[7*i+0],"hwx0");  
  367.         avi_set_dw(&buff[7*i+1], _idx_hwx[i].idx.is_key);  
  368.         avi_set_dw(&buff[7*i+2], _idx_hwx[i].idx.pos );  
  369.         avi_set_dw(&buff[7*i+3], _idx_hwx[i].idx.size );  
  370.         avi_set_dw(&buff[7*i+4], _idx_hwx[i].serial);  
  371.         avi_set_dw64(&buff[7*i+5], _idx_hwx[i].st);  
  372.     }  
  373.     avi_write_buff(buff,sizeof(uint32_t)*_i_frame*28);  
  374.   
  375.     free(buff);  
  376.     free(_idx_hwx);  
  377.     _idx_hwx = NULL;  
  378. }  
  379.   
  380. int avi_writer::avi_open(const char* filename)  
  381. {  
  382.     if(!filename)  
  383.     {  
  384.         Ipnc_DbgPrintf2(_TraceError, "invalid filename\n");  
  385.         return -1;  
  386.     }  
  387.   
  388.     if(_io_mode)  
  389.     {  
  390.         _f_handle.fp = fopen(filename,"wb+");  
  391.         if(!_f_handle.fp)  
  392.         {  
  393.             Ipnc_DbgPrintf2(_TraceError,  
  394.                     "create avi file failed 1: error=%d, file=%s!!!\n",  
  395.                     errno, filename);  
  396.             return -1;  
  397.         }  
  398.     }  
  399.     else  
  400.     {  
  401.         _f_handle.fd = open(filename,O_CREAT|O_RDWR);  
  402.         if(_f_handle.fd < 0 )  
  403.         {  
  404.             Ipnc_DbgPrintf2(_TraceError,  
  405.                         "create avi file failed 2: error=%d, file=%s!!!\n",  
  406.                         errno, filename);  
  407.             return -1;  
  408.         }  
  409.     }  
  410.   
  411.     Ipnc_DbgPrintf2(_TraceError,  
  412.             "create avi file success: %s\n",  
  413.             filename);  
  414.     avi_seek(0);  
  415.     avi_write_header();  
  416.     return 0;  
  417. }  
  418. int avi_writer::write_frame(void *data, int size, int b_key )  
  419. {  
  420.     int ret=0;  
  421.     int64_t i_pos = avi_tell();  
  422.   
  423.     /* chunk header */  
  424.     avi_write_fourcc("00dc" );  
  425.     avi_write_uint32(size);  
  426.   
  427.     ret = avi_write_buff(data,size);  
  428.   
  429.     if(size&0x01 )  
  430.     {  
  431.         /* pad */  
  432.         avi_write_char(0);  
  433.     }  
  434.   
  435.     /* Append idx chunk */  
  436.     if( _i_idx_max <= _i_frame )  
  437.     {  
  438.         _i_idx_max += 1000;  
  439.         _idx =(AVI_IDX*)realloc(_idx,_i_idx_max*sizeof(AVI_IDX));  
  440.     }  
  441.     _idx[_i_frame].is_key = b_key ? AVIIF_KEYFRAME : 0 ;  
  442.     _idx[_i_frame].pos = i_pos;  
  443.     _idx[_i_frame].size = size;  
  444.   
  445.     _i_frame++;  
  446.   
  447.     return ret;  
  448. }  
  449. #ifdef VIDEO_CLIP  
  450. int avi_writer::avi_write_clip(VideoClip * clip)  
  451. {  
  452.     int ret=0;  
  453.     int j=0,size=0,serial=0;  
  454.     int64_t timest=0;  
  455.     int is_key=0;  
  456.   
  457.     int64_t i_pos = avi_tell();  
  458.   
  459.     //Ipnc_DbgPrintf2(_TraceInfo, "write clip pos:%lld offset:%lld\n",i_pos,_off_set);  
  460.   
  461.     /* chunk header */  
  462.     ret = avi_write_buff( clip->get_buff_head(),clip->size());  
  463. /* 
  464.     Ipnc_DbgPrintf2(_TraceInfo, "clip frame num:%d start: serial:%d st:%lld end serial:%d st:%lld\n", 
  465.             clip->frame_count(), 
  466.             clip->get_frame_serial(0), 
  467.             clip->get_frame_timest(0), 
  468.             clip->get_frame_serial(clip->frame_count()-1), 
  469.             clip->get_frame_timest(clip->frame_count()-1)); 
  470.     Ipnc_DbgPrintf2(_TraceInfo, "avi file frame num :%d\n",_i_frame); 
  471. */  
  472.     for (j=0; j<clip->frame_count(); j++)  
  473.     {  
  474.         /* Append idx chunk */  
  475.         if( _i_idx_max <= _i_frame )  
  476.         {  
  477.             _i_idx_max += 1000;  
  478.             _idx =(AVI_IDX*)realloc(_idx,_i_idx_max*sizeof(AVI_IDX));  
  479.             _idx_hwx =(AVI_IDX_HWX*)realloc(_idx_hwx, _i_idx_max * sizeof(AVI_IDX_HWX));  
  480.         }  
  481.   
  482.         is_key = clip->get_frame_key(j);  
  483.         size = clip->get_frame_size(j);  
  484.         serial = clip->get_frame_serial(j);  
  485.         timest = clip->get_frame_timest(j);  
  486.   
  487.   
  488.         if(!_frist_serial)  
  489.             _frist_serial=serial;  
  490.         _cur_serial=serial;  
  491.         if(!_frist_st)  
  492.             _frist_st=timest;  
  493.         _cur_st=timest;  
  494.   
  495.         _idx[_i_frame].is_key = is_key ? AVIIF_KEYFRAME : 0 ;  
  496.         _idx[_i_frame].pos = i_pos;  
  497.         _idx[_i_frame].size = size;  
  498.   
  499.         _idx_hwx[_i_frame].idx.is_key = is_key ? AVIIF_KEYFRAME : 0 ;  
  500.         _idx_hwx[_i_frame].idx.pos = i_pos;  
  501.         _idx_hwx[_i_frame].idx.size = size;  
  502.         _idx_hwx[_i_frame].serial = serial;  
  503.         _idx_hwx[_i_frame].st = timest;  
  504.   
  505.         i_pos += (size+8+(size&0x01));  
  506.   
  507.         _i_frame++;  
  508.     }  
  509.   
  510.     return ret;  
  511. }  
  512. #endif  
  513. int64_t avi_writer::avi_close()  
  514. {  
  515.     int64_t file_size = 0;  
  516.     _i_movi_end = avi_tell();  
  517.   
  518.     /* write index */  
  519.     avi_write_idx();  
  520.   
  521.     _i_riff = avi_tell();  
  522.     //Ipnc_DbgPrintf2(_TraceInfo, "avi end:%lld offset:%lld\n",_i_riff,_off_set);  
  523.     //idx hwx  
  524.     //avi_write_idx_hwx();  
  525.   
  526.     file_size = avi_tell();  
  527.     //Ipnc_DbgPrintf2(_TraceInfo, "avi file len :%lld offset:%lld\n",file_size,_off_set);  
  528.     /* Fix header */  
  529.     avi_seek(0);  
  530.     avi_write_header();  
  531.   
  532.     if(_io_mode)  
  533.     {  
  534.         fclose(_f_handle.fp);  
  535.         _f_handle.fp = NULL;  
  536.     }  
  537.     else  
  538.     {  
  539.         close(_f_handle.fd);  
  540.         _f_handle.fd = 0;  
  541.     }  
  542.   
  543.     return file_size;  
  544. }  
  545.   
  546. int64_t avi_writer::get_avi_file_size()  
  547. {  
  548.     return _off_set;  
  549. }  
  550.   
  551. void avi_writer::avi_fflush()  
  552. {  
  553.     if(_io_mode)  
  554.     {  
  555.         fflush(_f_handle.fp);  
  556.     }  
  557. }  
  558.   
  559. int avi_writer::get_frist_serial()  
  560. {  
  561.     return _frist_serial;  
  562. }  
  563. int avi_writer::get_cur_serial()  
  564. {  
  565.     return _cur_serial;  
  566. }  
  567. int64_t avi_writer::get_frist_st()  
  568. {  
  569.     return _frist_st;  
  570. }  
  571. int64_t avi_writer::get_cur_st()  
  572. {  
  573.     return _cur_st;  
  574. }  
  575. int avi_writer::get_cur_fream_num()  
  576. {  
  577.     return _i_frame;  
  578. }  
  579. int avi_writer::get_cur_idx_hwx(AVI_IDX_HWX* idx,int fream_num)  
  580. {  
  581.     if(fream_num <=0 || !idx)  
  582.     {  
  583.         Ipnc_DbgPrintf2(_TraceInfo,"invalid idx or frame num.....\n");  
  584.         return -1;  
  585.     }  
  586.     if(!_idx_hwx)  
  587.     {  
  588.         Ipnc_DbgPrintf2(_TraceInfo,"invalid _idx_hwx.....\n");  
  589.         return -1;  
  590.     }  
  591.     memcpy(idx,_idx_hwx,fream_num* sizeof(AVI_IDX_HWX));  
  592.     return 0;  
  593. }  

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,首先需要了解一下AVI文件格式的结构。AVI文件格式是由一个RIFF头和多个块构成的。其中,RIFF头用于标识文件类型和文件大小,块用于存储音视频数据。在本次任务中,我们需要将G711u格式的音频数据H264格式的视频数据融合起来,生成一个AVI文件。 下面是一个简单的伪代码示例: ```c // 打开G711u文件H264文件 FILE *g711u_file = fopen("audio.g711u", "rb"); FILE *h264_file = fopen("video.h264", "rb"); // 创建AVI文件 FILE *avi_file = fopen("output.avi", "wb"); // 写入RIFF头 avi_header_t avi_header; create_avi_header(&avi_header); fwrite(&avi_header, sizeof(avi_header), 1, avi_file); // 写入音视频数据 while (!eof(g711u_file) && !eof(h264_file)) { // 读取G711u格式的音频数据 fread(audio_data, 1, audio_data_size, g711u_file); // 读取H264格式的视频数据 fread(video_data, 1, video_data_size, h264_file); // 写入音频块 avi_audio_chunk_t audio_chunk; create_avi_audio_chunk(&audio_chunk, audio_data, audio_data_size); fwrite(&audio_chunk, sizeof(audio_chunk), 1, avi_file); fwrite(audio_data, 1, audio_data_size, avi_file); // 写入视频块 avi_video_chunk_t video_chunk; create_avi_video_chunk(&video_chunk, video_data, video_data_size); fwrite(&video_chunk, sizeof(video_chunk), 1, avi_file); fwrite(video_data, 1, video_data_size, avi_file); } // 关闭文件 fclose(g711u_file); fclose(h264_file); fclose(avi_file); ``` 需要注意的是,上述代码中的`create_avi_header`、`create_avi_audio_chunk`和`create_avi_video_chunk`函数需要根据AVI文件格式的规范进行实现。另外,还需要根据实际情况确定音频和视频数据的大小、采样率、帧率等参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值