为了提高H264的保存效率,抛弃了FFmpeg库的avi封装,直接才源码的方式封装avi文件,源码来源于网络,经改造回馈网络。废话不多说,直接上干货。
/* * avi_writer.h */ #ifndef AVI_UIILS_WRITER_H_ #define AVI_UIILS_WRITER_H_ #ifdef VIDEO_CLIP #include "video_clip.h" #endif typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned uint32_t; typedef long long int64_t; typedef struct avi_idx{ int is_key; int pos; int size; }AVI_IDX; typedef struct avi_idx_hwx{ AVI_IDX idx; int serial; int64_t st; }AVI_IDX_HWX; /////////////////////////////////////////fopen fp IO /////////////////////////////////////////////// class avi_writer{ public : // open write 低级 io avi_writer(float fps,int width,int height); // fopen fwrite 高级 io avi_writer(int64_t offset,float fps,int width,int height); ~avi_writer(); private: union{ FILE *fp; int fd; }_f_handle; float _f_fps; char _fcc[4]; int _i_width; int _i_height; int64_t _i_movi; int64_t _i_movi_end; int64_t _i_riff; int _i_frame; int _i_idx_max; AVI_IDX* _idx; AVI_IDX_HWX* _idx_hwx; char _buff[9]; int _io_mode; int64_t _start_offset; int64_t _off_set; int _frist_serial; int _cur_serial; int64_t _frist_st; int64_t _cur_st; private: void avi_write_char(char c); void avi_write_uint16(uint16_t w); void avi_write_uint32(uint32_t dw ); void avi_write_fourcc(char fcc[4] ); int avi_write_buff(void* buff,int size); int64_t avi_tell(); int64_t avi_seek(int64_t offset); void avi_set_fourcc( void *_p, char fcc[4]); void avi_set_dw( void *_p, uint32_t dw ); void avi_set_dw64( void *_p, int64_t dw ); void avi_write_header(); void avi_write_idx(); void avi_write_idx_hwx(); public : int avi_open(const char* filename); int write_frame(void *data, int size, int b_key ); #ifdef VIDEO_CLIP int avi_write_clip(VideoClip * clip); #endif int64_t get_avi_file_size(); int64_t avi_close(); public: void avi_fflush(); int get_frist_serial(); int get_cur_serial(); int64_t get_frist_st(); int64_t get_cur_st(); int get_cur_fream_num(); //获取当前已经存盘数据的索引区 int get_cur_idx_hwx(AVI_IDX_HWX* idx,int fream_num); }; #endif
#ifndef AVI_UTILS_READER_H_ #define AVI_UTILS_READER_H_ typedef long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned uint32_t; #include "avi_writer.h" typedef struct { FILE *f; char fcc[4]; float f_fps; int i_width; int i_height; int64_t i_movi; int64_t i_movi_end; int64_t i_riff; int i_frame; int i_idx_max; uint32_t *idx; uint32_t *idx_hwx; } avi_read_t; typedef struct avi_idx1_hwx{ int is_key; int pos; int size; int serial; int64_t st; }IDX_HWX; //读取avi标准索引区 int avi_read_avi_idx1(avi_read_t* a,AVI_IDX**idx); int avi_read_idx_hwx(avi_read_t* a,IDX_HWX** idx); int avi_read( avi_read_t *a, void *buf,IDX_HWX* idx); void avi_rd_init( avi_read_t *a, FILE *f, float *f_fps,int *width,int *height); int avi_read( avi_read_t *a, void *buf, int buf_size, int* b_key ); int avi_read_frame(avi_read_t *a, void *buf, int buf_size,int64_t pos); void avi_rd_end( avi_read_t * a); #endif /* AVI_READER_H_ */
/* * avi_write.cpp *<pre name="code" class="cpp">#include <stdio.h> #include <stdlib.h> #include <string.h> #include "avi_writer.h" #include "avi_reader.h" uint16_t avi_read_uint16( avi_read_t *a) { uint16_t dw; dw=fgetc(a->f); dw|=fgetc(a->f)<<8; return dw; } uint32_t avi_read_uint32( avi_read_t *a) { uint32_t dw(0); unsigned char c = 0; c= fgetc(a->f); dw |=(c&0x000000ff); c = 0; c= fgetc(a->f); dw |= (c&0x000000ff)<<8; c = 0; c= fgetc(a->f); dw |= (c&0x000000ff)<<16; c = 0; c= fgetc(a->f); dw |= (c&0x000000ff)<<24; c = 0; /* dw = fgetc(a->f); dw |= (fgetc(a->f)&0xff)<<8; dw |= (fgetc(a->f)&0xff)<<16; dw |= (fgetc(a->f)&0xff)<<24; */ return dw; } int64_t avi_read_int64( avi_read_t *a) { int64_t dw; dw = (int64_t) fgetc(a->f); dw |=(int64_t) (fgetc(a->f)&0xff)<<8; dw |=(int64_t) (fgetc(a->f)&0xff)<<16; dw |=(int64_t) (fgetc(a->f)&0xff)<<24; dw |=(int64_t) (fgetc(a->f)&0xff)<<32; dw |=(int64_t) (fgetc(a->f)&0xff)<<40; dw |=(int64_t) (fgetc(a->f)&0xff)<<48; dw |=(int64_t) (fgetc(a->f)&0xff)<<56; return dw; } void avi_read_fourcc( avi_read_t *a, char fcc[4] ) { fcc[0]=fgetc(a->f); fcc[1]=fgetc(a->f); fcc[2]=fgetc(a->f); fcc[3]=fgetc(a->f); } static void avi_red_dw( void *_p, uint32_t dw ) { uint8_t *p =(uint8_t *)_p; p[0] = ( dw )&0xff; p[1] = ( dw >> 8 )&0xff; p[2] = ( dw >> 16)&0xff; p[3] = ( dw >> 24)&0xff; } static void avi_read_header( avi_read_t *a ) { char buf[8]; unsigned int uint32_data; avi_read_fourcc( a, buf ); a->i_riff = avi_read_uint32( a); avi_read_fourcc( a, buf ); avi_read_fourcc( a, buf ); uint32_data = avi_read_uint32( a ); avi_read_fourcc( a, buf ); avi_read_fourcc( a, buf ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a); a->i_frame = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); a->i_width = avi_read_uint32( a ); a->i_height = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); avi_read_fourcc( a, buf ); uint32_data = avi_read_uint32( a ); avi_read_fourcc( a, buf ); avi_read_fourcc( a, buf ); uint32_data = avi_read_uint32( a ); avi_read_fourcc( a, buf ); avi_read_fourcc( a, a->fcc ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); a->f_fps = (float)(avi_read_uint32( a )/1000); uint32_data = avi_read_uint32( a ); a->i_frame = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); a->i_width = avi_read_uint16( a ); a->i_height = avi_read_uint16( a ); avi_read_fourcc( a, buf ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); avi_read_uint16( a ); avi_read_uint16( a ); avi_read_fourcc( a, a->fcc ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); uint32_data = avi_read_uint32( a ); avi_read_fourcc( a, buf ); a->i_movi_end = avi_read_uint32( a ) -4; avi_read_fourcc( a, buf ); #if 0 /* Append idx chunk */ if( a->i_idx_max <= a->i_frame ) { a->i_idx_max += 1000; a->idx =(uint32_t*)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], size ); #endif } /* static void avi_read_idx( avi_read_t *a ) { char buf[8]; avi_read_fourcc( a, buf ); a->i_frame = avi_read_uint32( a ) / 16; //fwrite( a->idx, a->i_frame * 16, 1, a->f ); }*/ //读取avi标准索引区 int avi_read_avi_idx1(avi_read_t* a,AVI_IDX**idx) { char buf[8]; char* idx_buff = NULL; int i_movi_end = a->i_movi_end; int idx_pos_start; int idx_pos_end; int idx_len; //int64_t riff = a->i_riff+(56*4-4); int64_t temp; int ret; int frame_num =0; int i=0; temp=fseek(a->f,i_movi_end,SEEK_SET); memset(buf,0,8); avi_read_fourcc( a, buf ); if(strcmp(buf,"idx1")) { printf("<<<<<<<read buf is not 'idx1'>>>>>read buf is %s\n",buf); return -1; } frame_num = avi_read_uint32(a)/16; if(frame_num <=0 ) { *idx = NULL; printf("<<<<<<<read frame num faild>>>>>\n"); return frame_num; } AVI_IDX* idx_tmp = (AVI_IDX*)calloc(frame_num,sizeof(AVI_IDX)); for(i=0;i<frame_num;i++) { memset(buf,0,8); avi_read_fourcc( a, buf ); if(strcasecmp(buf,"00dc")) { printf("<<<<<<<read idx faild>>>>>\n"); break; } idx_tmp[i].is_key=avi_read_uint32(a); idx_tmp[i].pos = avi_read_uint32(a); idx_tmp[i].size = avi_read_uint32(a); } if(i!=frame_num) { free(idx_tmp); idx_tmp = NULL; return 0; } *idx = idx_tmp; return frame_num; } int avi_read_idx_hwx(avi_read_t* a,IDX_HWX** idx) { char buf[8]; char* idx_buff = NULL; int riff = a->i_riff+8; int riff2 = a->i_riff; int idx_pos_start; int idx_pos_end; int idx_len; //int64_t riff = a->i_riff+(56*4-4); int64_t temp; int ret; int frame_num =0; int i=0; temp=fseek(a->f,riff,SEEK_SET); memset(buf,0,8); avi_read_fourcc( a, buf ); if(strcmp(buf,"ihwx")) { // Ipnc_DbgPrintf2(_TraceError,"<<<<<<<read buf is not 'ihwx'>>>>>read buf is %s\n",buf); return -1; } idx_pos_start = ftell( a->f ); fseek(a->f,0,SEEK_END); idx_pos_end = ftell( a->f ); idx_len = idx_pos_end - idx_pos_start; fseek(a->f,0-idx_len,SEEK_END); frame_num = avi_read_uint32(a)/28; if(frame_num <=0 ) { *idx = NULL; return frame_num; } IDX_HWX* idx_hwx = (IDX_HWX*)calloc(frame_num,sizeof(IDX_HWX)); for(i=0;i<frame_num;i++) { memset(buf,0,8); avi_read_fourcc( a, buf ); if(strcasecmp(buf,"hwx0")) { break; } idx_hwx[i].is_key=avi_read_uint32(a); idx_hwx[i].pos = avi_read_uint32(a); idx_hwx[i].size = avi_read_uint32(a); idx_hwx[i].serial = avi_read_uint32(a); idx_hwx[i].st =(long long)avi_read_int64(a); } if(i!=frame_num) { free(idx_hwx); idx_hwx = NULL; *idx = NULL; return 0; } *idx = idx_hwx; return frame_num; } void avi_rd_init( avi_read_t *a, FILE *f, float *f_fps,int *width,int *height) { char hwx_fcc[8]; a->f = f; a->f_fps = 0; 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; a->idx_hwx = NULL; avi_read_header( a ); *f_fps=a->f_fps; *width=a->i_width; *height=a->i_height; } int avi_read( avi_read_t *a, void *buf, int buf_size, int* b_key ) { int frame_size = 0; int read_size = 0; int64_t i_pos = ftell( a->f ); char fcc[8]; char c; if (!a || !buf || (buf_size<16)) return 0; //avi_read_idx_hwx("ihwx",hwx_fcc); if (b_key) *b_key = 0; while ((frame_size<=0) && (!feof(a->f))) { avi_read_fourcc( a, fcc);// fcc[4] = '\0'; if (!strcmp(fcc, "00dc")) { frame_size = avi_read_uint32( a ); if ((frame_size>16) && (frame_size<buf_size)) { read_size = fread( buf, 1, frame_size, a->f ); if (read_size == frame_size) { if (frame_size&0x01 ) c = fgetc( a->f );/* pad */ a->i_frame++; } } } } return frame_size; } /* * sucess return frame_size * faild return -1 */ int avi_read_frame(avi_read_t *a, void *buf, int buf_size,int64_t pos) { int frame_size = 0; int read_size = 0; char fcc[8]; char c; int64_t i_pos = ftell( a->f ); if (!a || !buf || (buf_size<16)) return -1; if(i_pos!=pos) fseek(a->f,pos,SEEK_SET); avi_read_fourcc( a, fcc);// fcc[4] = '\0'; if (!strcmp(fcc, "00dc")) { frame_size = avi_read_uint32( a ); if ((frame_size>16) && (frame_size<buf_size)) { read_size = fread( buf, 1, frame_size, a->f ); if (read_size == frame_size) { if (frame_size&0x01 ) c = fgetc( a->f );/* pad */ } else { return -1; } } } else { return -1; } return frame_size; } void avi_rd_end( avi_read_t * a) { }
/* * avi_write.cpp * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "avi_writer.h" #ifdef WIN32 #include "..\..\..\media_base\media_dbg.h" #include "..\..\..\media_base\sync.h" #else #include "sync.h" #include<unistd.h> #include<string.h> #include<fcntl.h> #include<errno.h> #endif /* 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.*/ avi_writer::avi_writer(int64_t offset,float fps,int width,int height) { _i_width = width; _i_height = height; _f_fps = fps; memcpy( _fcc,"h264",4); _i_width = width; _i_height = height; _i_frame = 0; _i_movi = 0; _i_riff = 0; _i_movi_end = 0; _i_idx_max = 0; _idx = NULL; _idx_hwx = NULL; _io_mode = 0; // open write _start_offset = offset; _off_set = 0; _frist_serial=0; _cur_serial=0; _frist_st=0; _cur_st=0; } avi_writer::avi_writer(float fps,int width,int height) { _i_width = width; _i_height = height; _f_fps = fps; memcpy( _fcc,"h264",4); _i_width = width; _i_height = height; _i_frame = 0; _i_movi = 0; _i_riff = 0; _i_movi_end = 0; _i_idx_max = 0; _idx = NULL; _idx_hwx = NULL; _io_mode = 1; // fopen fwrite _start_offset = 0; _off_set = 0; _frist_serial=0; _cur_serial=0; _frist_st=0; _cur_st=0; } avi_writer::~avi_writer() { if(_idx) free(_idx); _idx = NULL; if(_idx_hwx) free(_idx_hwx); _idx_hwx = NULL; } void avi_writer::avi_write_char(char c) { if(_io_mode) { fputc( c, _f_handle.fp); } else { write(_f_handle.fd,&c,1); } _off_set += 1l; } void avi_writer::avi_write_uint16(uint16_t w) { if(_io_mode) { fputc( ( w ) & 0xff, _f_handle.fp); fputc( ( w >> 8 ) & 0xff, _f_handle.fp ); } else { _buff[0] = ( w ) & 0xff; _buff[1] = ( w >> 8 ) & 0xff; _buff[2] = '\0'; write(_f_handle.fd,_buff,2); } _off_set += 2l; } void avi_writer::avi_write_uint32(uint32_t dw ) { if(_io_mode) { fputc( ( dw ) & 0xff,_f_handle.fp ); fputc( ( dw >> 8 ) & 0xff,_f_handle.fp); fputc( ( dw >> 16) & 0xff,_f_handle.fp ); fputc( ( dw >> 24) & 0xff,_f_handle.fp); } else { _buff[0] = ( dw ) & 0xff; _buff[1] = ( dw >> 8 ) & 0xff; _buff[2] = ( dw >> 16 ) & 0xff; _buff[3] = ( dw >> 24 ) & 0xff; _buff[4] = '\0'; write(_f_handle.fd,_buff,4); } _off_set += 4l; } void avi_writer::avi_write_fourcc(char fcc[4] ) { if(_io_mode) { fputc( fcc[0],_f_handle.fp); fputc( fcc[1],_f_handle.fp); fputc( fcc[2],_f_handle.fp); fputc( fcc[3],_f_handle.fp); } else { write(_f_handle.fd,fcc,4); } _off_set += 4l; } int avi_writer::avi_write_buff(void* buff,int size) { int ret=0; if(_io_mode) { ret = fwrite(buff,1,size,_f_handle.fp); } else { ret = write(_f_handle.fd,buff,size); } if(ret!=size) { Ipnc_DbgPrintf2(_TraceInfo, "write error\n"); } _off_set +=(int64_t)ret; return ret; } void avi_writer::avi_write_header() { avi_write_fourcc("RIFF" ); avi_write_uint32(_i_riff > 0 ? _i_riff - 8 : 0xFFFFFFFF ); avi_write_fourcc("AVI " ); avi_write_fourcc("LIST" ); avi_write_uint32( 4 + 4*16 + 12 + 4*16 + 4*12 ); avi_write_fourcc("hdrl" ); avi_write_fourcc("avih" ); avi_write_uint32(4*16 - 8 ); avi_write_uint32(1000000 / _f_fps ); avi_write_uint32(0xffffffff ); avi_write_uint32(0 ); avi_write_uint32(AVIF_HASINDEX|AVIF_ISINTERLEAVED|AVIF_TRUSTCKTYPE); avi_write_uint32(_i_frame ); avi_write_uint32(0 ); avi_write_uint32(1 ); avi_write_uint32(1000000 ); avi_write_uint32(_i_width ); avi_write_uint32(_i_height ); avi_write_uint32(0 ); avi_write_uint32(0 ); avi_write_uint32(0 ); avi_write_uint32(0 ); avi_write_fourcc("LIST" ); avi_write_uint32( 4 + 4*16 + 4*12 ); avi_write_fourcc("strl" ); avi_write_fourcc("strh" ); avi_write_uint32( 4*16 - 8 ); avi_write_fourcc("vids" ); avi_write_fourcc(_fcc ); avi_write_uint32(0 ); avi_write_uint32(0 ); avi_write_uint32(0 ); avi_write_uint32(1000 ); avi_write_uint32(_f_fps * 1000 ); avi_write_uint32(0 ); avi_write_uint32(_i_frame ); avi_write_uint32(1024*1024 ); avi_write_uint32(-1 ); avi_write_uint32(_i_width * _i_height ); avi_write_uint32(0 ); avi_write_uint16(_i_width ); avi_write_uint16(_i_height ); avi_write_fourcc("strf" ); avi_write_uint32( 4*12 - 8 ); avi_write_uint32( 4*12 - 8 ); avi_write_uint32( _i_width ); avi_write_uint32( _i_height ); avi_write_uint16( 1 ); avi_write_uint16( 24 ); avi_write_fourcc( _fcc ); avi_write_uint32(_i_width * _i_height ); avi_write_uint32( 0 ); avi_write_uint32( 0 ); avi_write_uint32( 0 ); avi_write_uint32( 0 ); avi_write_fourcc("LIST" ); avi_write_uint32( _i_movi_end > 0 ? _i_movi_end - _i_movi + 4: 0xFFFFFFFF ); avi_write_fourcc("movi" ); } void avi_writer::avi_set_fourcc( void *_p, char fcc[4] ) { uint8_t *p =(uint8_t *)_p; p[0] = fcc[0]; p[1] = fcc[1]; p[2] = fcc[2]; p[3] = fcc[3]; } void avi_writer::avi_set_dw( void *_p, uint32_t dw ) { uint8_t *p =(uint8_t *)_p; p[0] = ( dw )&0xff; p[1] = ( dw >> 8 )&0xff; p[2] = ( dw >> 16)&0xff; p[3] = ( dw >> 24)&0xff; } void avi_writer::avi_set_dw64( void *_p, int64_t dw ) { uint8_t *p =(uint8_t *)_p; p[0] = ( dw )&0xff; p[1] = ( dw >> 8 )&0xff; p[2] = ( dw >> 16)&0xff; p[3] = ( dw >> 24)&0xff; p[4] = ( dw >> 32)&0xff; p[5] = ( dw >> 40)&0xff; p[6] = ( dw >> 48)&0xff; p[7] = ( dw >> 56)&0xff; } int64_t avi_writer::avi_tell() { int64_t pos = 0; if(_io_mode) { pos =(int64_t)ftell(_f_handle.fp); } else { pos = _off_set; } return pos; } int64_t avi_writer::avi_seek(int64_t offset ) { if(_io_mode) fseek(_f_handle.fp, offset, SEEK_SET); else lseek64(_f_handle.fd,_start_offset+offset,SEEK_SET); } void avi_writer::avi_write_idx() { int i=0; uint32_t* buff = NULL; avi_write_fourcc("idx1" ); avi_write_uint32(_i_frame * 16 ); buff = (uint32_t*)calloc(sizeof(uint32_t),_i_frame*16); if(!buff) { Ipnc_DbgPrintf2(_TraceInfo, "no mem....\n"); return ; } for(i=0;i<_i_frame;i++) { avi_set_fourcc(&buff[4*i+0],"00dc"); avi_set_dw(&buff[4*i+1], _idx[i].is_key); avi_set_dw(&buff[4*i+2], _idx[i].pos ); avi_set_dw(&buff[4*i+3], _idx[i].size ); } avi_write_buff(buff,sizeof(uint32_t)*_i_frame * 16); free(buff); free(_idx); _idx = NULL; } void avi_writer::avi_write_idx_hwx() { int i=0; uint32_t* buff = NULL; if(!_idx_hwx) return; avi_write_fourcc("ihwx"); avi_write_uint32(_i_frame); buff = (uint32_t*)calloc(sizeof(uint32_t),_i_frame*28); if(!buff) { Ipnc_DbgPrintf2(_TraceInfo, "no mem....\n"); return ; } Ipnc_DbgPrintf2(_TraceInfo, "frist serial:%d end serial:%d frist st:%lld cur st:%lld\n", _frist_serial,_cur_serial,_frist_st,_cur_st); for(i=0;i<_i_frame;i++) { avi_set_fourcc(&buff[7*i+0],"hwx0"); avi_set_dw(&buff[7*i+1], _idx_hwx[i].idx.is_key); avi_set_dw(&buff[7*i+2], _idx_hwx[i].idx.pos ); avi_set_dw(&buff[7*i+3], _idx_hwx[i].idx.size ); avi_set_dw(&buff[7*i+4], _idx_hwx[i].serial); avi_set_dw64(&buff[7*i+5], _idx_hwx[i].st); } avi_write_buff(buff,sizeof(uint32_t)*_i_frame*28); free(buff); free(_idx_hwx); _idx_hwx = NULL; } int avi_writer::avi_open(const char* filename) { if(!filename) { Ipnc_DbgPrintf2(_TraceError, "invalid filename\n"); return -1; } if(_io_mode) { _f_handle.fp = fopen(filename,"wb+"); if(!_f_handle.fp) { Ipnc_DbgPrintf2(_TraceError, "create avi file failed 1: error=%d, file=%s!!!\n", errno, filename); return -1; } } else { _f_handle.fd = open(filename,O_CREAT|O_RDWR); if(_f_handle.fd < 0 ) { Ipnc_DbgPrintf2(_TraceError, "create avi file failed 2: error=%d, file=%s!!!\n", errno, filename); return -1; } } Ipnc_DbgPrintf2(_TraceError, "create avi file success: %s\n", filename); avi_seek(0); avi_write_header(); return 0; } int avi_writer::write_frame(void *data, int size, int b_key ) { int ret=0; int64_t i_pos = avi_tell(); /* chunk header */ avi_write_fourcc("00dc" ); avi_write_uint32(size); ret = avi_write_buff(data,size); if(size&0x01 ) { /* pad */ avi_write_char(0); } /* Append idx chunk */ if( _i_idx_max <= _i_frame ) { _i_idx_max += 1000; _idx =(AVI_IDX*)realloc(_idx,_i_idx_max*sizeof(AVI_IDX)); } _idx[_i_frame].is_key = b_key ? AVIIF_KEYFRAME : 0 ; _idx[_i_frame].pos = i_pos; _idx[_i_frame].size = size; _i_frame++; return ret; } #ifdef VIDEO_CLIP int avi_writer::avi_write_clip(VideoClip * clip) { int ret=0; int j=0,size=0,serial=0; int64_t timest=0; int is_key=0; int64_t i_pos = avi_tell(); //Ipnc_DbgPrintf2(_TraceInfo, "write clip pos:%lld offset:%lld\n",i_pos,_off_set); /* chunk header */ ret = avi_write_buff( clip->get_buff_head(),clip->size()); /* Ipnc_DbgPrintf2(_TraceInfo, "clip frame num:%d start: serial:%d st:%lld end serial:%d st:%lld\n", clip->frame_count(), clip->get_frame_serial(0), clip->get_frame_timest(0), clip->get_frame_serial(clip->frame_count()-1), clip->get_frame_timest(clip->frame_count()-1)); Ipnc_DbgPrintf2(_TraceInfo, "avi file frame num :%d\n",_i_frame); */ for (j=0; j<clip->frame_count(); j++) { /* Append idx chunk */ if( _i_idx_max <= _i_frame ) { _i_idx_max += 1000; _idx =(AVI_IDX*)realloc(_idx,_i_idx_max*sizeof(AVI_IDX)); _idx_hwx =(AVI_IDX_HWX*)realloc(_idx_hwx, _i_idx_max * sizeof(AVI_IDX_HWX)); } is_key = clip->get_frame_key(j); size = clip->get_frame_size(j); serial = clip->get_frame_serial(j); timest = clip->get_frame_timest(j); if(!_frist_serial) _frist_serial=serial; _cur_serial=serial; if(!_frist_st) _frist_st=timest; _cur_st=timest; _idx[_i_frame].is_key = is_key ? AVIIF_KEYFRAME : 0 ; _idx[_i_frame].pos = i_pos; _idx[_i_frame].size = size; _idx_hwx[_i_frame].idx.is_key = is_key ? AVIIF_KEYFRAME : 0 ; _idx_hwx[_i_frame].idx.pos = i_pos; _idx_hwx[_i_frame].idx.size = size; _idx_hwx[_i_frame].serial = serial; _idx_hwx[_i_frame].st = timest; i_pos += (size+8+(size&0x01)); _i_frame++; } return ret; } #endif int64_t avi_writer::avi_close() { int64_t file_size = 0; _i_movi_end = avi_tell(); /* write index */ avi_write_idx(); _i_riff = avi_tell(); //Ipnc_DbgPrintf2(_TraceInfo, "avi end:%lld offset:%lld\n",_i_riff,_off_set); //idx hwx //avi_write_idx_hwx(); file_size = avi_tell(); //Ipnc_DbgPrintf2(_TraceInfo, "avi file len :%lld offset:%lld\n",file_size,_off_set); /* Fix header */ avi_seek(0); avi_write_header(); if(_io_mode) { fclose(_f_handle.fp); _f_handle.fp = NULL; } else { close(_f_handle.fd); _f_handle.fd = 0; } return file_size; } int64_t avi_writer::get_avi_file_size() { return _off_set; } void avi_writer::avi_fflush() { if(_io_mode) { fflush(_f_handle.fp); } } int avi_writer::get_frist_serial() { return _frist_serial; } int avi_writer::get_cur_serial() { return _cur_serial; } int64_t avi_writer::get_frist_st() { return _frist_st; } int64_t avi_writer::get_cur_st() { return _cur_st; } int avi_writer::get_cur_fream_num() { return _i_frame; } int avi_writer::get_cur_idx_hwx(AVI_IDX_HWX* idx,int fream_num) { if(fream_num <=0 || !idx) { Ipnc_DbgPrintf2(_TraceInfo,"invalid idx or frame num.....\n"); return -1; } if(!_idx_hwx) { Ipnc_DbgPrintf2(_TraceInfo,"invalid _idx_hwx.....\n"); return -1; } memcpy(idx,_idx_hwx,fream_num* sizeof(AVI_IDX_HWX)); return 0; }
原文地址:http://blog.csdn.net/zhujinghao_09/article/details/44458245