[MPlayer-dev-eng] Re: rc2 is out

Andriy N. Gritsenko andrej at lucky.net
Wed Dec 25 19:13:22 CET 2002


    Hi, Arpi!

Sometime (on Wednesday, December 25 at 17:05) I've received something...
>> You still not applied my muxer patch. :)  So I gotta develop it further.

>yes, i want to avoid people creating unplayable files and then push us to
>fix them ...

You are right, I agree. :)   However MPlayer still creates unplayable
files (AVI with mpeg1 video) so add that patch wouldn't be worse. :)

>> It's ok, may be I or someone else make it better. :)

>i would recommend re-using the mpeg muxer code from either libfame or
>libmp1e. they're well written, standard compliant, even VCD players eat it.
>muxing correct mpeg-ps is not trivial at all, and even the mpeg std is
>unclear at some points.

Hehe... libfame has no muxer code at all, it just produces MPEG1 video
stream. Beside if I could find any working muxer code then I think to
transfer it into mencoder source will be a great headache. ;)

However, I think I finally found the bug. It was a little but too weird
bug. Unfortunately I have no window$ comp right here so I cannot check it
but I hope it must work fine now. ;)  Diff against last patch attached.
If anyone would like to test it right now then I want hear how it works.
Anyway tomorrow or after tomorrow I'll do it myself.

    With best wishes.
    Andriy.

P.S. BTW, I've thought about splitting aviwrite.c into muxer_avi.c and
muxer_mpeg.c, and renaming aviwrite.* to muxer.*, it would help to add
new muxers (qt, ogm, etc.) in future. What do you think about it?
-------------- next part --------------
diff -udpr MPlayer-20021225/libmpdemux/aviwrite.c MPlayer-20021225.new/libmpdemux/aviwrite.c
--- MPlayer-20021225/libmpdemux/aviwrite.c	Wed Dec 25 18:49:12 2002
+++ MPlayer-20021225.new/libmpdemux/aviwrite.c	Wed Dec 25 19:37:59 2002
@@ -87,7 +87,7 @@ if(len>0){
 }
 }
 
-static void avifile_write_chunk(muxer_t *muxer,muxer_stream_t *s, FILE *f,int len,unsigned int flags){
+static void avifile_write_chunk(muxer_t *muxer,muxer_stream_t *s, FILE *f,size_t len,unsigned int flags){
 
     // add to the index:
     if(muxer->idx_pos>=muxer->idx_size){
@@ -322,12 +322,12 @@ static muxer_stream_t* mpegfile_new_stre
 	free (s);
 	s = NULL;
         muxer->avih.dwStreams--;
-//	printf ("MPEG stream can't contain above of 15 video streams!\n");
+	printf ("MPEG stream can't contain above of 15 video streams!\n");
       }
     } else { // MUXER_TYPE_AUDIO
       if (s->id - muxer->num_videos < 31) {
 	s->ckid = be2me_32 (0x1c0 + s->id - muxer->num_videos);
-	printf ("Added audio stream %d\n", s->id - muxer->num_videos + 1);
+//	printf ("Added audio stream %d\n", s->id - muxer->num_videos + 1);
       } else {
 	free (s->b_buffer);
 	free (s);
@@ -492,23 +492,33 @@ static void set_mpeg_pts(muxer_t *muxer,
   write_mpeg_ts (s->b_buffer+7, dts, 0x10);
 }
 
-static void mpegfile_write_chunk(muxer_t *muxer,muxer_stream_t *s, FILE *f,int len,unsigned int flags){
+static void mpegfile_write_chunk(muxer_t *muxer,muxer_stream_t *s,FILE *f,size_t len,unsigned int flags){
   size_t ptr=0, sz;
   unsigned int pts=0;
 
   if (s->type == MUXER_TYPE_VIDEO) { // try to recognize frame type...
     if (s->buffer[0] != 0 || s->buffer[1] != 0 || s->buffer[2] != 1 || len<6) {
       printf ("Unknown block type, possibly non-MPEG stream!\n");
-      return;
-    }
-    if (s->buffer[3] == 0xb8 || s->buffer[3] == 0xb3) { // Sequence or GOP start
-      s->gop_start = s->h.dwLength;
       sz = len;
-    } else if (s->buffer[3] == 0) { // Picture
+//      return;
+    } else if (s->buffer[3] == 0 || s->buffer[3] == 0xb3 ||
+	       s->buffer[3] == 0xb8) { // Picture or GOP
       int temp_ref;
-      int pt = (s->buffer[5]>>3) & 7;
+      int pt;
 
-      temp_ref = (s->buffer[4]<<2)+(s->buffer[5]>>6);
+      if (s->buffer[3]) { // GOP -- scan for Picture
+	s->gop_start = s->h.dwLength;
+	while (ptr < len-5 && (s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 ||
+	       s->buffer[ptr+2] != 1 || s->buffer[ptr+3] != 0)) ptr++;
+      }
+      if (ptr >= len-5) {
+	pt = 0; // Picture not found?!
+	temp_ref = 0;
+	printf ("Warning: picture not found in GOP!\n");
+      } else {
+	pt = (s->buffer[ptr+5]>>3) & 7;
+	temp_ref = (s->buffer[ptr+4]<<2)+(s->buffer[ptr+5]>>6);
+      }
       temp_ref += s->gop_start;
       switch (pt) {
 	case 2: // predictive
@@ -534,6 +544,8 @@ static void mpegfile_write_chunk(muxer_t
 	  s->timer = (double)temp_ref*s->h.dwScale/s->h.dwRate;
 	  break;
 	default: // intra-coded
+	  // pictires may be not in frame sequence so recalculate timer
+	  pts = (int)((double)90000*temp_ref*s->h.dwScale/s->h.dwRate) + MPEG_STARTPTS;
 	  sz = len; // no extra buffer for it...
       }
     } else {
diff -udpr MPlayer-20021225/libmpdemux/aviwrite.h MPlayer-20021225.new/libmpdemux/aviwrite.h
--- MPlayer-20021225/libmpdemux/aviwrite.h	Wed Dec 25 18:49:12 2002
+++ MPlayer-20021225.new/libmpdemux/aviwrite.h	Wed Dec 25 18:52:25 2002
@@ -57,7 +57,7 @@ typedef struct muxer_t{
   //int num_streams;
   muxer_stream_t* def_v;  // default video stream (for general headers)
   muxer_stream_t* streams[MUXER_MAX_STREAMS];
-  void (*cont_write_chunk)(struct muxer_t *muxer,muxer_stream_t *s, FILE *f,int len,unsigned int flags);
+  void (*cont_write_chunk)(struct muxer_t *muxer,muxer_stream_t *s, FILE *f,size_t len,unsigned int flags);
   void (*cont_write_header)(struct muxer_t *muxer,FILE *f);
   void (*cont_write_index)(struct muxer_t *muxer,FILE *f);
   muxer_stream_t* (*cont_new_stream)(struct muxer_t *muxer,int type);


More information about the MPlayer-dev-eng mailing list