changeset 21660:ca9da45d13e9

muxers now write to output muxer->stream rather than to muxer->file
author nicodvb
date Mon, 18 Dec 2006 21:03:59 +0000
parents da09e69a0f01
children 18a091f55d3f
files libmpcodecs/ae.c libmpcodecs/ae_faac.c libmpcodecs/ae_lame.c libmpcodecs/ae_lavc.c libmpcodecs/ae_pcm.c libmpcodecs/ae_toolame.c libmpcodecs/ae_twolame.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_xvid4.c libmpdemux/muxer.c libmpdemux/muxer.h libmpdemux/muxer_avi.c libmpdemux/muxer_lavf.c libmpdemux/muxer_mpeg.c libmpdemux/muxer_rawaudio.c libmpdemux/muxer_rawvideo.c mencoder.c
diffstat 22 files changed, 121 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/ae.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ae.c	Mon Dec 18 21:03:59 2006 +0000
@@ -7,6 +7,7 @@
 #include <math.h>
 #include "aviheader.h"
 #include "ms_hdr.h"
+#include "stream.h"
 #include "muxer.h"
 #include "ae.h"
 #include "config.h"
--- a/libmpcodecs/ae_faac.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ae_faac.c	Mon Dec 18 21:03:59 2006 +0000
@@ -9,6 +9,7 @@
 #include "aviheader.h"
 #include "libaf/af_format.h"
 #include "ms_hdr.h"
+#include "stream.h"
 #include "muxer.h"
 #include <faac.h>
 #include "ae.h"
--- a/libmpcodecs/ae_lame.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ae_lame.c	Mon Dec 18 21:03:59 2006 +0000
@@ -8,6 +8,7 @@
 #include "mp_msg.h"
 #include "aviheader.h"
 #include "ms_hdr.h"
+#include "stream.h"
 #include "muxer.h"
 #include "help_mp.h"
 #include "ae_pcm.h"
--- a/libmpcodecs/ae_lavc.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ae_lavc.c	Mon Dec 18 21:03:59 2006 +0000
@@ -8,6 +8,7 @@
 #include "mp_msg.h"
 #include "aviheader.h"
 #include "ms_hdr.h"
+#include "stream.h"
 #include "muxer.h"
 #include "ae_lavc.h"
 #include "help_mp.h"
--- a/libmpcodecs/ae_pcm.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ae_pcm.c	Mon Dec 18 21:03:59 2006 +0000
@@ -9,6 +9,7 @@
 #include "aviheader.h"
 #include "libaf/af_format.h"
 #include "ms_hdr.h"
+#include "stream.h"
 #include "muxer.h"
 #include "ae_pcm.h"
 
--- a/libmpcodecs/ae_toolame.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ae_toolame.c	Mon Dec 18 21:03:59 2006 +0000
@@ -9,6 +9,7 @@
 #include "aviheader.h"
 #include "libaf/af_format.h"
 #include "ms_hdr.h"
+#include "stream.h"
 #include "muxer.h"
 #include "ae_toolame.h"
 #include "libmpdemux/mp3_hdr.h"
--- a/libmpcodecs/ae_twolame.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ae_twolame.c	Mon Dec 18 21:03:59 2006 +0000
@@ -9,6 +9,7 @@
 #include "aviheader.h"
 #include "libaf/af_format.h"
 #include "ms_hdr.h"
+#include "stream.h"
 #include "muxer.h"
 #include "ae_twolame.h"
 #include "libmpdemux/mp3_hdr.h"
--- a/libmpcodecs/ve_libdv.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ve_libdv.c	Mon Dec 18 21:03:59 2006 +0000
@@ -13,6 +13,7 @@
 #include "demuxer.h"
 #include "stheader.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 #include "img_format.h"
--- a/libmpcodecs/ve_nuv.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ve_nuv.c	Mon Dec 18 21:03:59 2006 +0000
@@ -12,6 +12,7 @@
 #include "demuxer.h"
 #include "stheader.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 #include "img_format.h"
--- a/libmpcodecs/ve_qtvideo.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ve_qtvideo.c	Mon Dec 18 21:03:59 2006 +0000
@@ -25,6 +25,7 @@
 #include "demuxer.h"
 #include "stheader.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 #include "img_format.h"
--- a/libmpcodecs/ve_raw.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ve_raw.c	Mon Dec 18 21:03:59 2006 +0000
@@ -11,6 +11,7 @@
 #include "demuxer.h"
 #include "stheader.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 #include "img_format.h"
--- a/libmpcodecs/ve_vfw.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ve_vfw.c	Mon Dec 18 21:03:59 2006 +0000
@@ -23,6 +23,7 @@
 #include "mp_image.h"
 #include "vf.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 //===========================================================================//
--- a/libmpcodecs/ve_x264.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ve_x264.c	Mon Dec 18 21:03:59 2006 +0000
@@ -39,6 +39,7 @@
 #include "demuxer.h"
 #include "stheader.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 #include "img_format.h"
--- a/libmpcodecs/ve_xvid4.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpcodecs/ve_xvid4.c	Mon Dec 18 21:03:59 2006 +0000
@@ -41,6 +41,7 @@
 #include "demuxer.h"
 #include "stheader.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 #include "img_format.h"
--- a/libmpdemux/muxer.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpdemux/muxer.c	Mon Dec 18 21:03:59 2006 +0000
@@ -11,18 +11,18 @@
 #include "aviheader.h"
 #include "ms_hdr.h"
 
+#include "stream.h"
 #include "muxer.h"
-#include "stream.h"
 #include "demuxer.h"
 #include "mp_msg.h"
 #include "help_mp.h"
 #include "stheader.h"
 
-muxer_t *muxer_new_muxer(int type,FILE *f){
+muxer_t *muxer_new_muxer(int type,stream_t *stream){
     muxer_t* muxer=calloc(1,sizeof(muxer_t));
     if(!muxer)
         return NULL;
-    muxer->file = f;
+    muxer->stream = stream;
     switch (type) {
       case MUXER_TYPE_MPEG:
 	if(! muxer_init_muxer_mpeg(muxer))
--- a/libmpdemux/muxer.h	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpdemux/muxer.h	Mon Dec 18 21:03:59 2006 +0000
@@ -79,12 +79,12 @@
   int muxbuf_num;
   int muxbuf_skip_buffer;
   // functions:
+  stream_t *stream;
   void (*fix_stream_parameters)(muxer_stream_t *);
   void (*cont_write_chunk)(muxer_stream_t *,size_t,unsigned int, double dts, double pts);
   void (*cont_write_header)(struct muxer_t *);
   void (*cont_write_index)(struct muxer_t *);
   muxer_stream_t* (*cont_new_stream)(struct muxer_t *,int);
-  FILE* file;
   void *priv;
 } muxer_t;
 
@@ -98,7 +98,7 @@
   unsigned int flags;
 } muxbuf_t;
 
-muxer_t *muxer_new_muxer(int type,FILE *);
+muxer_t *muxer_new_muxer(int type,stream_t *stream);
 #define muxer_new_stream(muxer,a) muxer->cont_new_stream(muxer,a)
 #define muxer_stream_fix_parameters(muxer, a) muxer->fix_stream_parameters(a)
 void muxer_write_chunk(muxer_stream_t *s, size_t len, unsigned int flags, double dts, double pts);
--- a/libmpdemux/muxer_avi.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpdemux/muxer_avi.c	Mon Dec 18 21:03:59 2006 +0000
@@ -130,19 +130,19 @@
     return s;
 }
 
-static void write_avi_chunk(FILE *f,unsigned int id,int len,void* data){
+static void write_avi_chunk(stream_t *stream,unsigned int id,int len,void* data){
  int le_len = le2me_32(len);
  int le_id = le2me_32(id);
- fwrite(&le_id,4,1,f);
- fwrite(&le_len,4,1,f);
+ stream_write_buffer(stream, &le_id, 4);
+ stream_write_buffer(stream, &le_len, 4);
 
 if(len>0){
   if(data){
     // DATA
-    fwrite(data,len,1,f);
+    stream_write_buffer(stream, data, len);
     if(len&1){  // padding
       unsigned char zerobyte=0;
-      fwrite(&zerobyte,1,1,f);
+      stream_write_buffer(stream, &zerobyte, 1);
     }
   } else {
     // JUNK
@@ -151,20 +151,19 @@
     while(len>0){
       int l=strlen(avi_junk_data);
       if(l>len) l=len;
-      fwrite(avi_junk_data,l,1,f);
+      stream_write_buffer(stream, avi_junk_data, l);
       len-=l;
     }
   }
 }
 }
 
-static void write_avi_list(FILE *f,unsigned int id,int len);
+static void write_avi_list(stream_t *s,unsigned int id,int len);
 static void avifile_write_standard_index(muxer_t *muxer);
 
 static void avifile_odml_new_riff(muxer_t *muxer)
 {
     struct avi_stream_info *vsi = muxer->def_v->priv;
-    FILE *f = muxer->file;
     uint32_t riff[3];
 
     mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Starting new RIFF chunk at %dMB.\n", (int)(muxer->file_end/1024/1024));
@@ -174,17 +173,17 @@
         vsi->riffofssize+=16;
         vsi->riffofs=realloc_struct(vsi->riffofs,(vsi->riffofssize+1),sizeof(off_t));
     }
-    vsi->riffofs[vsi->riffofspos] = ftello(f);
+    vsi->riffofs[vsi->riffofspos] = stream_tell(muxer->stream);
 
     /* RIFF/AVIX chunk */
     riff[0]=le2me_32(mmioFOURCC('R','I','F','F'));
     riff[1]=0;
     riff[2]=le2me_32(mmioFOURCC('A','V','I','X'));
-    fwrite(riff,12,1,f);
+    stream_write_buffer(muxer->stream, riff, 12);
 
-    write_avi_list(f,listtypeAVIMOVIE,0);
+    write_avi_list(muxer->stream,listtypeAVIMOVIE,0);
 
-    muxer->file_end = ftello(f);
+    muxer->file_end = stream_tell(muxer->stream);
 }
 
 static void avifile_write_header(muxer_t *muxer);
@@ -197,10 +196,10 @@
     int paddedlen = len + (len&1);
 
     if (s->type == MUXER_TYPE_VIDEO && !s->h.dwSuggestedBufferSize) {
-	off_t pos=ftell(muxer->file);
-	fseek(muxer->file, 0, SEEK_SET);
+	off_t pos=stream_tell(muxer->stream);
+	stream_seek(muxer->stream, 0);
 	avifile_write_header(muxer);
-	fseek(muxer->file, pos, SEEK_SET);
+	stream_seek(muxer->stream, pos);
     }
 
     rifflen = muxer->file_end - vsi->riffofs[vsi->riffofspos] - 8;
@@ -238,7 +237,7 @@
     ++si->idxpos;
 
     // write out the chunk:
-    write_avi_chunk(muxer->file,s->ckid,len,s->buffer); /* unsigned char */
+    write_avi_chunk(muxer->stream,s->ckid,len,s->buffer); /* unsigned char */
 
     if (len > s->h.dwSuggestedBufferSize){
 	s->h.dwSuggestedBufferSize = len;
@@ -248,7 +247,7 @@
     muxer->file_end += 8 + paddedlen;
 }
 
-static void write_avi_list(FILE *f,unsigned int id,int len){
+static void write_avi_list(stream_t *stream,unsigned int id,int len){
   unsigned int list_id=FOURCC_LIST;
   int le_len;
   int le_id;
@@ -256,9 +255,9 @@
   list_id = le2me_32(list_id);
   le_len = le2me_32(len);
   le_id = le2me_32(id);
-  fwrite(&list_id,4,1,f);
-  fwrite(&le_len,4,1,f);
-  fwrite(&le_id,4,1,f);
+  stream_write_buffer(stream, &list_id, 4);
+  stream_write_buffer(stream, &le_len, 4);
+  stream_write_buffer(stream, &le_id, 4);
 }
 
 #define WFSIZE(wf) (sizeof(WAVEFORMATEX)+(wf)->cbSize)
@@ -269,7 +268,6 @@
   unsigned int i;
   unsigned int hdrsize;
   muxer_info_t info[16];
-  FILE *f = muxer->file;
   VideoPropHeader vprp;
   uint32_t aspect = avi_aspect(muxer->def_v);
   struct avi_stream_info *vsi = muxer->def_v->priv;
@@ -306,17 +304,17 @@
           rifflen = vsi->riffofs[i+1] - vsi->riffofs[i] - 8;
           movilen = le2me_32(rifflen - 12);
           rifflen = le2me_32(rifflen);
-          fseeko(f, vsi->riffofs[i]+4, SEEK_SET);
-          fwrite(&rifflen,4,1,f);
+          stream_seek(muxer->stream, vsi->riffofs[i]+4);
+          stream_write_buffer(muxer->stream,&rifflen,4);
 
           /* fixup movi length */
           if (i > 0) {
-              fseeko(f, vsi->riffofs[i]+16, SEEK_SET);
-              fwrite(&movilen,4,1,f);
+              stream_seek(muxer->stream, vsi->riffofs[i]+16);
+              stream_write_buffer(muxer->stream,&movilen,4);
           }
       }
 
-      fseeko(f, 12, SEEK_SET);
+      stream_seek(muxer->stream, 12);
   } else {
     // RIFF header:
     riff[0]=mmioFOURCC('R','I','F','F');
@@ -325,7 +323,7 @@
     riff[0]=le2me_32(riff[0]);
     riff[1]=le2me_32(riff[1]);
     riff[2]=le2me_32(riff[2]);
-    fwrite(&riff,12,1,f);
+    stream_write_buffer(muxer->stream,&riff,12);
   }
 
   // update AVI header:
@@ -370,10 +368,10 @@
 	  hdrsize += 32 + 16*si->superidxsize; //indx
       }
   }
-  write_avi_list(f,listtypeAVIHEADER,hdrsize);
+  write_avi_list(muxer->stream,listtypeAVIHEADER,hdrsize);
   
   le2me_MainAVIHeader(&muxer->avih);
-  write_avi_chunk(f,ckidAVIMAINHDR,sizeof(muxer->avih),&muxer->avih); /* MainAVIHeader */
+  write_avi_chunk(muxer->stream,ckidAVIMAINHDR,sizeof(muxer->avih),&muxer->avih); /* MainAVIHeader */
   le2me_MainAVIHeader(&muxer->avih);
 
   // stream headers:
@@ -416,9 +414,9 @@
 	  break;
       }
 
-      write_avi_list(f,listtypeSTREAMHEADER,hdrsize);
+      write_avi_list(muxer->stream,listtypeSTREAMHEADER,hdrsize);
       le2me_AVIStreamHeader(&s->h);
-      write_avi_chunk(f,ckidSTREAMHEADER,sizeof(s->h),&s->h); /* AVISTreamHeader */ // strh
+      write_avi_chunk(muxer->stream,ckidSTREAMHEADER,sizeof(s->h),&s->h); /* AVISTreamHeader */ // strh
       le2me_AVIStreamHeader(&s->h);
 
       switch(s->type){
@@ -426,7 +424,7 @@
 {
           int biSize=s->bih->biSize;
           le2me_BITMAPINFOHEADER(s->bih);
-          write_avi_chunk(f,ckidSTREAMFORMAT,biSize,s->bih); /* BITMAPINFOHEADER */
+          write_avi_chunk(muxer->stream,ckidSTREAMFORMAT,biSize,s->bih); /* BITMAPINFOHEADER */
           le2me_BITMAPINFOHEADER(s->bih);
 
 	  if (aspect != 0) {
@@ -434,7 +432,7 @@
 	      le2me_VideoPropHeader(&vprp);
 	      le2me_VIDEO_FIELD_DESC(&vprp.FieldInfo[0]);
 	      le2me_VIDEO_FIELD_DESC(&vprp.FieldInfo[1]);
-	      write_avi_chunk(f,mmioFOURCC('v','p','r','p'),
+	      write_avi_chunk(muxer->stream,mmioFOURCC('v','p','r','p'),
 	                      sizeof(VideoPropHeader) -
 	                      sizeof(VIDEO_FIELD_DESC)*(2-fields),
 	                      &vprp); /* Video Properties Header */
@@ -445,7 +443,7 @@
 {
           int wfsize = WFSIZE(s->wf);
           le2me_WAVEFORMATEX(s->wf);
-          write_avi_chunk(f,ckidSTREAMFORMAT,wfsize,s->wf); /* WAVEFORMATEX */
+          write_avi_chunk(muxer->stream,ckidSTREAMFORMAT,wfsize,s->wf); /* WAVEFORMATEX */
           le2me_WAVEFORMATEX(s->wf);
 }	  
 	  break;
@@ -462,7 +460,7 @@
 	  idxhdr[6] = 0;
 	  idxhdr[7] = 0;
 
-	  fwrite(idxhdr,sizeof(idxhdr),1,f);
+	  stream_write_buffer(muxer->stream,idxhdr,sizeof(idxhdr));
 	  for (j=0; j<n; j++) {
 	      struct avi_odmlsuperidx_entry *entry = &si->superidx[j];
 	      unsigned int data[4];
@@ -470,7 +468,7 @@
 	      data[1] = le2me_32(entry->ofs >> 32);
 	      data[2] = le2me_32(entry->len);
 	      data[3] = le2me_32(entry->duration);
-	      fwrite(data,sizeof(data),1,f);
+	      stream_write_buffer(muxer->stream,data,sizeof(data));
 	  }
       }
   }
@@ -479,8 +477,8 @@
   if (isodml) {
       memset(dmlh, 0, sizeof(dmlh));
       dmlh[0] = le2me_32(muxer->avih.dwTotalFrames);
-      write_avi_list(f,mmioFOURCC('o','d','m','l'),sizeof(dmlh)+8);
-      write_avi_chunk(f,mmioFOURCC('d','m','l','h'),sizeof(dmlh),dmlh);
+      write_avi_list(muxer->stream,mmioFOURCC('o','d','m','l'),sizeof(dmlh)+8);
+      write_avi_chunk(muxer->stream,mmioFOURCC('d','m','l','h'),sizeof(dmlh),dmlh);
   }
 
 // ============= INFO ===============
@@ -527,27 +525,27 @@
   }
   // write infos:
   if (hdrsize!=0){
-      write_avi_list(f,mmioFOURCC('I','N','F','O'),hdrsize);
+      write_avi_list(muxer->stream,mmioFOURCC('I','N','F','O'),hdrsize);
       for(i=0;info[i].id!=0;i++) if(info[i].text){
-          write_avi_chunk(f,info[i].id,strlen(info[i].text)+1,info[i].text);
+          write_avi_chunk(muxer->stream,info[i].id,strlen(info[i].text)+1,info[i].text);
       }
   }
 
   // JUNK:
-  write_avi_chunk(f,ckidAVIPADDING,MOVIALIGN-(ftello(f)%MOVIALIGN)-8,NULL); /* junk */
+  write_avi_chunk(muxer->stream,ckidAVIPADDING,MOVIALIGN-(stream_tell(muxer->stream)%MOVIALIGN)-8,NULL); /* junk */
   if (!isodml) {
     // 'movi' header:
-    write_avi_list(f,listtypeAVIMOVIE,muxer->movi_end-ftello(f)-12);
+    write_avi_list(muxer->stream,listtypeAVIMOVIE,muxer->movi_end-stream_tell(muxer->stream)-12);
   } else {
-    if (ftello(f) != MOVIALIGN) {
+    if (stream_tell(muxer->stream) != MOVIALIGN) {
 	mp_msg(MSGT_MUXER, MSGL_ERR, "Opendml superindex is too big for reserved space!\n");
-	mp_msg(MSGT_MUXER, MSGL_ERR, "Expected filepos %d, real filepos %ld, missing space %ld\n", MOVIALIGN, ftell(muxer->file), ftell(muxer->file)-MOVIALIGN);
+	mp_msg(MSGT_MUXER, MSGL_ERR, "Expected filepos %d, real filepos %ld, missing space %ld\n", MOVIALIGN, stream_tell(muxer->stream), stream_tell(muxer->stream)-MOVIALIGN);
 	mp_msg(MSGT_MUXER, MSGL_ERR, "Try increasing MOVIALIGN in libmpdemux/muxer_avi.c\n");
     }
-    write_avi_list(f,listtypeAVIMOVIE,muxer->movi_end-ftello(f)-12);
+    write_avi_list(muxer->stream,listtypeAVIMOVIE,muxer->movi_end-stream_tell(muxer->stream)-12);
   }
-  muxer->movi_start=ftello(muxer->file);
-  if (muxer->file_end == 0) muxer->file_end = ftello(muxer->file);
+  muxer->movi_start=stream_tell(muxer->stream);
+  if (muxer->file_end == 0) muxer->file_end = stream_tell(muxer->stream);
 }
 
 static void avifile_odml_write_index(muxer_t *muxer){
@@ -619,36 +617,36 @@
 	idxhdr[7] = 0; /* unused */
 
 	si->superidx[j].len = 32 + 8*k;
-	si->superidx[j].ofs = ftello(muxer->file);
+	si->superidx[j].ofs = stream_tell(muxer->stream);
 	si->superidx[j].duration = duration;
 
-	fwrite(idxhdr,sizeof(idxhdr),1,muxer->file);
+	stream_write_buffer(muxer->stream, idxhdr,sizeof(idxhdr));
 	for (k=0; k<entries_per_subidx && idxpos<si->idxpos; k++) {
 	    unsigned int entry[2];
 	    entry[0] = le2me_32(si->idx[idxpos].ofs - start);
 	    entry[1] = le2me_32(si->idx[idxpos].len | si->idx[idxpos].flags);
 	    idxpos++;
-	    fwrite(entry,sizeof(entry),1,muxer->file);
+	    stream_write_buffer(muxer->stream, entry, sizeof(entry));
 	}
      }
   }
-  muxer->file_end=ftello(muxer->file);
+  muxer->file_end=stream_tell(muxer->stream);
 }
 
 static void avifile_write_standard_index(muxer_t *muxer){
 
-  muxer->movi_end=ftello(muxer->file);
+  muxer->movi_end=stream_tell(muxer->stream);
   if(muxer->idx && muxer->idx_pos>0){
       int i;
       // fixup index entries:
 //      for(i=0;i<muxer->idx_pos;i++) muxer->idx[i].dwChunkOffset-=muxer->movi_start-4;
       // write index chunk:
       for (i=0; i<muxer->idx_pos; i++) le2me_AVIINDEXENTRY((&muxer->idx[i]));
-      write_avi_chunk(muxer->file,ckidAVINEWINDEX,16*muxer->idx_pos,muxer->idx); /* AVIINDEXENTRY */
+      write_avi_chunk(muxer->stream,ckidAVINEWINDEX,16*muxer->idx_pos,muxer->idx); /* AVIINDEXENTRY */
       for (i=0; i<muxer->idx_pos; i++) le2me_AVIINDEXENTRY((&muxer->idx[i]));
       muxer->avih.dwFlags|=AVIF_HASINDEX;
   }
-  muxer->file_end=ftello(muxer->file);
+  muxer->file_end=stream_tell(muxer->stream);
 }
 
 static void avifile_write_index(muxer_t *muxer){
--- a/libmpdemux/muxer_lavf.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpdemux/muxer_lavf.c	Mon Dec 18 21:03:59 2006 +0000
@@ -12,8 +12,8 @@
 #include "aviheader.h"
 #include "ms_hdr.h"
 
+#include "stream.h"
 #include "muxer.h"
-#include "stream.h"
 #include "demuxer.h"
 #include "stheader.h"
 #include "m_option.h"
@@ -89,14 +89,30 @@
 static int mp_write(URLContext *h, unsigned char *buf, int size)
 {
 	muxer_t *muxer = (muxer_t*)h->priv_data;
-	return fwrite(buf, 1, size, muxer->file);
+	return stream_write_buffer(muxer->stream, buf, size);
 }
 
 static offset_t mp_seek(URLContext *h, offset_t pos, int whence)
 {
 	muxer_t *muxer = (muxer_t*)h->priv_data;
+	if(whence == SEEK_CUR)
+	{
+		off_t cur = stream_tell(muxer->stream);
+		if(cur == -1)
+			return -1;
+		pos += cur;
+	}
+	else if(whence == SEEK_END)
+	{
+		off_t size=0;
+		if(stream_control(muxer->stream, STREAM_CTRL_GET_SIZE, &size) == STREAM_UNSUPORTED || size < pos)
+			return -1;
+		pos = size - pos;
+	}
 	mp_msg(MSGT_MUXER, MSGL_DBG2, "SEEK %"PRIu64"\n", (int64_t)pos);
-	return fseeko(muxer->file, pos, whence);
+	if(!stream_seek(muxer->stream, pos))
+		return -1;
+	return 0;
 }
 
 
--- a/libmpdemux/muxer_mpeg.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpdemux/muxer_mpeg.c	Mon Dec 18 21:03:59 2006 +0000
@@ -12,8 +12,8 @@
 #include "aviheader.h"
 #include "ms_hdr.h"
 
+#include "stream.h"
 #include "muxer.h"
-#include "stream.h"
 #include "demuxer.h"
 #include "stheader.h"
 #include "m_option.h"
@@ -748,7 +748,7 @@
 	memset(&buff[6], 0xff, len - 6);
 }
 
-static void write_psm_block(muxer_t *muxer, FILE *f)
+static void write_psm_block(muxer_t *muxer, stream_t *stream)
 {
 	uint16_t offset, stuffing_len;
 	muxer_priv_t *priv = (muxer_priv_t *) muxer->priv;
@@ -763,7 +763,7 @@
 		write_pes_padding(&buff[offset], stuffing_len);
 		offset += stuffing_len;
 	}
-	fwrite(buff, offset, 1, f);
+	stream_write_buffer(stream, buff, offset);
 	priv->headers_size += offset;
 }
 
@@ -824,7 +824,7 @@
 }
 
 	
-static int write_mpeg_pack(muxer_t *muxer, muxer_stream_t *s, FILE *f, int isoend)
+static int write_mpeg_pack(muxer_t *muxer, muxer_stream_t *s, stream_t *stream, int isoend)
 {
 	size_t tot, offset;
 	muxer_priv_t *priv;
@@ -842,7 +842,7 @@
 		buff[offset + 2] = 1;
 		buff[offset + 3] = 0xb9;
 		
-		fwrite(buff, priv->packet_size, 1, f);
+		stream_write_buffer(stream, buff, priv->packet_size);
 		return 1;
 	}
 	else	//FAKE DVD NAV PACK
@@ -863,7 +863,7 @@
 			offset += stuffing_len;
 		}
 			
-		fwrite(buff, offset, 1, f);
+		stream_write_buffer(stream, buff, offset);
 		priv->headers_size += offset;
 		tot = offset;
 		muxer->movi_end += tot;
@@ -1240,7 +1240,7 @@
 	spriv->size += len;
 
 	if(dvd_pack && (spriv->pack_offset == priv->packet_size))
-		write_mpeg_pack(muxer, NULL, muxer->file, 0);	//insert fake Nav Packet
+		write_mpeg_pack(muxer, NULL, muxer->stream, 0);	//insert fake Nav Packet
 
 	if(n > 0)
 		remove_frames(spriv,  n);
@@ -1259,7 +1259,7 @@
 		spriv->pack_offset += diff;
 	}
 	
-	fwrite(spriv->pack, spriv->pack_offset, 1, muxer->file);
+	stream_write_buffer(muxer->stream, spriv->pack, spriv->pack_offset);
 
 	priv->headers_size += spriv->pack_offset - len;
 	priv->data_size += len;
@@ -2351,7 +2351,7 @@
 	spriv->psm_fixed = 1;
 	priv->psm_streams_cnt++;
 	if((priv->psm_streams_cnt == muxer->num_videos + muxer->num_audios) && priv->use_psm)
-		write_psm_block(muxer, muxer->file);
+		write_psm_block(muxer, muxer->stream);
   }
 
   flush_buffers(muxer, 0);
@@ -2374,7 +2374,7 @@
 	while(flush_buffers(muxer, 0) > 0);
 	flush_buffers(muxer, 1);
 	if(priv->is_genmpeg1 || priv->is_genmpeg2)
-		write_mpeg_pack(muxer, NULL, muxer->file, 1);	//insert fake Nav Packet
+		write_mpeg_pack(muxer, NULL, muxer->stream, 1);	//insert fake Nav Packet
 		
 	mp_msg(MSGT_MUXER, MSGL_INFO, "\nOverhead: %.3lf%% (%"PRIu64" / %"PRIu64")\n", 100.0 * (double)priv->headers_size / (double)priv->data_size, priv->headers_size, priv->data_size);
 }
@@ -2400,7 +2400,7 @@
 	//write the first system header only for generic mpeg1/2 muxes, and only when we have collected all necessary infos
 	if(priv->is_genmpeg1 || priv->is_genmpeg2 || ((priv->is_xvcd || priv->is_xsvcd) && (priv->headers_cnt == 1)))
 	{
-		write_mpeg_pack(muxer, NULL, muxer->file, 0);
+		write_mpeg_pack(muxer, NULL, muxer->stream, 0);
 		priv->update_system_header = 0;
 	}
 	
--- a/libmpdemux/muxer_rawaudio.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpdemux/muxer_rawaudio.c	Mon Dec 18 21:03:59 2006 +0000
@@ -9,6 +9,7 @@
 #include "aviheader.h"
 #include "ms_hdr.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 static muxer_stream_t* rawaudiofile_new_stream(muxer_t *muxer,int type){
@@ -50,7 +51,7 @@
 
     // write out the chunk:
     if (s->type==MUXER_TYPE_AUDIO)
-        fwrite(s->buffer,len,1,muxer->file);
+        stream_write_buffer(muxer->stream, s->buffer, len);
 }
 
 static void rawaudiofile_write_header(muxer_t *muxer){
--- a/libmpdemux/muxer_rawvideo.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/libmpdemux/muxer_rawvideo.c	Mon Dec 18 21:03:59 2006 +0000
@@ -14,6 +14,7 @@
 #include "aviheader.h"
 #include "ms_hdr.h"
 
+#include "stream.h"
 #include "muxer.h"
 
 static muxer_stream_t* rawvideofile_new_stream(muxer_t *muxer,int type){
@@ -39,11 +40,11 @@
     return s;
 }
 
-static void write_rawvideo_chunk(FILE *f,int len,void* data){
+static void write_rawvideo_chunk(stream_t *stream,int len,void* data){
     if(len>0){
 	if(data){
 	    // DATA
-	    fwrite(data,len,1,f);
+            stream_write_buffer(stream,data,len);
 	}
     }
 }
@@ -53,7 +54,7 @@
 
     // write out the chunk:
     if (s->type == MUXER_TYPE_VIDEO)
-    write_rawvideo_chunk(muxer->file,len,s->buffer); /* unsigned char */
+    write_rawvideo_chunk(muxer->stream,len,s->buffer); /* unsigned char */
 
     // if((unsigned int)len>s->h.dwSuggestedBufferSize) s->h.dwSuggestedBufferSize=len;
 
--- a/mencoder.c	Mon Dec 18 20:56:24 2006 +0000
+++ b/mencoder.c	Mon Dec 18 21:03:59 2006 +0000
@@ -359,13 +359,13 @@
 }
 
 static muxer_t* muxer=NULL;
-static FILE* muxer_f=NULL;
 
 extern void print_wave_header(WAVEFORMATEX *h, int verbose_level);
 
 int main(int argc,char* argv[]){
 
 stream_t* stream=NULL;
+stream_t* ostream=NULL;
 demuxer_t* demuxer=NULL;
 stream_t* stream2=NULL;
 demuxer_t* demuxer2=NULL;
@@ -402,6 +402,7 @@
 int next_frameno=-1;
 int curfile=0;
 int new_srate=0;
+int fformat=DEMUXER_TYPE_UNKNOWN;
 
 unsigned int timer_start=0;
 ao_data_t ao_data = {0,0,0,0,OUTBURST,-1,0};
@@ -713,17 +714,13 @@
 // Apply current settings for forced subs
 spudec_set_forced_subs_only(vo_spudec,forced_subs_only);
 
-// set up output file:
-if(!strcmp(out_filename, "-"))
-    muxer_f=stdout;
-else
-    muxer_f=fopen(out_filename,"wb");
-if(!muxer_f) {
+ostream = open_output_stream(out_filename, 0);
+if(!ostream) {
   mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CannotOpenOutputFile, out_filename);
   mencoder_exit(1,NULL);
 }
 
-muxer=muxer_new_muxer(out_file_format,muxer_f);
+muxer=muxer_new_muxer(out_file_format,ostream);
 if(!muxer) {
   mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CannotInitializeMuxer);
   mencoder_exit(1,NULL);
@@ -1092,7 +1089,7 @@
     float v_pts=0;
     int skip_flag=0; // 1=skip  -1=duplicate
 
-    if((end_at.type == END_AT_SIZE && end_at.pos <= ftello(muxer_f))  ||
+    if((end_at.type == END_AT_SIZE && end_at.pos <= stream_tell(muxer->stream))  ||
        (end_at.type == END_AT_TIME && end_at.pos < mux_v->timer))
         break;
 
@@ -1451,7 +1448,7 @@
 	    	mux_v->timer, decoded_frameno, (int)(p*100),
 	    	(t>1) ? (int)(decoded_frameno/t+0.5) : 0,
 	    	(p>0.001) ? (int)((t/p-t)/60) : 0, 
-	    	(p>0.001) ? (int)(ftello(muxer_f)/p/1024/1024) : 0,
+	    	(p>0.001) ? (int)(stream_tell(muxer->stream)/p/1024/1024) : 0,
 	    	v_pts_corr,
 	    	(mux_v->timer>1) ? (int)(mux_v->size/mux_v->timer/125) : 0,
 	    	(mux_a && mux_a->timer>1) ? (int)(mux_a->size/mux_a->timer/125) : 0,
@@ -1463,7 +1460,7 @@
 	    mux_v->timer, decoded_frameno, (int)(p*100),
 	    (t>1) ? (float)(decoded_frameno/t) : 0,
 	    (p>0.001) ? (int)((t/p-t)/60) : 0, 
-	    (p>0.001) ? (int)(ftello(muxer_f)/p/1024/1024) : 0,
+	    (p>0.001) ? (int)(stream_tell(muxer->stream)/p/1024/1024) : 0,
 	    v_pts_corr,
 	    (mux_v->timer>1) ? (int)(mux_v->size/mux_v->timer/125) : 0,
 	    (mux_a && mux_a->timer>1) ? (int)(mux_a->size/mux_a->timer/125) : 0
@@ -1506,10 +1503,12 @@
 
  frame_data = (s_frame_data){ .start = NULL, .in_size = 0, .frame_time = 0., .already_read = 0 };
 
+#if 0
  if(ferror(muxer_f)) {
      mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile, out_filename);
      mencoder_exit(1, NULL);
  }
+#endif
 
 } // while(!at_eof)
 
@@ -1549,13 +1548,15 @@
         aencoder->fixup(aencoder);
 
 if (muxer->cont_write_index) muxer_write_index(muxer);
-muxer_f_size=ftello(muxer_f);
-fseek(muxer_f,0,SEEK_SET);
+muxer_f_size=stream_tell(muxer->stream);
+stream_seek(muxer->stream,0);
 if (muxer->cont_write_header) muxer_write_header(muxer); // update header
+#if 0
 if(ferror(muxer_f) || fclose(muxer_f) != 0) {
     mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile, out_filename);
     mencoder_exit(1, NULL);
 }
+#endif
 if(vobsub_writer)
     vobsub_out_close(vobsub_writer);