diff -ur main.orig/libmpcodecs/ve_lavc.c main.patchtest/libmpcodecs/ve_lavc.c --- main.orig/libmpcodecs/ve_lavc.c 2006-02-13 12:55:41.000000000 -0800 +++ main.patchtest/libmpcodecs/ve_lavc.c 2006-02-16 23:25:50.000000000 -0800 @@ -770,6 +770,8 @@ mux_v->bih->biSize= sizeof(BITMAPINFOHEADER) + lavc_venc_context->extradata_size; } + mux_v->decoder_delay = lavc_venc_context->max_b_frames ? 1 : 0; + return 1; } @@ -854,8 +856,10 @@ out_size = avcodec_encode_video(lavc_venc_context, mux_v->buffer, mux_v->buffer_size, pic); - if(out_size == 0) + if(out_size == 0) { + ++mux_v->encoder_delay; return 0; + } muxer_write_chunk(mux_v,out_size,lavc_venc_context->coded_frame->key_frame?0x10:0, MP_NOPTS_VALUE, MP_NOPTS_VALUE); diff -ur main.orig/libmpcodecs/ve_x264.c main.patchtest/libmpcodecs/ve_x264.c --- main.orig/libmpcodecs/ve_x264.c 2006-02-13 12:55:41.000000000 -0800 +++ main.patchtest/libmpcodecs/ve_x264.c 2006-02-16 23:25:50.000000000 -0800 @@ -435,6 +435,11 @@ return 0; } + if (mod->param.i_bframe > 1 && mod->param.b_bframe_pyramid) + mod->mux->decoder_delay = 2; + else + mod->mux->decoder_delay = mod->param.i_bframe ? 1 : 0; + return 1; } @@ -511,6 +516,8 @@ && frame_ref == 1 && !bframe); muxer_write_chunk(mod->mux, i_size, keyframe?0x10:0, MP_NOPTS_VALUE, MP_NOPTS_VALUE); } + else + ++mod->mux->encoder_delay; return i_size; } diff -ur main.orig/libmpcodecs/ve_xvid4.c main.patchtest/libmpcodecs/ve_xvid4.c --- main.orig/libmpcodecs/ve_xvid4.c 2006-02-13 12:55:41.000000000 -0800 +++ main.patchtest/libmpcodecs/ve_xvid4.c 2006-02-16 23:25:50.000000000 -0800 @@ -504,6 +504,8 @@ /* Store the encoder instance into the private data */ mod->instance = mod->create.handle; + mod->mux->decoder_delay = mod->create.max_bframes ? 1 : 0; + return(FINE); } @@ -620,7 +622,10 @@ } /* If size is == 0, we're done with that frame */ - if(size == 0) return(FINE); + if(size == 0) { + ++mod->mux->encoder_delay; + return(FINE); + } /* xvidcore returns stats about encoded frame in an asynchronous way * accumulate these stats */ diff -ur main.orig/libmpcodecs/ve_xvid.c main.patchtest/libmpcodecs/ve_xvid.c --- main.orig/libmpcodecs/ve_xvid.c 2006-02-13 12:55:41.000000000 -0800 +++ main.patchtest/libmpcodecs/ve_xvid.c 2006-02-16 23:25:50.000000000 -0800 @@ -378,6 +378,10 @@ vbrInit(&fp->vbr_state); +#ifdef XVID_API_UNSTABLE + fp->mux->decoder_delay = enc_param.max_bframes ? 1 : 0; +#endif + return 1; } @@ -523,7 +527,10 @@ #endif // write output + if (fp->enc_frame.length > 0) muxer_write_chunk(fp->mux, fp->enc_frame.length, fp->enc_frame.intra==1 ? 0x10 : 0, MP_NOPTS_VALUE, MP_NOPTS_VALUE); + else + ++fp->mux->encoder_delay; // update the VBR engine vbrUpdate(&fp->vbr_state, enc_stats.quant, fp->enc_frame.intra, diff -ur main.orig/libmpdemux/muxer_avi.c main.patchtest/libmpdemux/muxer_avi.c --- main.orig/libmpdemux/muxer_avi.c 2006-02-16 19:26:10.000000000 -0800 +++ main.patchtest/libmpdemux/muxer_avi.c 2006-02-16 23:25:50.000000000 -0800 @@ -665,10 +665,19 @@ } } +static void avifile_fix_parameters(muxer_stream_t *s){ + /* adjust audio_delay_fix according to individual stream delay */ + if (s->type == MUXER_TYPE_AUDIO) + s->muxer->audio_delay_fix -= (float)s->decoder_delay * s->h.dwScale/s->h.dwRate; + if (s->type == MUXER_TYPE_VIDEO) + s->muxer->audio_delay_fix += (float)s->decoder_delay * s->h.dwScale/s->h.dwRate; +} + int muxer_init_muxer_avi(muxer_t *muxer){ muxer->cont_new_stream = &avifile_new_stream; muxer->cont_write_chunk = &avifile_write_chunk; muxer->cont_write_header = &avifile_write_header; muxer->cont_write_index = &avifile_write_index; + muxer->fix_stream_parameters = &avifile_fix_parameters; return 1; } diff -ur main.orig/libmpdemux/muxer.h main.patchtest/libmpdemux/muxer.h --- main.orig/libmpdemux/muxer.h 2006-02-16 19:26:10.000000000 -0800 +++ main.patchtest/libmpdemux/muxer.h 2006-02-16 23:25:50.000000000 -0800 @@ -38,6 +38,8 @@ // stream specific: WAVEFORMATEX *wf; BITMAPINFOHEADER *bih; // in format + int encoder_delay; // in number of frames + int decoder_delay; // in number of frames // mpeg specific: size_t ipb[3]; // sizes of I/P/B frames // muxer of that stream diff -ur main.orig/mencoder.c main.patchtest/mencoder.c --- main.orig/mencoder.c 2006-02-16 22:53:59.000000000 -0800 +++ main.patchtest/mencoder.c 2006-02-16 23:25:50.000000000 -0800 @@ -1393,6 +1393,9 @@ AV_delay-=audio_delay; AV_delay /= playback_speed; AV_delay-=mux_a->timer-(mux_v->timer-(v_timer_corr+v_pts_corr)); + // adjust for encoder delays + AV_delay -= (float) mux_a->encoder_delay * mux_a->h.dwScale/mux_a->h.dwRate; + AV_delay += (float) mux_v->encoder_delay * mux_v->h.dwScale/mux_v->h.dwRate; // compensate input video timer by av: x=AV_delay*0.1f; if(x<-max_pts_correction) x=-max_pts_correction; else