changeset 14878:5723c4b2a2ea

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 <ods15@ods15.dyndns.org>
author henry
date Tue, 01 Mar 2005 20:21:58 +0000
parents db1f17e9b7a2
children 3b89d966f17e
files help/help_mp-en.h libmpcodecs/vd.c libmpcodecs/ve_divx4.c libmpcodecs/ve_lavc.c libmpcodecs/ve_libdv.c libmpcodecs/ve_nuv.c libmpcodecs/ve_qtvideo.c libmpcodecs/ve_raw.c libmpcodecs/ve_vfw.c libmpcodecs/ve_x264.c libmpcodecs/ve_xvid.c libmpcodecs/ve_xvid4.c libmpcodecs/vf.c libmpcodecs/vf.h libmpcodecs/vfcap.h mencoder.c
diffstat 16 files changed, 81 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- 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"
--- 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;
--- 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;
--- 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;
--- 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;
--- 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;
--- 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;
--- 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;
--- 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;
--- 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;
--- 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;
--- 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;
--- 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){
--- 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);
--- 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
 
--- 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){