Index: mencoder.c =================================================================== RCS file: /cvsroot/mplayer/main/mencoder.c,v retrieving revision 1.305 diff -u -r1.305 mencoder.c --- mencoder.c 5 Aug 2005 19:57:44 -0000 1.305 +++ mencoder.c 9 Nov 2005 05:19:13 -0000 @@ -933,9 +933,6 @@ } // if(sh_audio) -mp_msg(MSGT_MENCODER, MSGL_INFO, MSGTR_WritingAVIHeader); -if (muxer->cont_write_header) muxer_write_header(muxer); - decoded_frameno=0; signal(SIGINT,exit_sighandler); // Interrupt from keyboard Index: libmpdemux/muxer.c =================================================================== RCS file: /cvsroot/mplayer/main/libmpdemux/muxer.c,v retrieving revision 1.9 diff -u -r1.9 muxer.c --- libmpdemux/muxer.c 21 Jun 2005 18:54:50 -0000 1.9 +++ libmpdemux/muxer.c 9 Nov 2005 05:19:13 -0000 @@ -21,6 +21,7 @@ muxer_t *muxer_new_muxer(int type,FILE *f){ muxer_t* muxer=malloc(sizeof(muxer_t)); memset(muxer,0,sizeof(muxer_t)); + muxer->muxbuf_do_buffer = 1; muxer->file = f; switch (type) { case MUXER_TYPE_MPEG: @@ -48,3 +49,65 @@ } return muxer; } + +/* buffer frames until we either: + * (a) have a video stream + * (b) give up because we think there is no video coming */ +//XXX: UNFINISHED +void muxer_write_chunk(muxer_stream_t *s, size_t len, unsigned int flags) { + if (s->muxer->muxbuf_do_buffer) { + /* buffer this frame */ + s->muxer->muxbuf_buffer[s->muxer->muxbuf_num] = s->buffer; + s->muxer->muxbuf_len[s->muxer->muxbuf_num] = len; + s->muxer->muxbuf_stream[s->muxer->muxbuf_num] = s; + ++s->muxer->muxbuf_num; + /* make a replacement buffer available to the stream */ + s->buffer=malloc(s->buffer_size); + if (!s->buffer) { + /* TODO: do something reasonable here */ + mp_msg(MSGT_MUXER, MSGL_FATAL, "Muxer frame buffer cannot allocate memory!\n"); + } + /* see if we have a video frame or if buffer is full; + * leave room for current frame in buffer */ + if (s->type == MUXER_TYPE_VIDEO || s->muxer->muxbuf_num >= MUXER_FRAME_BUFFER_LEN-1) { + int i; + /* write header */ + mp_msg(MSGT_MUXER, MSGL_INFO, MSGTR_WritingAVIHeader); + if (s->muxer->cont_write_header) muxer_write_header(s->muxer); + /* print info */ + if (s->muxer->muxbuf_num >= MUXER_FRAME_BUFFER_LEN-1) + mp_msg(MSGT_MUXER, MSGL_ERR, "Muxer frame buffer has %d non-video frames.\n" + "Sending frames to muxer anyway -- header may be incorrect.\n", + s->muxer->muxbuf_num); + else + mp_msg(MSGT_MUXER, MSGL_V, "Muxer frame buffer sending %d frames to muxer.\n", + s->muxer->muxbuf_num); + /* send all buffered frames to muxer */ + for (i = 0; i < s->muxer->muxbuf_num; ++i) { + s = s->muxer->muxbuf_stream[i]; + free(s->buffer); /* free the old buffer */ + s->buffer = s->muxer->muxbuf_buffer[i]; + s->muxer->cont_write_chunk(s, s->muxer->muxbuf_len[i], flags); + } + s->muxer->muxbuf_do_buffer = s->muxer->muxbuf_num = 0; + } + } + else { /* if (s->do_buffer_frames) */ + s->muxer->cont_write_chunk(s, len, flags); + } + + /* this code moved directly from muxer_avi.c */ + // alter counters: + if(s->h.dwSampleSize){ + // CBR + s->h.dwLength+=len/s->h.dwSampleSize; + if(len%s->h.dwSampleSize) mp_msg(MSGT_MUXER, MSGL_WARN, "Warning! len isn't divisable by samplesize!\n"); + } else { + // VBR + s->h.dwLength++; + } + s->timer=(double)s->h.dwLength*s->h.dwScale/s->h.dwRate; + s->size+=len; + + return; +} Index: libmpdemux/muxer.h =================================================================== RCS file: /cvsroot/mplayer/main/libmpdemux/muxer.h,v retrieving revision 1.15 diff -u -r1.15 muxer.h --- libmpdemux/muxer.h 19 Jun 2005 09:12:43 -0000 1.15 +++ libmpdemux/muxer.h 9 Nov 2005 05:19:13 -0000 @@ -1,5 +1,6 @@ #define MUXER_MAX_STREAMS 16 +#define MUXER_FRAME_BUFFER_LEN 100 // arbitrary number. what would be good? #define MUXER_TYPE_VIDEO 0 #define MUXER_TYPE_AUDIO 1 @@ -66,11 +67,19 @@ //int num_streams; muxer_stream_t* def_v; // default video stream (for general headers) muxer_stream_t* streams[MUXER_MAX_STREAMS]; + // for prebuffering frames until we get a video frame + unsigned char *muxbuf_buffer[MUXER_FRAME_BUFFER_LEN]; + size_t muxbuf_len[MUXER_FRAME_BUFFER_LEN]; + muxer_stream_t *muxbuf_stream[MUXER_FRAME_BUFFER_LEN]; + int muxbuf_num; + int muxbuf_do_buffer; + // functions void (*fix_stream_parameters)(muxer_stream_t *); void (*cont_write_chunk)(muxer_stream_t *,size_t,unsigned int); void (*cont_write_header)(struct muxer_t *); void (*cont_write_index)(struct muxer_t *); muxer_stream_t* (*cont_new_stream)(struct muxer_t *,int); + int index_written; FILE* file; void *priv; } muxer_t; @@ -78,7 +87,7 @@ muxer_t *muxer_new_muxer(int type,FILE *); #define muxer_new_stream(muxer,a) muxer->cont_new_stream(muxer,a) #define muxer_stream_fix_parameters(muxer, a) muxer->fix_stream_parameters(a) -#define muxer_write_chunk(a,b,c) a->muxer->cont_write_chunk(a,b,c) +void muxer_write_chunk(muxer_stream_t *s, size_t len, unsigned int flags); #define muxer_write_header(muxer) muxer->cont_write_header(muxer) #define muxer_write_index(muxer) muxer->cont_write_index(muxer) Index: libmpdemux/muxer_avi.c =================================================================== RCS file: /cvsroot/mplayer/main/libmpdemux/muxer_avi.c,v retrieving revision 1.30 diff -u -r1.30 muxer_avi.c --- libmpdemux/muxer_avi.c 21 Feb 2005 21:45:49 -0000 1.30 +++ libmpdemux/muxer_avi.c 9 Nov 2005 05:19:13 -0000 @@ -241,20 +241,9 @@ // write out the chunk: write_avi_chunk(muxer->file,s->ckid,len,s->buffer); /* unsigned char */ - // alter counters: if (len > s->h.dwSuggestedBufferSize){ s->h.dwSuggestedBufferSize = len; } - if(s->h.dwSampleSize){ - // CBR - s->h.dwLength+=len/s->h.dwSampleSize; - if(len%s->h.dwSampleSize) mp_msg(MSGT_MUXER, MSGL_WARN, "Warning! len isn't divisable by samplesize!\n"); - } else { - // VBR - s->h.dwLength++; - } - s->timer=(double)s->h.dwLength*s->h.dwScale/s->h.dwRate; - s->size+=len; if((unsigned int)len>s->h.dwSuggestedBufferSize) s->h.dwSuggestedBufferSize=len; muxer->file_end += 8 + paddedlen; @@ -328,7 +317,7 @@ } // update AVI header: - if(muxer->def_v){ + if(muxer->index_written){ int i; muxer->avih.dwMicroSecPerFrame=1000000.0*muxer->def_v->h.dwScale/muxer->def_v->h.dwRate; // muxer->avih.dwMaxBytesPerSec=1000000; // dummy!!!!! FIXME @@ -658,6 +647,7 @@ } else { avifile_write_standard_index(muxer); } + muxer->index_written = 1; } int muxer_init_muxer_avi(muxer_t *muxer){