|
|
|
@ -36,6 +36,7 @@ |
|
|
|
#include <vlc_sout.h> |
|
|
|
#include <vlc_block.h> |
|
|
|
#include <vlc_codecs.h> |
|
|
|
#include <vlc_bits.h> |
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* Module descriptor |
|
|
|
@ -571,106 +572,6 @@ static int Mux ( sout_mux_t *p_mux ) |
|
|
|
return( 0 ); |
|
|
|
} |
|
|
|
|
|
|
|
/****************************************************************************/ |
|
|
|
/****************************************************************************/ |
|
|
|
/****************************************************************************/ |
|
|
|
/****************************************************************************/ |
|
|
|
|
|
|
|
typedef struct buffer_out_s |
|
|
|
{ |
|
|
|
int i_buffer_size; |
|
|
|
block_t *p_block; |
|
|
|
} buffer_out_t; |
|
|
|
|
|
|
|
static void bo_Init( buffer_out_t *p_bo, int i_size ) |
|
|
|
{ |
|
|
|
p_bo->p_block = block_Alloc( i_size ); |
|
|
|
p_bo->p_block->i_buffer = 0; |
|
|
|
p_bo->i_buffer_size = i_size; |
|
|
|
} |
|
|
|
|
|
|
|
static void bo_SetByte( buffer_out_t *p_bo, int i_offset, uint8_t i ) |
|
|
|
{ |
|
|
|
if( i_offset >= p_bo->i_buffer_size ) |
|
|
|
{ |
|
|
|
int i_growth = HDR_BASE_SIZE; |
|
|
|
while( i_offset >= p_bo->i_buffer_size + i_growth ) |
|
|
|
{ |
|
|
|
i_growth += HDR_BASE_SIZE; |
|
|
|
} |
|
|
|
int i = p_bo->p_block->i_buffer; /* Realloc would set payload size == buffer size */ |
|
|
|
p_bo->p_block = block_Realloc( p_bo->p_block, 0, p_bo->i_buffer_size + i_growth ); |
|
|
|
p_bo->p_block->i_buffer = i; |
|
|
|
p_bo->i_buffer_size += i_growth; |
|
|
|
} |
|
|
|
p_bo->p_block->p_buffer[i_offset] = i; |
|
|
|
} |
|
|
|
static void bo_AddByte( buffer_out_t *p_bo, uint8_t i ) |
|
|
|
{ |
|
|
|
bo_SetByte( p_bo, p_bo->p_block->i_buffer, i ); |
|
|
|
p_bo->p_block->i_buffer++; |
|
|
|
} |
|
|
|
static void bo_SetWordLE( buffer_out_t *p_bo, int i_offset, uint16_t i ) |
|
|
|
{ |
|
|
|
bo_SetByte( p_bo, i_offset, i &0xff ); |
|
|
|
bo_SetByte( p_bo, i_offset + 1, ( ( i >> 8) &0xff ) ); |
|
|
|
} |
|
|
|
static void bo_AddWordLE( buffer_out_t *p_bo, uint16_t i ) |
|
|
|
{ |
|
|
|
bo_AddByte( p_bo, i &0xff ); |
|
|
|
bo_AddByte( p_bo, ( ( i >> 8) &0xff ) ); |
|
|
|
} |
|
|
|
static void bo_AddWordBE( buffer_out_t *p_bo, uint16_t i ) |
|
|
|
{ |
|
|
|
bo_AddByte( p_bo, ( ( i >> 8) &0xff ) ); |
|
|
|
bo_AddByte( p_bo, i &0xff ); |
|
|
|
} |
|
|
|
static void bo_SetDWordLE( buffer_out_t *p_bo, int i_offset, uint32_t i ) |
|
|
|
{ |
|
|
|
bo_SetWordLE( p_bo, i_offset, i &0xffff ); |
|
|
|
bo_SetWordLE( p_bo, i_offset + 2, ( ( i >> 16) &0xffff ) ); |
|
|
|
} |
|
|
|
static void bo_AddDWordLE( buffer_out_t *p_bo, uint32_t i ) |
|
|
|
{ |
|
|
|
bo_AddWordLE( p_bo, i &0xffff ); |
|
|
|
bo_AddWordLE( p_bo, ( ( i >> 16) &0xffff ) ); |
|
|
|
} |
|
|
|
static void bo_AddDWordBE( buffer_out_t *p_bo, uint32_t i ) |
|
|
|
{ |
|
|
|
bo_AddWordBE( p_bo, ( ( i >> 16) &0xffff ) ); |
|
|
|
bo_AddWordBE( p_bo, i &0xffff ); |
|
|
|
} |
|
|
|
#if 0 |
|
|
|
static void bo_AddLWordLE( buffer_out_t *p_bo, uint64_t i ) |
|
|
|
{ |
|
|
|
bo_AddDWordLE( p_bo, i &0xffffffff ); |
|
|
|
bo_AddDWordLE( p_bo, ( ( i >> 32) &0xffffffff ) ); |
|
|
|
} |
|
|
|
static void bo_AddLWordBE( buffer_out_t *p_bo, uint64_t i ) |
|
|
|
{ |
|
|
|
bo_AddDWordBE( p_bo, ( ( i >> 32) &0xffffffff ) ); |
|
|
|
bo_AddDWordBE( p_bo, i &0xffffffff ); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
static void bo_AddFCC( buffer_out_t *p_bo, const char *fcc ) |
|
|
|
{ |
|
|
|
bo_AddByte( p_bo, fcc[0] ); |
|
|
|
bo_AddByte( p_bo, fcc[1] ); |
|
|
|
bo_AddByte( p_bo, fcc[2] ); |
|
|
|
bo_AddByte( p_bo, fcc[3] ); |
|
|
|
} |
|
|
|
|
|
|
|
static void bo_AddMem( buffer_out_t *p_bo, int i_size, uint8_t *p_mem ) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
|
|
|
|
for( i = 0; i < i_size; i++ ) |
|
|
|
{ |
|
|
|
bo_AddByte( p_bo, p_mem[i] ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
**************************************************************************** |
|
|
|
** |
|
|
|
@ -680,21 +581,21 @@ static void bo_AddMem( buffer_out_t *p_bo, int i_size, uint8_t *p_mem ) |
|
|
|
****************************************************************************/ |
|
|
|
#define AVI_BOX_ENTER( fcc ) \ |
|
|
|
int i_datasize_offset; \ |
|
|
|
bo_AddFCC( p_bo, fcc ); \ |
|
|
|
i_datasize_offset = p_bo->p_block->i_buffer; \ |
|
|
|
bo_AddDWordLE( p_bo, 0 ) |
|
|
|
bo_add_fourcc( p_bo, fcc ); \ |
|
|
|
i_datasize_offset = p_bo->b->i_buffer; \ |
|
|
|
bo_add_32le( p_bo, 0 ) |
|
|
|
|
|
|
|
#define AVI_BOX_ENTER_LIST( fcc ) \ |
|
|
|
AVI_BOX_ENTER( "LIST" ); \ |
|
|
|
bo_AddFCC( p_bo, fcc ) |
|
|
|
bo_add_fourcc( p_bo, fcc ) |
|
|
|
|
|
|
|
#define AVI_BOX_EXIT( i_err ) \ |
|
|
|
if( p_bo->p_block->i_buffer&0x01 ) bo_AddByte( p_bo, 0 ); \ |
|
|
|
bo_SetDWordLE( p_bo, i_datasize_offset, p_bo->p_block->i_buffer - i_datasize_offset - 4 ); \ |
|
|
|
if( p_bo->b->i_buffer&0x01 ) bo_add_8( p_bo, 0 ); \ |
|
|
|
bo_set_32le( p_bo, i_datasize_offset, p_bo->b->i_buffer - i_datasize_offset - 4 ); \ |
|
|
|
return( i_err ); |
|
|
|
|
|
|
|
static int avi_HeaderAdd_avih( sout_mux_t *p_mux, |
|
|
|
buffer_out_t *p_bo ) |
|
|
|
bo_t *p_bo ) |
|
|
|
{ |
|
|
|
sout_mux_sys_t *p_sys = p_mux->p_sys; |
|
|
|
avi_stream_t *p_video = NULL; |
|
|
|
@ -737,34 +638,34 @@ static int avi_HeaderAdd_avih( sout_mux_t *p_mux, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bo_AddDWordLE( p_bo, i_microsecperframe ); |
|
|
|
bo_AddDWordLE( p_bo, i_maxbytespersec ); |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* padding */ |
|
|
|
bo_AddDWordLE( p_bo, AVIF_TRUSTCKTYPE | |
|
|
|
AVIF_HASINDEX | |
|
|
|
AVIF_ISINTERLEAVED ); /* flags */ |
|
|
|
bo_AddDWordLE( p_bo, i_totalframes ); |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* initial frame */ |
|
|
|
bo_AddDWordLE( p_bo, p_sys->i_streams ); /* streams count */ |
|
|
|
bo_AddDWordLE( p_bo, 1024 * 1024 ); /* suggested buffer size */ |
|
|
|
bo_add_32le( p_bo, i_microsecperframe ); |
|
|
|
bo_add_32le( p_bo, i_maxbytespersec ); |
|
|
|
bo_add_32le( p_bo, 0 ); /* padding */ |
|
|
|
bo_add_32le( p_bo, AVIF_TRUSTCKTYPE | |
|
|
|
AVIF_HASINDEX | |
|
|
|
AVIF_ISINTERLEAVED ); /* flags */ |
|
|
|
bo_add_32le( p_bo, i_totalframes ); |
|
|
|
bo_add_32le( p_bo, 0 ); /* initial frame */ |
|
|
|
bo_add_32le( p_bo, p_sys->i_streams ); /* streams count */ |
|
|
|
bo_add_32le( p_bo, 1024 * 1024 ); /* suggested buffer size */ |
|
|
|
if( p_video ) |
|
|
|
{ |
|
|
|
bo_AddDWordLE( p_bo, p_video->p_bih->biWidth ); |
|
|
|
bo_AddDWordLE( p_bo, p_video->p_bih->biHeight ); |
|
|
|
bo_add_32le( p_bo, p_video->p_bih->biWidth ); |
|
|
|
bo_add_32le( p_bo, p_video->p_bih->biHeight ); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
bo_AddDWordLE( p_bo, 0 ); |
|
|
|
bo_AddDWordLE( p_bo, 0 ); |
|
|
|
bo_add_32le( p_bo, 0 ); |
|
|
|
bo_add_32le( p_bo, 0 ); |
|
|
|
} |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* ???? */ |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* ???? */ |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* ???? */ |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* ???? */ |
|
|
|
bo_add_32le( p_bo, 0 ); /* ???? */ |
|
|
|
bo_add_32le( p_bo, 0 ); /* ???? */ |
|
|
|
bo_add_32le( p_bo, 0 ); /* ???? */ |
|
|
|
bo_add_32le( p_bo, 0 ); /* ???? */ |
|
|
|
|
|
|
|
AVI_BOX_EXIT( 0 ); |
|
|
|
} |
|
|
|
static int avi_HeaderAdd_strh( buffer_out_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
static int avi_HeaderAdd_strh( bo_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
{ |
|
|
|
AVI_BOX_ENTER( "strh" ); |
|
|
|
|
|
|
|
@ -772,23 +673,23 @@ static int avi_HeaderAdd_strh( buffer_out_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
{ |
|
|
|
case VIDEO_ES: |
|
|
|
{ |
|
|
|
bo_AddFCC( p_bo, "vids" ); |
|
|
|
bo_AddDWordBE( p_bo, p_stream->p_bih->biCompression ); |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* flags */ |
|
|
|
bo_AddWordLE( p_bo, 0 ); /* priority */ |
|
|
|
bo_AddWordLE( p_bo, 0 ); /* langage */ |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* initial frame */ |
|
|
|
bo_AddDWordLE( p_bo, 1000 );/* scale */ |
|
|
|
bo_AddDWordLE( p_bo, (uint32_t)( 1000 * p_stream->f_fps )); |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* start */ |
|
|
|
bo_AddDWordLE( p_bo, p_stream->i_frames ); |
|
|
|
bo_AddDWordLE( p_bo, 1024 * 1024 ); |
|
|
|
bo_AddDWordLE( p_bo, -1 ); /* quality */ |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* samplesize */ |
|
|
|
bo_AddWordLE( p_bo, 0 ); /* ??? */ |
|
|
|
bo_AddWordLE( p_bo, 0 ); /* ??? */ |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_bih->biWidth ); |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_bih->biHeight ); |
|
|
|
bo_add_fourcc( p_bo, "vids" ); |
|
|
|
bo_add_32be( p_bo, p_stream->p_bih->biCompression ); |
|
|
|
bo_add_32le( p_bo, 0 ); /* flags */ |
|
|
|
bo_add_16le( p_bo, 0 ); /* priority */ |
|
|
|
bo_add_16le( p_bo, 0 ); /* langage */ |
|
|
|
bo_add_32le( p_bo, 0 ); /* initial frame */ |
|
|
|
bo_add_32le( p_bo, 1000 );/* scale */ |
|
|
|
bo_add_32le( p_bo, (uint32_t)( 1000 * p_stream->f_fps )); |
|
|
|
bo_add_32le( p_bo, 0 ); /* start */ |
|
|
|
bo_add_32le( p_bo, p_stream->i_frames ); |
|
|
|
bo_add_32le( p_bo, 1024 * 1024 ); |
|
|
|
bo_add_32le( p_bo, -1 ); /* quality */ |
|
|
|
bo_add_32le( p_bo, 0 ); /* samplesize */ |
|
|
|
bo_add_16le( p_bo, 0 ); /* ??? */ |
|
|
|
bo_add_16le( p_bo, 0 ); /* ??? */ |
|
|
|
bo_add_16le( p_bo, p_stream->p_bih->biWidth ); |
|
|
|
bo_add_16le( p_bo, p_stream->p_bih->biHeight ); |
|
|
|
} |
|
|
|
break; |
|
|
|
case AUDIO_ES: |
|
|
|
@ -807,23 +708,23 @@ static int avi_HeaderAdd_strh( buffer_out_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
i_scale = 1000; |
|
|
|
i_rate = 1000 * p_stream->i_bitrate / 8; |
|
|
|
} |
|
|
|
bo_AddFCC( p_bo, "auds" ); |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* tag */ |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* flags */ |
|
|
|
bo_AddWordLE( p_bo, 0 ); /* priority */ |
|
|
|
bo_AddWordLE( p_bo, 0 ); /* langage */ |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* initial frame */ |
|
|
|
bo_AddDWordLE( p_bo, i_scale );/* scale */ |
|
|
|
bo_AddDWordLE( p_bo, i_rate ); |
|
|
|
bo_AddDWordLE( p_bo, 0 ); /* start */ |
|
|
|
bo_AddDWordLE( p_bo, p_stream->i_frames ); |
|
|
|
bo_AddDWordLE( p_bo, 10 * 1024 ); |
|
|
|
bo_AddDWordLE( p_bo, -1 ); /* quality */ |
|
|
|
bo_AddDWordLE( p_bo, i_samplesize ); |
|
|
|
bo_AddWordLE( p_bo, 0 ); /* ??? */ |
|
|
|
bo_AddWordLE( p_bo, 0 ); /* ??? */ |
|
|
|
bo_AddWordLE( p_bo, 0 ); |
|
|
|
bo_AddWordLE( p_bo, 0 ); |
|
|
|
bo_add_fourcc( p_bo, "auds" ); |
|
|
|
bo_add_32le( p_bo, 0 ); /* tag */ |
|
|
|
bo_add_32le( p_bo, 0 ); /* flags */ |
|
|
|
bo_add_16le( p_bo, 0 ); /* priority */ |
|
|
|
bo_add_16le( p_bo, 0 ); /* langage */ |
|
|
|
bo_add_32le( p_bo, 0 ); /* initial frame */ |
|
|
|
bo_add_32le( p_bo, i_scale );/* scale */ |
|
|
|
bo_add_32le( p_bo, i_rate ); |
|
|
|
bo_add_32le( p_bo, 0 ); /* start */ |
|
|
|
bo_add_32le( p_bo, p_stream->i_frames ); |
|
|
|
bo_add_32le( p_bo, 10 * 1024 ); |
|
|
|
bo_add_32le( p_bo, -1 ); /* quality */ |
|
|
|
bo_add_32le( p_bo, i_samplesize ); |
|
|
|
bo_add_16le( p_bo, 0 ); /* ??? */ |
|
|
|
bo_add_16le( p_bo, 0 ); /* ??? */ |
|
|
|
bo_add_16le( p_bo, 0 ); |
|
|
|
bo_add_16le( p_bo, 0 ); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
@ -831,51 +732,51 @@ static int avi_HeaderAdd_strh( buffer_out_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
AVI_BOX_EXIT( 0 ); |
|
|
|
} |
|
|
|
|
|
|
|
static int avi_HeaderAdd_strf( buffer_out_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
static int avi_HeaderAdd_strf( bo_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
{ |
|
|
|
AVI_BOX_ENTER( "strf" ); |
|
|
|
|
|
|
|
switch( p_stream->i_cat ) |
|
|
|
{ |
|
|
|
case AUDIO_ES: |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_wf->wFormatTag ); |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_wf->nChannels ); |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_wf->nSamplesPerSec ); |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_wf->nAvgBytesPerSec ); |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_wf->nBlockAlign ); |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_wf->wBitsPerSample ); |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_wf->cbSize ); |
|
|
|
bo_AddMem( p_bo, p_stream->p_wf->cbSize, (uint8_t*)&p_stream->p_wf[1] ); |
|
|
|
bo_add_16le( p_bo, p_stream->p_wf->wFormatTag ); |
|
|
|
bo_add_16le( p_bo, p_stream->p_wf->nChannels ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_wf->nSamplesPerSec ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_wf->nAvgBytesPerSec ); |
|
|
|
bo_add_16le( p_bo, p_stream->p_wf->nBlockAlign ); |
|
|
|
bo_add_16le( p_bo, p_stream->p_wf->wBitsPerSample ); |
|
|
|
bo_add_16le( p_bo, p_stream->p_wf->cbSize ); |
|
|
|
bo_add_mem( p_bo, p_stream->p_wf->cbSize, (uint8_t*)&p_stream->p_wf[1] ); |
|
|
|
break; |
|
|
|
case VIDEO_ES: |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biSize ); |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biWidth ); |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biHeight ); |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_bih->biPlanes ); |
|
|
|
bo_AddWordLE( p_bo, p_stream->p_bih->biBitCount ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biSize ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biWidth ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biHeight ); |
|
|
|
bo_add_16le( p_bo, p_stream->p_bih->biPlanes ); |
|
|
|
bo_add_16le( p_bo, p_stream->p_bih->biBitCount ); |
|
|
|
if( VLC_FOURCC( 0, 0, 0, 1 ) == 0x00000001 ) |
|
|
|
{ |
|
|
|
bo_AddDWordBE( p_bo, p_stream->p_bih->biCompression ); |
|
|
|
bo_add_32be( p_bo, p_stream->p_bih->biCompression ); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biCompression ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biCompression ); |
|
|
|
} |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biSizeImage ); |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biXPelsPerMeter ); |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biYPelsPerMeter ); |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biClrUsed ); |
|
|
|
bo_AddDWordLE( p_bo, p_stream->p_bih->biClrImportant ); |
|
|
|
bo_AddMem( p_bo, |
|
|
|
p_stream->p_bih->biSize - sizeof( VLC_BITMAPINFOHEADER ), |
|
|
|
(uint8_t*)&p_stream->p_bih[1] ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biSizeImage ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biXPelsPerMeter ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biYPelsPerMeter ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biClrUsed ); |
|
|
|
bo_add_32le( p_bo, p_stream->p_bih->biClrImportant ); |
|
|
|
bo_add_mem( p_bo, |
|
|
|
p_stream->p_bih->biSize - sizeof( VLC_BITMAPINFOHEADER ), |
|
|
|
(uint8_t*)&p_stream->p_bih[1] ); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
AVI_BOX_EXIT( 0 ); |
|
|
|
} |
|
|
|
|
|
|
|
static int avi_HeaderAdd_strl( buffer_out_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
static int avi_HeaderAdd_strl( bo_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
{ |
|
|
|
AVI_BOX_ENTER_LIST( "strl" ); |
|
|
|
|
|
|
|
@ -885,18 +786,18 @@ static int avi_HeaderAdd_strl( buffer_out_t *p_bo, avi_stream_t *p_stream ) |
|
|
|
AVI_BOX_EXIT( 0 ); |
|
|
|
} |
|
|
|
|
|
|
|
static int avi_HeaderAdd_meta( buffer_out_t *p_bo, const char psz_meta[4], |
|
|
|
static int avi_HeaderAdd_meta( bo_t *p_bo, const char psz_meta[4], |
|
|
|
const char *psz_data ) |
|
|
|
{ |
|
|
|
if ( psz_data == NULL ) return 1; |
|
|
|
const char *psz = psz_data; |
|
|
|
AVI_BOX_ENTER( psz_meta ); |
|
|
|
while (*psz) bo_AddByte( p_bo, *psz++ ); |
|
|
|
bo_AddByte( p_bo, 0 ); |
|
|
|
while (*psz) bo_add_8( p_bo, *psz++ ); |
|
|
|
bo_add_8( p_bo, 0 ); |
|
|
|
AVI_BOX_EXIT( 0 ); |
|
|
|
} |
|
|
|
|
|
|
|
static int avi_HeaderAdd_INFO( sout_mux_t *p_mux, buffer_out_t *p_bo ) |
|
|
|
static int avi_HeaderAdd_INFO( sout_mux_t *p_mux, bo_t *p_bo ) |
|
|
|
{ |
|
|
|
char *psz; |
|
|
|
|
|
|
|
@ -931,7 +832,7 @@ static block_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux ) |
|
|
|
sout_mux_sys_t *p_sys = p_mux->p_sys; |
|
|
|
int i_stream; |
|
|
|
int i_junk; |
|
|
|
buffer_out_t bo; |
|
|
|
bo_t bo; |
|
|
|
|
|
|
|
struct |
|
|
|
{ |
|
|
|
@ -940,23 +841,23 @@ static block_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux ) |
|
|
|
int i_hdrldatastart; |
|
|
|
} offsets; |
|
|
|
|
|
|
|
bo_Init( &bo, HDR_BASE_SIZE ); |
|
|
|
bo_init( &bo, HDR_BASE_SIZE ); |
|
|
|
|
|
|
|
bo_AddFCC( &bo, "RIFF" ); |
|
|
|
offsets.i_riffsize = bo.p_block->i_buffer; |
|
|
|
bo_AddDWordLE( &bo, 0xEFBEADDE ); |
|
|
|
bo_AddFCC( &bo, "AVI " ); |
|
|
|
bo_add_fourcc( &bo, "RIFF" ); |
|
|
|
offsets.i_riffsize = bo.b->i_buffer; |
|
|
|
bo_add_32le( &bo, 0xEFBEADDE ); |
|
|
|
bo_add_fourcc( &bo, "AVI " ); |
|
|
|
|
|
|
|
bo_AddFCC( &bo, "LIST" ); |
|
|
|
bo_add_fourcc( &bo, "LIST" ); |
|
|
|
/* HDRL List size should exclude following data in HDR buffer
|
|
|
|
* -12 (RIFF, RIFF size, 'AVI ' tag), |
|
|
|
* - 8 (hdr1 LIST tag and its size) |
|
|
|
* - 12 (movi LIST tag, size, 'movi' listType ) |
|
|
|
*/ |
|
|
|
offsets.i_hdrllistsize = bo.p_block->i_buffer; |
|
|
|
bo_AddDWordLE( &bo, 0xEFBEADDE ); |
|
|
|
bo_AddFCC( &bo, "hdrl" ); |
|
|
|
offsets.i_hdrldatastart = bo.p_block->i_buffer; |
|
|
|
offsets.i_hdrllistsize = bo.b->i_buffer; |
|
|
|
bo_add_32le( &bo, 0xEFBEADDE ); |
|
|
|
bo_add_fourcc( &bo, "hdrl" ); |
|
|
|
offsets.i_hdrldatastart = bo.b->i_buffer; |
|
|
|
|
|
|
|
avi_HeaderAdd_avih( p_mux, &bo ); |
|
|
|
for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ ) |
|
|
|
@ -965,53 +866,53 @@ static block_t *avi_HeaderCreateRIFF( sout_mux_t *p_mux ) |
|
|
|
} |
|
|
|
|
|
|
|
/* align on 16 bytes */ |
|
|
|
int i_align = ( ( bo.p_block->i_buffer + 12 + 0xE ) & ~ 0xF ); |
|
|
|
i_junk = i_align - bo.p_block->i_buffer; |
|
|
|
bo_AddFCC( &bo, "JUNK" ); |
|
|
|
bo_AddDWordLE( &bo, i_junk ); |
|
|
|
int i_align = ( ( bo.b->i_buffer + 12 + 0xE ) & ~ 0xF ); |
|
|
|
i_junk = i_align - bo.b->i_buffer; |
|
|
|
bo_add_fourcc( &bo, "JUNK" ); |
|
|
|
bo_add_32le( &bo, i_junk ); |
|
|
|
for( int i=0; i< i_junk; i++ ) |
|
|
|
{ |
|
|
|
bo_AddByte( &bo, 0 ); |
|
|
|
bo_add_8( &bo, 0 ); |
|
|
|
} |
|
|
|
|
|
|
|
/* Now set hdrl size */ |
|
|
|
bo_SetDWordLE( &bo, offsets.i_hdrllistsize, |
|
|
|
bo.p_block->i_buffer - offsets.i_hdrldatastart ); |
|
|
|
bo_set_32le( &bo, offsets.i_hdrllistsize, |
|
|
|
bo.b->i_buffer - offsets.i_hdrldatastart ); |
|
|
|
|
|
|
|
avi_HeaderAdd_INFO( p_mux, &bo ); |
|
|
|
|
|
|
|
bo_AddFCC( &bo, "LIST" ); |
|
|
|
bo_AddDWordLE( &bo, p_sys->i_movi_size + 4 ); |
|
|
|
bo_AddFCC( &bo, "movi" ); |
|
|
|
bo_add_fourcc( &bo, "LIST" ); |
|
|
|
bo_add_32le( &bo, p_sys->i_movi_size + 4 ); |
|
|
|
bo_add_fourcc( &bo, "movi" ); |
|
|
|
|
|
|
|
/* Now set RIFF size */ |
|
|
|
bo_SetDWordLE( &bo, offsets.i_riffsize, bo.p_block->i_buffer - 8 |
|
|
|
+ p_sys->i_movi_size + p_sys->i_idx1_size ); |
|
|
|
bo_set_32le( &bo, offsets.i_riffsize, bo.b->i_buffer - 8 |
|
|
|
+ p_sys->i_movi_size + p_sys->i_idx1_size ); |
|
|
|
|
|
|
|
return( bo.p_block ); |
|
|
|
return( bo.b ); |
|
|
|
} |
|
|
|
|
|
|
|
static block_t * avi_HeaderCreateidx1( sout_mux_t *p_mux ) |
|
|
|
{ |
|
|
|
sout_mux_sys_t *p_sys = p_mux->p_sys; |
|
|
|
uint32_t i_idx1_size; |
|
|
|
buffer_out_t bo; |
|
|
|
bo_t bo; |
|
|
|
|
|
|
|
i_idx1_size = 16 * p_sys->idx1.i_entry_count + 8; |
|
|
|
|
|
|
|
bo_Init( &bo, i_idx1_size ); |
|
|
|
memset( bo.p_block->p_buffer, 0, i_idx1_size); |
|
|
|
bo_init( &bo, i_idx1_size ); |
|
|
|
memset( bo.b->p_buffer, 0, i_idx1_size); |
|
|
|
|
|
|
|
bo_AddFCC( &bo, "idx1" ); |
|
|
|
bo_AddDWordLE( &bo, i_idx1_size - 8); |
|
|
|
bo_add_fourcc( &bo, "idx1" ); |
|
|
|
bo_add_32le( &bo, i_idx1_size - 8); |
|
|
|
|
|
|
|
for( unsigned i = 0; i < p_sys->idx1.i_entry_count; i++ ) |
|
|
|
{ |
|
|
|
bo_AddFCC( &bo, p_sys->idx1.entry[i].fcc ); |
|
|
|
bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_flags ); |
|
|
|
bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_pos ); |
|
|
|
bo_AddDWordLE( &bo, p_sys->idx1.entry[i].i_length ); |
|
|
|
bo_add_fourcc( &bo, p_sys->idx1.entry[i].fcc ); |
|
|
|
bo_add_32le( &bo, p_sys->idx1.entry[i].i_flags ); |
|
|
|
bo_add_32le( &bo, p_sys->idx1.entry[i].i_pos ); |
|
|
|
bo_add_32le( &bo, p_sys->idx1.entry[i].i_length ); |
|
|
|
} |
|
|
|
|
|
|
|
return( bo.p_block ); |
|
|
|
return( bo.b ); |
|
|
|
} |
|
|
|
|