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 8 Nov 2005 03:33:01 -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->do_buffer_frames = 1; muxer->file = f; switch (type) { case MUXER_TYPE_MPEG: @@ -48,3 +49,46 @@ } return muxer; } + +/* buffer frames until we either: + * (a) have a video stream + * (b) give up because we think there is no video coming */ +//XXX: BROKEN RIGHT NOW */ +void muxer_write_chunk(muxer_stream_t *s, size_t len, unsigned int flags) { + if (s->muxer->do_buffer_frames) { + /* buffer this frame */ + s->muxer->frame_buf[s->muxer->num_frames] = s->buffer; + s->muxer->frame_lengths[s->muxer->num_frames] = len; + ++s->muxer->num_frames; + /* 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->num_frames >= MUXER_FRAME_BUFFER_LEN-1) { + int i; + if (s->muxer->num_frames >= 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->num_frames); + else + mp_msg(MSGT_MUXER, MSGL_V, "Muxer frame buffer sending %d frames to muxer.\n", + s->muxer->num_frames); + /* send all buffered frames to muxer */ + for (i = 0; i < s->muxer->num_frames; ++i) { + s->buffer = s->muxer->frame_buf[i]; + len = s->muxer->frame_lengths[i]; + s->muxer->cont_write_chunk(s, len, flags); + free(s->buffer); + } + s->muxer->do_buffer_frames = s->muxer->num_frames = 0; + } + /* make a new 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"); + } + } + else { /* if (s->do_buffer_frames) */ + s->muxer->cont_write_chunk(s, len, flags); + } + 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 8 Nov 2005 03:33:01 -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,6 +67,12 @@ //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 *frame_buf[MUXER_FRAME_BUFFER_LEN]; + size_t frame_lengths[MUXER_FRAME_BUFFER_LEN]; + int num_frames; + int do_buffer_frames; + // 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 *); @@ -78,7 +85,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)