from: http://blog.csdn.net/zhujinghao_09/article/details/44458245

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

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

H264 数据avi文件封装和拆解相关推荐

  1. FFMPEG avi文件封装实现

    FFMPEG avi录像实现 date:2022.09.27 author:lyn version:ffmpeg4.1.3 1.avi数据结构 2.ffmpeg avi封装实现 3.avi函数调用关系 ...

  2. FFMPEG保存H264流到AVI文件中形成录像

    研究了使用FFMPEG保存H264流到AVI文件中形成录像的方法,下面是大致流程. 使用的FFMPEG版本   ffmpeg-2.6.9.然后我静态编译后使用的静态库,至于怎么静态编译看我之前的文章. ...

  3. AVI音视频封装格式学习(五)——h265与PCM合成AVI文件

    不知道是处于版权收费问题还是什么原因,H265现在也并没有非常广泛的被普及.将h265数据合成AVI的资料现在在网上也基本上没有.使用格式化工厂工具将h265数据封装成AVI格式,发现它在封装的时候其 ...

  4. H264文件封装MP4文件

    推荐一篇优秀的博文.对于MP4的初学者很有用:MP4文件格式解析_chenchong_219的博客-CSDN博客_mp4格式 对于这篇博文最后 Sample Table Box部分我想做一些补充,如有 ...

  5. AVI文件的音视频数据简析

    AVI文件的音视频数据 如图是使用AtomicBrowser2(AVI)打开的一个AVI文件: AVI文件从其RIFF标识符后跟的'AVI'开始. 其数据格式如下: 视频音频的放置方式 其中LIST ...

  6. h.264视频文件封装

    所谓封装格式就是将已经编码压缩好的视频轨和音频轨按照一定的格式放到一个文件中,也就是说仅仅是一个外壳,或者大家把它当成一个放视频轨和音频轨的文件夹也可以.说得通俗点,视频轨相当于饭,而音频轨相当于菜, ...

  7. ffmpeg获取rtsp h265_用FFmpeg将rtsp视频流保存成H264、h265文件

    ffmpeg:FFmpeg的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward,是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算 ...

  8. AVI视频封装格式(阅读笔记)

    文章目录 1.AVI简介(本节为抄录) 2.AVI格式示意图(本节为抄录) 3.示意图 VS 数据结构 VS 具体数据 3.1 RIFF文件头[最开始12个字节] 3.2 hdrl信息[第13-24字 ...

  9. Qt利用avilib实现录屏功能,生成avi文件

    环境: Qt + vs2013 + avilib demo下载:https://download.csdn.net/download/birenxiaofeigg/12087607 界面 开始录制: ...

最新文章

  1. eladmin代码自动生成_高效代码自动化生成
  2. SAP CRM Survey调查问卷的模型设计原理解析
  3. async 和 await 之异步编程的学习
  4. SRV记录注册不成功的可能的原因
  5. spring mysql事物级别_mysql事务级别和spring中应用
  6. logistic回归分析优点_逻辑回归的简单介绍
  7. UIPageControl---iOS-Apple苹果官方文档翻译
  8. pom.xml文件中nonFilteredFileExtension标签
  9. PostgreSQL 给数据库添加用户
  10. glusphere设置球位置_玄武区举办桌上冰壶球比赛暨江苏省桌上冰壶球俱乐部联赛(玄武区站)活动...
  11. Thin框架的应用(一) 单机双人对战象棋程序
  12. 俺的三国武将观(一)
  13. linux – Docker:无法添加对接口(不支持操作)
  14. ELK集群部署(六)之Kafka操作
  15. 【神经网络】神经网络中的矩阵的理解
  16. 一般能ping通自己的IP ,但是ping 不通网关,也ping不通别的主机IP
  17. 一、大数据_课程导论(P2~P6)
  18. 文章标题const/ this 指针/析构函数/浅拷贝
  19. 北京大学计算机专业王腾,王腾-青年学者-北大地空学院
  20. 三元运算符,文件处理的可读可写

热门文章

  1. ae怎么做圆一圈圈扩散效果_轻备学院AE特效基础教程 - 如何制作一个带有动画效果村庄烟雾...
  2. python图像腐蚀处理_[Python图像处理]八.图像腐蚀和图像膨胀
  3. Java synchronized解析
  4. Kettle和ETL的基本构成
  5. 2556. [NOIP2016]玩具谜题
  6. XPsp3键盘设备链/栈信息_02_VMware
  7. 基于 Asio 的 C++ 网络编程
  8. 6、Cocos2dx 3.0游戏开发的基本概念找个小三场比赛
  9. iOS开发-ViewController的生命周期和切换
  10. WP8开发日志(1):Toolkit的本地化