- VCD MPEG-1 compliant stream support (set AVF_FLAG_VCD)

Originally committed as revision 491 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Juanjo 2002-05-12 21:38:54 +00:00
parent 79b0d5f925
commit 92b3e12592
2 changed files with 42 additions and 16 deletions

View 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 */

View 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;
}