forked from FFmpeg/FFmpeg
- 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:
parent
79b0d5f925
commit
92b3e12592
2 changed files with 42 additions and 16 deletions
|
@ -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 */
|
||||
|
|
54
libav/mpeg.c
54
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;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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue