diff --git a/libav/avformat.h b/libav/avformat.h index 10de1f8c2c..3b20a2d335 100644 --- a/libav/avformat.h +++ b/libav/avformat.h @@ -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 */ diff --git a/libav/mpeg.c b/libav/mpeg.c index 58ec253d68..91136e6091 100644 --- a/libav/mpeg.c +++ b/libav/mpeg.c @@ -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;inb_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;inb_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; }