- VCD MPEG-1 compliant stream support (set AVF_FLAG_VCD)
authorJuanjo <pulento@users.sourceforge.net>
Sun, 12 May 2002 21:38:54 +0000 (21:38 +0000)
committerJuanjo <pulento@users.sourceforge.net>
Sun, 12 May 2002 21:38:54 +0000 (21:38 +0000)
Originally committed as revision 491 to svn://svn.ffmpeg.org/ffmpeg/trunk

libav/avformat.h
libav/mpeg.c

index 10de1f8..3b20a2d 100644 (file)
@@ -1,7 +1,7 @@
 
 #define LIBAV_VERSION_INT 0x000406  
 #define LIBAV_VERSION     "0.4.6"
-#define LIBAV_BUILD       4600
+#define LIBAV_BUILD       4601
 
 #include "avcodec.h"
 
@@ -94,6 +94,7 @@ typedef struct AVFormatContext {
     char author[512];
     char copyright[512];
     char comment[512];
+    int flags; /* format specific flags */
     /* This buffer is only needed when packets were already buffered but
        not decoded, for example to get the codec parameters in mpeg
        streams */
@@ -111,6 +112,7 @@ extern AVFormat *first_format;
 extern AVFormat rm_format;
 
 /* mpegmux.c */
+#define AVF_FLAG_VCD   0x00000001   /* VCD compatible MPEG-PS */
 extern AVFormat mpeg_mux_format;
 
 /* asfenc.c */
index 58ec253..91136e6 100644 (file)
@@ -47,6 +47,7 @@ typedef struct {
 
 #define PACK_START_CODE             ((unsigned int)0x000001ba)
 #define SYSTEM_HEADER_START_CODE    ((unsigned int)0x000001bb)
+#define SEQUENCE_END_CODE           ((unsigned int)0x000001b7)
 #define PACKET_START_CODE_MASK      ((unsigned int)0xffffff00)
 #define PACKET_START_CODE_PREFIX    ((unsigned int)0x00000100)
 #define ISO_11172_END_CODE          ((unsigned int)0x000001b9)
@@ -162,7 +163,11 @@ static int mpeg_mux_init(AVFormatContext *ctx)
     s->packet_number = 0;
 
     /* XXX: hardcoded */
-    s->packet_size = 2048;
+    if (ctx->flags & AVF_FLAG_VCD)
+        s->packet_size = 2324; /* VCD packet size */
+    else
+        s->packet_size = 2048;
+        
     /* startcode(4) + length(2) + flags(1) */
     s->packet_data_max_size = s->packet_size - 7;
     s->audio_bound = 0;
@@ -204,11 +209,22 @@ static int mpeg_mux_init(AVFormatContext *ctx)
         bitrate += st->codec.bit_rate;
     }
     s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);
-    /* every 2 seconds */
-    s->pack_header_freq = 2 * bitrate / s->packet_size / 8;
-    /* every 10 seconds */
-    s->system_header_freq = s->pack_header_freq * 5;
-
+    
+    if (ctx->flags & AVF_FLAG_VCD)
+        /* every packet */
+        s->pack_header_freq = 1;
+    else
+        /* every 2 seconds */
+        s->pack_header_freq = 2 * bitrate / s->packet_size / 8;
+    
+    if (ctx->flags & AVF_FLAG_VCD)
+        /* every 40 packets, this is my invention */
+        s->system_header_freq = s->pack_header_freq * 40;
+    else
+        /* every 10 seconds */
+        s->system_header_freq = s->pack_header_freq * 5;
+    
+    
     for(i=0;i<ctx->nb_streams;i++) {
         stream = ctx->streams[i]->priv_data;
         stream->buffer_ptr = 0;
@@ -242,7 +258,7 @@ static int mpeg_mux_init(AVFormatContext *ctx)
 }
 
 /* flush the packet on stream stream_index */
-static void flush_packet(AVFormatContext *ctx, int stream_index)
+static void flush_packet(AVFormatContext *ctx, int stream_index, int last_pkt)
 {
     MpegMuxContext *s = ctx->priv_data;
     StreamInfo *stream = ctx->streams[stream_index]->priv_data;
@@ -250,7 +266,8 @@ static void flush_packet(AVFormatContext *ctx, int stream_index)
     int size, payload_size, startcode, id, len, stuffing_size, i;
     INT64 timestamp;
     UINT8 buffer[128];
-
+    int last = last_pkt ? 4 : 0;
+    
     id = stream->id;
     timestamp = stream->start_pts;
 
@@ -260,7 +277,7 @@ static void flush_packet(AVFormatContext *ctx, int stream_index)
 #endif
 
     buf_ptr = buffer;
-    if ((s->packet_number % s->pack_header_freq) == 0) {
+    if (((s->packet_number % s->pack_header_freq) == 0)) {
         /* output pack and systems header if needed */
         size = put_pack_header(ctx, buf_ptr, timestamp);
         buf_ptr += size;
@@ -273,7 +290,7 @@ static void flush_packet(AVFormatContext *ctx, int stream_index)
     put_buffer(&ctx->pb, buffer, size);
 
     /* packet header */
-    payload_size = s->packet_size - (size + 6 + 5);
+    payload_size = s->packet_size - (size + 6 + 5 + last);
     if (id < 0xc0) {
         startcode = PRIVATE_STREAM_1;
         payload_size -= 4;
@@ -309,6 +326,9 @@ static void flush_packet(AVFormatContext *ctx, int stream_index)
         }
     }
 
+    if (last_pkt) {
+        put_be32(&ctx->pb, ISO_11172_END_CODE);
+    }
     /* output data */
     put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size);
     put_flush_packet(&ctx->pb);
@@ -351,7 +371,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
             /* output the packet */
             if (stream->start_pts == -1)
                 stream->start_pts = stream->pts;
-            flush_packet(ctx, stream_index);
+            flush_packet(ctx, stream_index, 0);
         }
     }
 
@@ -367,13 +387,17 @@ static int mpeg_mux_end(AVFormatContext *ctx)
     /* flush each packet */
     for(i=0;i<ctx->nb_streams;i++) {
         stream = ctx->streams[i]->priv_data;
-        if (stream->buffer_ptr > 0) 
-            flush_packet(ctx, i);
+        if (stream->buffer_ptr > 0) {
+            if (i == (ctx->nb_streams - 1)) 
+                flush_packet(ctx, i, 1);
+            else
+                flush_packet(ctx, i, 0);
+        }
     }
 
     /* write the end header */
-    put_be32(&ctx->pb, ISO_11172_END_CODE);
-    put_flush_packet(&ctx->pb);
+    //put_be32(&ctx->pb, ISO_11172_END_CODE);
+    //put_flush_packet(&ctx->pb);
     return 0;
 }