better framework for specific mpeg mux options such as vcd - added (incomplete) mpeg2 vob muxer for dvd creation

Originally committed as revision 1042 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Fabrice Bellard 2002-10-15 10:22:23 +00:00
parent 8351471307
commit fb7566d082
1 changed files with 59 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/* /*
* MPEG1 mux/demux * MPEG1/2 mux/demux
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard. * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -43,6 +43,8 @@ typedef struct {
/* stream info */ /* stream info */
int audio_bound; int audio_bound;
int video_bound; int video_bound;
int is_mpeg2;
int is_vcd;
} MpegMuxContext; } MpegMuxContext;
#define PACK_START_CODE ((unsigned int)0x000001ba) #define PACK_START_CODE ((unsigned int)0x000001ba)
@ -62,6 +64,10 @@ typedef struct {
#define AUDIO_ID 0xc0 #define AUDIO_ID 0xc0
#define VIDEO_ID 0xe0 #define VIDEO_ID 0xe0
extern AVOutputFormat mpeg1system_mux;
extern AVOutputFormat mpeg1vcd_mux;
extern AVOutputFormat mpeg2vob_mux;
static int put_pack_header(AVFormatContext *ctx, static int put_pack_header(AVFormatContext *ctx,
UINT8 *buf, INT64 timestamp) UINT8 *buf, INT64 timestamp)
{ {
@ -154,9 +160,10 @@ static int mpeg_mux_init(AVFormatContext *ctx)
StreamInfo *stream; StreamInfo *stream;
s->packet_number = 0; s->packet_number = 0;
s->is_vcd = (ctx->oformat == &mpeg1vcd_mux);
s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux);
/* XXX: hardcoded */ if (s->is_vcd)
if (ctx->flags & AVF_FLAG_VCD)
s->packet_size = 2324; /* VCD packet size */ s->packet_size = 2324; /* VCD packet size */
else else
s->packet_size = 2048; s->packet_size = 2048;
@ -203,14 +210,14 @@ static int mpeg_mux_init(AVFormatContext *ctx)
} }
s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);
if (ctx->flags & AVF_FLAG_VCD) if (s->is_vcd || s->is_mpeg2)
/* every packet */ /* every packet */
s->pack_header_freq = 1; s->pack_header_freq = 1;
else else
/* every 2 seconds */ /* every 2 seconds */
s->pack_header_freq = 2 * bitrate / s->packet_size / 8; s->pack_header_freq = 2 * bitrate / s->packet_size / 8;
if (ctx->flags & AVF_FLAG_VCD) if (s->is_vcd)
/* every 40 packets, this is my invention */ /* every 40 packets, this is my invention */
s->system_header_freq = s->pack_header_freq * 40; s->system_header_freq = s->pack_header_freq * 40;
else else
@ -255,7 +262,7 @@ static void flush_packet(AVFormatContext *ctx, int stream_index, int last_pkt)
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
StreamInfo *stream = ctx->streams[stream_index]->priv_data; StreamInfo *stream = ctx->streams[stream_index]->priv_data;
UINT8 *buf_ptr; UINT8 *buf_ptr;
int size, payload_size, startcode, id, len, stuffing_size, i; int size, payload_size, startcode, id, len, stuffing_size, i, header_len;
INT64 timestamp; INT64 timestamp;
UINT8 buffer[128]; UINT8 buffer[128];
int last = last_pkt ? 4 : 0; int last = last_pkt ? 4 : 0;
@ -282,7 +289,12 @@ static void flush_packet(AVFormatContext *ctx, int stream_index, int last_pkt)
put_buffer(&ctx->pb, buffer, size); put_buffer(&ctx->pb, buffer, size);
/* packet header */ /* packet header */
payload_size = s->packet_size - (size + 6 + 5 + last); if (s->is_mpeg2) {
header_len = 8;
} else {
header_len = 5;
}
payload_size = s->packet_size - (size + 6 + header_len + last);
if (id < 0xc0) { if (id < 0xc0) {
startcode = PRIVATE_STREAM_1; startcode = PRIVATE_STREAM_1;
payload_size -= 4; payload_size -= 4;
@ -295,12 +307,16 @@ static void flush_packet(AVFormatContext *ctx, int stream_index, int last_pkt)
put_be32(&ctx->pb, startcode); put_be32(&ctx->pb, startcode);
put_be16(&ctx->pb, payload_size + 5); put_be16(&ctx->pb, payload_size + header_len);
/* stuffing */ /* stuffing */
for(i=0;i<stuffing_size;i++) for(i=0;i<stuffing_size;i++)
put_byte(&ctx->pb, 0xff); put_byte(&ctx->pb, 0xff);
/* presentation time stamp */ if (s->is_mpeg2) {
put_byte(&ctx->pb, 0x80); /* mpeg2 id */
put_byte(&ctx->pb, 0x80); /* flags */
put_byte(&ctx->pb, 0x05); /* header len (only pts is included) */
}
put_byte(&ctx->pb, put_byte(&ctx->pb,
(0x02 << 4) | (0x02 << 4) |
(((timestamp >> 30) & 0x07) << 1) | (((timestamp >> 30) & 0x07) << 1) |
@ -626,11 +642,37 @@ static int mpegps_read_close(AVFormatContext *s)
return 0; return 0;
} }
static AVOutputFormat mpegps_mux = { static AVOutputFormat mpeg1system_mux = {
"mpeg", "mpeg",
"MPEG PS format", "MPEG1 System format",
"video/x-mpeg", "video/x-mpeg",
"mpg,mpeg,vob", "mpg,mpeg",
sizeof(MpegMuxContext),
CODEC_ID_MP2,
CODEC_ID_MPEG1VIDEO,
mpeg_mux_init,
mpeg_mux_write_packet,
mpeg_mux_end,
};
static AVOutputFormat mpeg1vcd_mux = {
"vcd",
"MPEG1 System format (VCD)",
"video/x-mpeg",
NULL,
sizeof(MpegMuxContext),
CODEC_ID_MP2,
CODEC_ID_MPEG1VIDEO,
mpeg_mux_init,
mpeg_mux_write_packet,
mpeg_mux_end,
};
static AVOutputFormat mpeg2vob_mux = {
"vob",
"MPEG2 PS format (VOB)",
"video/x-mpeg",
"vob",
sizeof(MpegMuxContext), sizeof(MpegMuxContext),
CODEC_ID_MP2, CODEC_ID_MP2,
CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG1VIDEO,
@ -652,7 +694,9 @@ static AVInputFormat mpegps_demux = {
int mpegps_init(void) int mpegps_init(void)
{ {
av_register_output_format(&mpegps_mux); av_register_output_format(&mpeg1system_mux);
av_register_output_format(&mpeg1vcd_mux);
av_register_output_format(&mpeg2vob_mux);
av_register_input_format(&mpegps_demux); av_register_input_format(&mpegps_demux);
return 0; return 0;
} }