[MPlayer-dev-eng] Re: pre5?

Eric Lammerts eric at lammerts.org
Fri Jun 7 00:24:32 CEST 2002


On Thu, Jun 06, 2002 at 09:08:28PM +0200, Arpi wrote:
> Hi,
> 
> i've collected the importamt changes from cvs log, since pre4:

You never applied this patch (see below) that I sent about two weeks ago. It
adds error checking to mencoder's .avi writing. Without it, mencoder will
happily go on even if the disk is full (producing a corrupted avi). This is
especially bad if you do things like "mencoder <opts> source.mpg && rm -f
source.mpg".

Eric


Index: mencoder.c
===================================================================
RCS file: /cvsroot/mplayer/main/mencoder.c,v
retrieving revision 1.130
diff -u -r1.130 mencoder.c
--- mencoder.c	20 May 2002 03:25:21 -0000	1.130
+++ mencoder.c	26 May 2002 16:49:47 -0000
@@ -12,6 +12,7 @@
 #define ACODEC_VBRMP3 2
 #define ACODEC_NULL 3
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -286,7 +287,10 @@
 
 // callback for ve_*.c:
 void mencoder_write_chunk(aviwrite_stream_t *s,int len,unsigned int flags){
-    aviwrite_write_chunk(muxer,s,muxer_f,len,flags);
+    if(aviwrite_write_chunk(muxer,s,muxer_f,len,flags) < 0) {
+        mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+        mencoder_exit(1, NULL);
+    }
 }
 
 
@@ -733,7 +737,10 @@
 }
 
 printf("Writing AVI header...\n");
-aviwrite_write_header(muxer,muxer_f);
+if(aviwrite_write_header(muxer,muxer_f) < 0) {
+	mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+	mencoder_exit(1, NULL);
+}
 
 decoded_frameno=0;
 
@@ -875,7 +882,10 @@
 	    }
 	}
 	if(len<=0) break; // EOF?
-	aviwrite_write_chunk(muxer,mux_a,muxer_f,len,0);
+	if(aviwrite_write_chunk(muxer,mux_a,muxer_f,len,0) < 0) {
+		mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+		mencoder_exit(1, NULL);
+	}
 	if(!mux_a->h.dwSampleSize && mux_a->timer>0)
 	    mux_a->wf->nAvgBytesPerSec=0.5f+(double)mux_a->size/mux_a->timer; // avg bps (VBR)
 	if(mux_a->buffer_len>=len){
@@ -953,17 +963,32 @@
 switch(mux_v->codec){
 case VCODEC_COPY:
     mux_v->buffer=start;
-    if(skip_flag<=0) aviwrite_write_chunk(muxer,mux_v,muxer_f,in_size,(sh_video->ds->flags&1)?0x10:0);
+    if(skip_flag<=0) {
+        if(aviwrite_write_chunk(muxer,mux_v,muxer_f,in_size,(sh_video->ds->flags&1)?0x10:0) < 0) {
+            mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+            mencoder_exit(1, NULL);
+        }
+    }
     break;
 case VCODEC_FRAMENO:
     mux_v->buffer=&decoded_frameno; // tricky
-    if(skip_flag<=0) aviwrite_write_chunk(muxer,mux_v,muxer_f,sizeof(int),0x10);
+    if(skip_flag<=0) {
+        if(aviwrite_write_chunk(muxer,mux_v,muxer_f,sizeof(int),0x10) < 0) {
+            mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+            mencoder_exit(1, NULL);
+        }
+    }
     break;
 default:
     // decode_video will callback down to ve_*.c encoders, through the video filters
     blit_frame=decode_video(sh_video,start,in_size,(skip_flag>0)?1:0);
     if(skip_flag>0) break;
-    if(!blit_frame) aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0); // empty.
+    if(!blit_frame) { // empty.
+        if(aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0) < 0) {
+            mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+            mencoder_exit(1, NULL);
+        }
+    }
 }
 
 videosamples++;
@@ -974,7 +999,10 @@
 	if(!tv_param_on && !verbose) printf("\nduplicate %d frame(s)!!!    \n",-skip_flag);
     while(skip_flag<0){
 	duplicatedframes++;
-	aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0);
+	if(aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0) < 0) {
+            mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+            mencoder_exit(1, NULL);
+        }
 	++skip_flag;
     }
 } else
@@ -1119,12 +1147,21 @@
 #endif
 
 printf("\nWriting AVI index...\n");
-aviwrite_write_index(muxer,muxer_f);
+if(aviwrite_write_index(muxer,muxer_f) < 0) {
+    mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+    mencoder_exit(1, NULL);
+}
 muxer_f_size=ftello(muxer_f);
 printf("Fixup AVI header...\n");
 fseek(muxer_f,0,SEEK_SET);
-aviwrite_write_header(muxer,muxer_f); // update header
-fclose(muxer_f);
+if(aviwrite_write_header(muxer,muxer_f) < 0) {  // update header
+    mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+    mencoder_exit(1, NULL);
+}
+if(fclose(muxer_f) != 0) {
+    mp_msg(MSGT_MENCODER,MSGL_FATAL,"%s: %s.\n", out_filename, strerror(errno));
+    mencoder_exit(1, NULL);
+}
 
 if(out_video_codec==VCODEC_FRAMENO && mux_v->timer>100){
     printf("Recommended video bitrate for 650MB CD: %d\n",(int)((650*1024*1024-muxer_f_size)/mux_v->timer/125));
Index: libmpdemux/aviwrite.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/aviwrite.h,v
retrieving revision 1.4
diff -u -r1.4 aviwrite.h
--- libmpdemux/aviwrite.h	12 Apr 2002 10:40:38 -0000	1.4
+++ libmpdemux/aviwrite.h	26 May 2002 16:49:47 -0000
@@ -43,9 +43,9 @@
 
 aviwrite_stream_t* aviwrite_new_stream(aviwrite_t *muxer,int type);
 aviwrite_t* aviwrite_new_muxer();
-void aviwrite_write_chunk(aviwrite_t *muxer,aviwrite_stream_t *s, FILE *f,int len,unsigned int flags);
-void aviwrite_write_header(aviwrite_t *muxer,FILE *f);
-void aviwrite_write_index(aviwrite_t *muxer,FILE *f);
+int aviwrite_write_chunk(aviwrite_t *muxer,aviwrite_stream_t *s, FILE *f,int len,unsigned int flags);
+int aviwrite_write_header(aviwrite_t *muxer,FILE *f);
+int aviwrite_write_index(aviwrite_t *muxer,FILE *f);
 
 
 
Index: libmpdemux/aviwrite.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/aviwrite.c,v
retrieving revision 1.7
diff -u -r1.7 aviwrite.c
--- libmpdemux/aviwrite.c	12 Apr 2002 10:40:38 -0000	1.7
+++ libmpdemux/aviwrite.c	26 May 2002 16:49:48 -0000
@@ -54,16 +54,16 @@
     return muxer;
 }
 
-static void write_avi_chunk(FILE *f,unsigned int id,int len,void* data){
-fwrite(&id,4,1,f);
-fwrite(&len,4,1,f);
+static int write_avi_chunk(FILE *f,unsigned int id,int len,void* data){
+if(fwrite(&id,4,1,f) != 1) return -1;
+if(fwrite(&len,4,1,f) != 1) return -1;
 if(len>0){
   if(data){
     // DATA
-    fwrite(data,len,1,f);
+    if(fwrite(data,len,1,f) != 1) return -1;
     if(len&1){  // padding
       unsigned char zerobyte=0;
-      fwrite(&zerobyte,1,1,f);
+      if(fwrite(&zerobyte,1,1,f) != 1) return -1;
     }
   } else {
     // JUNK
@@ -72,14 +72,15 @@
     while(len>0){
       int l=strlen(avi_junk_data);
       if(l>len) l=len;
-      fwrite(avi_junk_data,l,1,f);
+      if(fwrite(avi_junk_data,l,1,f) != 1) return -1;
       len-=l;
     }
   }
 }
+return 0;
 }
 
-void aviwrite_write_chunk(aviwrite_t *muxer,aviwrite_stream_t *s, FILE *f,int len,unsigned int flags){
+int aviwrite_write_chunk(aviwrite_t *muxer,aviwrite_stream_t *s, FILE *f,int len,unsigned int flags){
 
     // add to the index:
     if(muxer->idx_pos>=muxer->idx_size){
@@ -93,7 +94,7 @@
     ++muxer->idx_pos;
 
     // write out the chunk:
-    write_avi_chunk(f,s->ckid,len,s->buffer);
+    if(write_avi_chunk(f,s->ckid,len,s->buffer) < 0) return -1;
     
     // alter counters:
     if(s->h.dwSampleSize){
@@ -107,21 +108,22 @@
     s->timer=(double)s->h.dwLength*s->h.dwScale/s->h.dwRate;
     s->size+=len;
     if(len>s->h.dwSuggestedBufferSize) s->h.dwSuggestedBufferSize=len;
-
+    return 0;
 }
 
-static void write_avi_list(FILE *f,unsigned int id,int len){
+static int write_avi_list(FILE *f,unsigned int id,int len){
   unsigned int list_id=FOURCC_LIST;
   len+=4; // list fix
-  fwrite(&list_id,4,1,f);
-  fwrite(&len,4,1,f);
-  fwrite(&id,4,1,f);
+  if(fwrite(&list_id,4,1,f) != 1 ||
+     fwrite(&len,4,1,f) != 1 ||
+     fwrite(&id,4,1,f) != 1) return -1;
+  return 0;
 }
 
 // muxer->streams[i]->wf->cbSize
 #define WFSIZE(wf) (sizeof(WAVEFORMATEX)+(((wf)->cbSize)?((wf)->cbSize-2):0))
 
-void aviwrite_write_header(aviwrite_t *muxer,FILE *f){
+int aviwrite_write_header(aviwrite_t *muxer,FILE *f){
   unsigned int riff[3];
   int i;
   unsigned int hdrsize;
@@ -129,7 +131,7 @@
   riff[0]=mmioFOURCC('R','I','F','F');
   riff[1]=muxer->file_end;  // filesize
   riff[2]=formtypeAVI; // 'AVI '
-  fwrite(&riff,12,1,f);
+  if(fwrite(&riff,12,1,f) != 1) return -1;
 
   // update AVI header:
   if(muxer->def_v){
@@ -158,8 +160,8 @@
 	  break;
       }
   }
-  write_avi_list(f,listtypeAVIHEADER,hdrsize);
-  write_avi_chunk(f,ckidAVIMAINHDR,sizeof(muxer->avih),&muxer->avih);
+  if(write_avi_list(f,listtypeAVIHEADER,hdrsize) < 0 ||
+     write_avi_chunk(f,ckidAVIMAINHDR,sizeof(muxer->avih),&muxer->avih) < 0) return -1;
 
   // stream headers:
   for(i=0;i<muxer->avih.dwStreams;i++){
@@ -172,35 +174,37 @@
           hdrsize+=WFSIZE(muxer->streams[i]->wf)+8; // strf
 	  break;
       }
-      write_avi_list(f,listtypeSTREAMHEADER,hdrsize);
-      write_avi_chunk(f,ckidSTREAMHEADER,sizeof(muxer->streams[i]->h),&muxer->streams[i]->h); // strh
+      if(write_avi_list(f,listtypeSTREAMHEADER,hdrsize) < 0 ||
+         write_avi_chunk(f,ckidSTREAMHEADER,sizeof(muxer->streams[i]->h),&muxer->streams[i]->h) < 0) return -1; // strh
       switch(muxer->streams[i]->type){
       case AVIWRITE_TYPE_VIDEO:
-          write_avi_chunk(f,ckidSTREAMFORMAT,muxer->streams[i]->bih->biSize,muxer->streams[i]->bih);
+	  if(write_avi_chunk(f,ckidSTREAMFORMAT,muxer->streams[i]->bih->biSize,muxer->streams[i]->bih) < 0) return -1;
 	  break;
       case AVIWRITE_TYPE_AUDIO:
-          write_avi_chunk(f,ckidSTREAMFORMAT,WFSIZE(muxer->streams[i]->wf),muxer->streams[i]->wf);
+	  if(write_avi_chunk(f,ckidSTREAMFORMAT,WFSIZE(muxer->streams[i]->wf),muxer->streams[i]->wf) < 0) return -1;
 	  break;
       }
   }
 
   // JUNK:
-  write_avi_chunk(f,ckidAVIPADDING,2048-(ftell(f)&2047)-8,NULL);
+  if(write_avi_chunk(f,ckidAVIPADDING,2048-(ftell(f)&2047)-8,NULL) < 0) return -1;
   // 'movi' header:
-  write_avi_list(f,listtypeAVIMOVIE,muxer->movi_end-ftell(f)-12);
+  if(write_avi_list(f,listtypeAVIMOVIE,muxer->movi_end-ftell(f)-12) < 0) return -1;
   muxer->movi_start=ftell(f);
+  return 0;
 }
 
-void aviwrite_write_index(aviwrite_t *muxer,FILE *f){
+int aviwrite_write_index(aviwrite_t *muxer,FILE *f){
   muxer->movi_end=ftell(f);
   if(muxer->idx && muxer->idx_pos>0){
       // fixup index entries:
 //      int i;
 //      for(i=0;i<muxer->idx_pos;i++) muxer->idx[i].dwChunkOffset-=muxer->movi_start-4;
       // write index chunk:
-      write_avi_chunk(f,ckidAVINEWINDEX,16*muxer->idx_pos,muxer->idx);
+      if(write_avi_chunk(f,ckidAVINEWINDEX,16*muxer->idx_pos,muxer->idx) < 0) return -1;
       muxer->avih.dwFlags|=AVIF_HASINDEX;
   }
   muxer->file_end=ftell(f);
+  return 0;
 }
 



More information about the MPlayer-dev-eng mailing list