您的位置:首页 > 其它

H264 数据avi文件封装和拆解

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

[cpp] view
plaincopyprint?

/*

* 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

[cpp] view
plaincopyprint?

#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_ */

[cpp] view
plaincopyprint?

/*

* 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)

{

}

[cpp] view
plaincopyprint?

/*

* 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: