Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'

limitation and the JUNK chunks needed to do that.


git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12236 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
ranma 2004-04-19 02:14:09 +00:00
parent a46cb905a3
commit df14981c08
1 changed files with 56 additions and 42 deletions

View File

@ -53,6 +53,9 @@ struct avi_stream_info {
int idxpos;
int superidxpos;
int superidxsize;
int riffofspos;
int riffofssize;
off_t *riffofs;
struct avi_odmlidx_entry *idx;
struct avi_odmlsuperidx_entry *superidx;
};
@ -107,6 +110,9 @@ static muxer_stream_t* avifile_new_stream(muxer_t *muxer,int type){
memset(si,0,sizeof(struct avi_stream_info));
si->idxsize=256;
si->idx=malloc(sizeof(struct avi_odmlidx_entry)*si->idxsize);
si->riffofssize=16;
si->riffofs=malloc(sizeof(off_t)*(si->riffofssize+1));
memset(si->riffofs, 0, sizeof(off_t)*si->riffofssize);
switch(type){
case MUXER_TYPE_VIDEO:
@ -159,11 +165,18 @@ static void avifile_write_index(muxer_t *muxer);
static void avifile_odml_new_riff(muxer_t *muxer)
{
struct avi_stream_info *vsi = muxer->def_v->priv;
FILE *f = muxer->file;
uint32_t riff[3];
/* Pad to ODML_CHUNKLEN */
write_avi_chunk(f,ckidAVIPADDING,ODML_CHUNKLEN - (ftello(f)%ODML_CHUNKLEN) - 8,NULL);
mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Starting new RIFF chunk at %dMiB.\n", (int)(muxer->file_end/1024/1024));
vsi->riffofspos++;
if (vsi->riffofspos>=vsi->riffofssize) {
vsi->riffofssize+=16;
vsi->riffofs=realloc(vsi->riffofs,sizeof(off_t)*(vsi->riffofssize+1));
}
vsi->riffofs[vsi->riffofspos] = ftello(f);
/* RIFF/AVIX chunk */
riff[0]=le2me_32(mmioFOURCC('R','I','F','F'));
@ -172,15 +185,29 @@ static void avifile_odml_new_riff(muxer_t *muxer)
fwrite(riff,12,1,f);
write_avi_list(f,listtypeAVIMOVIE,0);
muxer->file_end = ftello(f);
}
static void avifile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags){
off_t pos;
struct avi_stream_info *si = s->priv;
off_t rifflen;
muxer_t *muxer=s->muxer;
int isodml = muxer->file_end > ODML_CHUNKLEN ? 1 : 0;
struct avi_stream_info *si = s->priv;
struct avi_stream_info *vsi = muxer->def_v->priv;
int paddedlen = len + (len&1);
if (!isodml) {
rifflen = muxer->file_end - vsi->riffofs[vsi->riffofspos] - 8;
if (vsi->riffofspos == 0) {
rifflen += 8+muxer->idx_pos*sizeof(AVIINDEXENTRY);
}
if (rifflen + paddedlen > ODML_CHUNKLEN) {
if (vsi->riffofspos == 0) {
avifile_write_index(muxer);
}
avifile_odml_new_riff(muxer);
}
if (vsi->riffofspos == 0) {
// add to the traditional index:
if(muxer->idx_pos>=muxer->idx_size){
muxer->idx_size+=256; // 4kB
@ -188,7 +215,7 @@ static void avifile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags)
}
muxer->idx[muxer->idx_pos].ckid=s->ckid;
muxer->idx[muxer->idx_pos].dwFlags=flags; // keyframe?
muxer->idx[muxer->idx_pos].dwChunkOffset=ftello(muxer->file)-(muxer->movi_start-4);
muxer->idx[muxer->idx_pos].dwChunkOffset=muxer->file_end-(muxer->movi_start-4);
muxer->idx[muxer->idx_pos].dwChunkLength=len;
++muxer->idx_pos;
}
@ -199,24 +226,10 @@ static void avifile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags)
si->idx=realloc(si->idx,sizeof(*si->idx)*si->idxsize);
}
si->idx[si->idxpos].flags=(flags&AVIIF_KEYFRAME)?0:ODML_NOTKEYFRAME;
si->idx[si->idxpos].ofs=ftello(muxer->file);
si->idx[si->idxpos].ofs=muxer->file_end;
si->idx[si->idxpos].len=len;
++si->idxpos;
pos = muxer->file_end;
if (pos < ODML_CHUNKLEN &&
pos + 16*muxer->idx_pos + len + 8 > ODML_CHUNKLEN) {
avifile_write_index(muxer);
avifile_odml_new_riff(muxer);
pos = muxer->file_end = ftello(muxer->file);
}
if (pos % ODML_CHUNKLEN + len + 8 > ODML_CHUNKLEN) {
avifile_odml_new_riff(muxer);
muxer->file_end = ftello(muxer->file);
}
// write out the chunk:
write_avi_chunk(muxer->file,s->ckid,len,s->buffer); /* unsigned char */
@ -236,7 +249,7 @@ static void avifile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags)
s->size+=len;
if((unsigned int)len>s->h.dwSuggestedBufferSize) s->h.dwSuggestedBufferSize=len;
muxer->file_end += len + len&1 + 8;
muxer->file_end += 8 + paddedlen;
}
static void write_avi_list(FILE *f,unsigned int id,int len){
@ -264,7 +277,8 @@ static void avifile_write_header(muxer_t *muxer){
VideoPropHeader vprp;
uint32_t aspect = avi_aspect(muxer->def_v);
off_t pos;
int isodml = muxer->file_end > ODML_CHUNKLEN ? 1 : 0;
struct avi_stream_info *vsi = muxer->def_v->priv;
int isodml = vsi->riffofspos > 0;
if (aspect == 0) {
mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.\n");
@ -273,28 +287,27 @@ static void avifile_write_header(muxer_t *muxer){
}
if (isodml) {
for (pos = 0; pos < muxer->file_end; pos += ODML_CHUNKLEN) {
unsigned int rifflen, movilen;
int i;
/* fixup RIFF length */
if (muxer->file_end - pos > ODML_CHUNKLEN) {
rifflen = le2me_32(ODML_CHUNKLEN - 8);
movilen = le2me_32(ODML_CHUNKLEN - 20);
} else {
rifflen = le2me_32(muxer->file_end - pos - 8);
movilen = le2me_32(muxer->file_end - pos - 20);
vsi->riffofs[vsi->riffofspos+1] = muxer->file_end;
/* fixup RIFF lengths */
for (i=0; i<=vsi->riffofspos; i++) {
rifflen = vsi->riffofs[i+1] - vsi->riffofs[i] - 8;
movilen = le2me_32(rifflen - 12);
rifflen = le2me_32(rifflen);
fseeko(f, vsi->riffofs[i]+4, SEEK_SET);
fwrite(&rifflen,4,1,f);
/* fixup movi length */
if (i > 0) {
fseeko(f, vsi->riffofs[i]+16, SEEK_SET);
fwrite(&movilen,4,1,f);
}
}
fseeko(f, pos + 4, SEEK_SET);
fwrite(&rifflen,4,1,f);
/* fixup movi length */
if (pos > 0) {
fseeko(f, pos + 16, SEEK_SET);
fwrite(&movilen,4,1,f);
}
}
fseeko(f, 12, SEEK_SET);
fseeko(f, 12, SEEK_SET);
} else {
// RIFF header:
riff[0]=mmioFOURCC('R','I','F','F');
@ -525,6 +538,7 @@ info[i].id=0;
write_avi_list(f,listtypeAVIMOVIE,muxer->movi_end-ftello(f)-12);
}
muxer->movi_start=ftello(muxer->file);
if (muxer->file_end == 0) muxer->file_end = ftello(muxer->file);
}
static void avifile_odml_write_index(muxer_t *muxer){