# HG changeset patch # User henry # Date 1109708518 0 # Node ID 5723c4b2a2eabfad153f61672688e6f421786b43 # Parent db1f17e9b7a212bf4ea153d86b4555a6febe1a7b fixes for encoding of multiple files - do not uninitialize video encoder between files - checks for image size & format change moved from mencoder.c to vfilters by Oded Shimon diff -r db1f17e9b7a2 -r 5723c4b2a2ea help/help_mp-en.h --- a/help/help_mp-en.h Tue Mar 01 20:16:49 2005 +0000 +++ b/help/help_mp-en.h Tue Mar 01 20:21:58 2005 +0000 @@ -215,7 +215,7 @@ #define MSGTR_WritingAVIHeader "Writing AVI header...\n" #define MSGTR_DuplicateFrames "\n%d duplicate frame(s)!\n" #define MSGTR_SkipFrame "\nSkipping frame!\n" -#define MSGTR_ResolutionDoesntMatch "\nNew video file has different resolution than the previous one.\n" +#define MSGTR_ResolutionDoesntMatch "\nNew video file has different resolution or colorspace than the previous one.\n" #define MSGTR_FrameCopyFileMismatch "\nAll video files must have identical fps, resolution, and codec for -ovc copy.\n" #define MSGTR_AudioCopyFileMismatch "\nAll files must have identical audio codec and format for -oac copy.\n" #define MSGTR_ErrorWritingFile "%s: Error writing file.\n" diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/vd.c --- a/libmpcodecs/vd.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/vd.c Tue Mar 01 20:21:58 2005 +0000 @@ -309,10 +309,10 @@ vf->w = sh->disp_w; vf->h = sh->disp_h; - if(vf->config(vf,sh->disp_w,sh->disp_h, - screen_size_x,screen_size_y, - fullscreen|(vidmode<<1)|(softzoom<<2)|(flip<<3), - out_fmt)==0){ + if(vf_config_wrapper(vf,sh->disp_w,sh->disp_h, + screen_size_x,screen_size_y, + fullscreen|(vidmode<<1)|(softzoom<<2)|(flip<<3), + out_fmt)==0){ // "MPlayer",out_fmt)){ mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_CannotInitVO); sh->vf_inited=-1; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_divx4.c --- a/libmpcodecs/ve_divx4.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_divx4.c Tue Mar 01 20:21:58 2005 +0000 @@ -453,6 +453,7 @@ static int vf_open(vf_instance_t *vf, char* args){ vf->config=config; + vf->default_caps=VFCAP_CONSTANT; vf->control=control; vf->query_format=query_format; vf->put_image=put_image; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_lavc.c --- a/libmpcodecs/ve_lavc.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_lavc.c Tue Mar 01 20:21:58 2005 +0000 @@ -923,6 +923,7 @@ static int vf_open(vf_instance_t *vf, char* args){ vf->uninit=uninit; vf->config=config; + vf->default_caps=VFCAP_CONSTANT; vf->control=control; vf->query_format=query_format; vf->put_image=put_image; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_libdv.c --- a/libmpcodecs/ve_libdv.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_libdv.c Tue Mar 01 20:21:58 2005 +0000 @@ -85,6 +85,7 @@ static int vf_open(vf_instance_t *vf, char* args){ vf->config=config; + vf->default_caps=VFCAP_CONSTANT; vf->control=control; vf->query_format=query_format; vf->put_image=put_image; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_nuv.c --- a/libmpcodecs/ve_nuv.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_nuv.c Tue Mar 01 20:21:58 2005 +0000 @@ -192,6 +192,7 @@ static int vf_open(vf_instance_t *vf, char* args){ vf->config=config; + vf->default_caps=VFCAP_CONSTANT; vf->control=control; vf->query_format=query_format; vf->put_image=put_image; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_qtvideo.c --- a/libmpcodecs/ve_qtvideo.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_qtvideo.c Tue Mar 01 20:21:58 2005 +0000 @@ -278,6 +278,7 @@ static int vf_open(vf_instance_t *vf, char* args){ OSErr cres = 1; vf->config=config; + vf->default_caps=VFCAP_CONSTANT; vf->control=control; vf->query_format=query_format; vf->put_image=put_image; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_raw.c --- a/libmpcodecs/ve_raw.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_raw.c Tue Mar 01 20:21:58 2005 +0000 @@ -125,6 +125,7 @@ static int vf_open(vf_instance_t *vf, char* args){ vf->config = config; + vf->default_caps = VFCAP_CONSTANT; vf->control = control; vf->query_format = query_format; vf->put_image = put_image; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_vfw.c --- a/libmpcodecs/ve_vfw.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_vfw.c Tue Mar 01 20:21:58 2005 +0000 @@ -251,6 +251,7 @@ static int vf_open(vf_instance_t *vf, char* args){ vf->config=config; + vf->default_caps=VFCAP_CONSTANT; vf->control=control; vf->query_format=query_format; vf->put_image=put_image; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_x264.c --- a/libmpcodecs/ve_x264.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_x264.c Tue Mar 01 20:21:58 2005 +0000 @@ -375,6 +375,7 @@ h264_module_t *mod; vf->config = config; + vf->default_caps = VFCAP_CONSTANT; vf->control = control; vf->query_format = query_format; vf->put_image = put_image; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_xvid.c --- a/libmpcodecs/ve_xvid.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_xvid.c Tue Mar 01 20:21:58 2005 +0000 @@ -539,6 +539,7 @@ { XVID_INIT_PARAM params = { 0, 0, 0}; vf->config = config; + vf->default_caps = VFCAP_CONSTANT; vf->control = control; vf->uninit = uninit; vf->query_format = query_format; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/ve_xvid4.c --- a/libmpcodecs/ve_xvid4.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/ve_xvid4.c Tue Mar 01 20:21:58 2005 +0000 @@ -546,6 +546,7 @@ /* Setting libmpcodec module API pointers */ vf->config = config; + vf->default_caps = VFCAP_CONSTANT; vf->control = control; vf->uninit = uninit; vf->query_format = query_format; diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/vf.c --- a/libmpcodecs/vf.c Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/vf.c Tue Mar 01 20:21:58 2005 +0000 @@ -541,6 +541,37 @@ dst->qscale= src->qscale; } } +/** + * \brief Video config() function wrapper + * + * Blocks config() calls with different size or format for filters + * with VFCAP_CONSTANT + * + * First call is redirected to vf->config. + * + * In following calls, it verifies that the configuration parameters + * are unchanged, and returns either success or error. + * +*/ +int vf_config_wrapper(struct vf_instance_s* vf, + int width, int height, int d_width, int d_height, + unsigned int flags, unsigned int outfmt) +{ + if ((vf->default_caps&VFCAP_CONSTANT) && vf->fmt.have_configured) { + if ((vf->fmt.orig_width != width) + || (vf->fmt.orig_height != height) + || (vf->fmt.orig_fmt != outfmt)) { + mp_msg(MSGT_VFILTER,MSGL_FATAL,MSGTR_ResolutionDoesntMatch); + return 0; + } + return 1; + } + vf->fmt.have_configured = 1; + vf->fmt.orig_height = height; + vf->fmt.orig_width = width; + vf->fmt.orig_fmt = outfmt; + vf->config(vf, width, height, d_width, d_height, flags, outfmt); +} int vf_next_config(struct vf_instance_s* vf, int width, int height, int d_width, int d_height, @@ -571,7 +602,7 @@ vf->next=vf2; } vf->next->w = width; vf->next->h = height; - return vf->next->config(vf->next,width,height,d_width,d_height,voflags,outfmt); + return vf_config_wrapper(vf->next,width,height,d_width,d_height,voflags,outfmt); } int vf_next_control(struct vf_instance_s* vf, int request, void* data){ diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/vf.h --- a/libmpcodecs/vf.h Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/vf.h Tue Mar 01 20:21:58 2005 +0000 @@ -19,6 +19,11 @@ int static_idx; } vf_image_context_t; +typedef struct vf_format_context_t { + int have_configured; + int orig_width, orig_height, orig_fmt; +} vf_format_context_t; + typedef struct vf_instance_s { vf_info_t* info; // funcs: @@ -44,6 +49,7 @@ // data: int w, h; vf_image_context_t imgctx; + vf_format_context_t fmt; struct vf_instance_s* next; mp_image_t *dmpi; struct vf_priv_s* priv; @@ -99,3 +105,6 @@ void vf_uninit_filter(vf_instance_t* vf); void vf_uninit_filter_chain(vf_instance_t* vf); +int vf_config_wrapper(struct vf_instance_s* vf, + int width, int height, int d_width, int d_height, + unsigned int flags, unsigned int outfmt); diff -r db1f17e9b7a2 -r 5723c4b2a2ea libmpcodecs/vfcap.h --- a/libmpcodecs/vfcap.h Tue Mar 01 20:16:49 2005 +0000 +++ b/libmpcodecs/vfcap.h Tue Mar 01 20:21:58 2005 +0000 @@ -24,4 +24,6 @@ #define VFCAP_ACCEPT_STRIDE 0x400 // filter does postprocessing (so you shouldn't scale/filter image before it) #define VFCAP_POSTPROC 0x800 +// filter cannot be reconfigured to different size & format +#define VFCAP_CONSTANT 0x1000 diff -r db1f17e9b7a2 -r 5723c4b2a2ea mencoder.c --- a/mencoder.c Tue Mar 01 20:16:49 2005 +0000 +++ b/mencoder.c Tue Mar 01 20:21:58 2005 +0000 @@ -392,8 +392,6 @@ int decoded_frameno=0; int next_frameno=-1; int curfile=0; -int prevwidth = 0; -int prevhieght = 0; ///< When different from 0, after decoding a frame, Resolution must be checked to match previous file unsigned int timer_start; @@ -739,8 +737,9 @@ mux_v->bih->biSizeImage=mux_v->bih->biWidth*mux_v->bih->biHeight*(mux_v->bih->biBitCount/8); } break; -default: - +default: { + static vf_instance_t * ve = NULL; + if (!ve) { switch(mux_v->codec){ case VCODEC_DIVX4: sh_video->vfilter=vf_open_encoder(NULL,"divx4",(char *)mux_v); break; @@ -765,6 +764,8 @@ mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_EncoderOpenFailed); mencoder_exit(1,NULL); } + ve = sh_video->vfilter; + } else sh_video->vfilter = ve; // append 'expand' filter, it fixes stride problems and renders osd: if (auto_expand) { char* vf_args[] = { "osd", "1", NULL }; @@ -776,7 +777,7 @@ init_best_video_codec(sh_video,video_codec_list,video_fm_list); mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n"); if(!sh_video->inited) mencoder_exit(1,NULL); - + } } if (!curfile) { @@ -1544,13 +1545,7 @@ blit_frame=decode_video(sh_video,start,in_size, skip_flag>0 && (!sh_video->vfilter || ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE)); - if (prevwidth) { - if ((mux_v->bih->biWidth != prevwidth) || (mux_v->bih->biHeight != prevhieght)) { - mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ResolutionDoesntMatch); - mencoder_exit(1,NULL); - } - prevhieght = prevwidth = 0; - } + if (sh_video->vf_inited < 0) mencoder_exit(1, NULL); if(!blit_frame){ badframes++; @@ -1724,28 +1719,33 @@ } // while(!at_eof) -/* Emit the remaining frames in the video system */ -/*TODO emit frmaes delayed by decoder lag*/ - if(sh_video && sh_video->vfilter){ - mp_msg(MSGT_FIXME, MSGL_FIXME, "\nFlushing video frames\n"); - ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, - VFCTRL_FLUSH_FRAMES, 0); - } +if (!interrupted && filelist[++curfile].name != 0) { + // Before uniniting sh_video and the filter chain, break apart the VE. + vf_instance_t * ve; // this will be the filter right before the ve. + for (ve = sh_video->vfilter; ve->next && ve->next->next; ve = ve->next); + if (ve->next) + ve->next = NULL; // I'm telling the last filter, before the VE, there is nothing after it + else // There is no chain except the VE. + sh_video->vfilter = NULL; -if (!interrupted && filelist[++curfile].name != 0) { if(sh_video){ uninit_video(sh_video);sh_video=NULL; } if(demuxer) free_demuxer(demuxer); if(stream) free_stream(stream); // kill cache thread - prevwidth = mux_v->bih->biWidth; - prevhieght = mux_v->bih->biHeight; - at_eof = 0; m_config_pop(mconfig); goto play_next_file; } +/* Emit the remaining frames in the video system */ +/*TODO emit frmaes delayed by decoder lag*/ +if(sh_video && sh_video->vfilter){ + mp_msg(MSGT_MENCODER, MSGL_INFO, "\nFlushing video frames\n"); + ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, + VFCTRL_FLUSH_FRAMES, 0); +} + #ifdef HAVE_MP3LAME // fixup CBR mp3 audio header: if(sh_audio && mux_a->codec==ACODEC_VBRMP3 && !lame_param_vbr){