Merge commit 'e4c9e59a4547adaaa0ce9f25b0d0c5b91ae15472'

* commit 'e4c9e59a4547adaaa0ce9f25b0d0c5b91ae15472':
  mpeg: K&R formatting cosmetics

Conflicts:
	libavformat/mpegenc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer
2014-08-08 21:31:54 +02:00

View File

@@ -26,7 +26,9 @@
#include "libavutil/log.h" #include "libavutil/log.h"
#include "libavutil/mathematics.h" #include "libavutil/mathematics.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavcodec/put_bits.h" #include "libavcodec/put_bits.h"
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include "mpeg.h" #include "mpeg.h"
@@ -90,8 +92,8 @@ extern AVOutputFormat ff_mpeg2dvd_muxer;
extern AVOutputFormat ff_mpeg2svcd_muxer; extern AVOutputFormat ff_mpeg2svcd_muxer;
extern AVOutputFormat ff_mpeg2vob_muxer; extern AVOutputFormat ff_mpeg2vob_muxer;
static int put_pack_header(AVFormatContext *ctx, static int put_pack_header(AVFormatContext *ctx, uint8_t *buf,
uint8_t *buf, int64_t timestamp) int64_t timestamp)
{ {
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
PutBitContext pb; PutBitContext pb;
@@ -99,21 +101,19 @@ static int put_pack_header(AVFormatContext *ctx,
init_put_bits(&pb, buf, 128); init_put_bits(&pb, buf, 128);
put_bits32(&pb, PACK_START_CODE); put_bits32(&pb, PACK_START_CODE);
if (s->is_mpeg2) { if (s->is_mpeg2)
put_bits(&pb, 2, 0x1); put_bits(&pb, 2, 0x1);
} else { else
put_bits(&pb, 4, 0x2); put_bits(&pb, 4, 0x2);
}
put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07));
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff));
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff)); put_bits(&pb, 15, (uint32_t)((timestamp) & 0x7fff));
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
if (s->is_mpeg2) { if (s->is_mpeg2)
/* clock extension */ /* clock extension */
put_bits(&pb, 9, 0); put_bits(&pb, 9, 0);
}
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
put_bits(&pb, 22, s->mux_rate); put_bits(&pb, 22, s->mux_rate);
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
@@ -126,7 +126,8 @@ static int put_pack_header(AVFormatContext *ctx,
return put_bits_ptr(&pb) - pb.buf; return put_bits_ptr(&pb) - pb.buf;
} }
static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_stream_id) static int put_system_header(AVFormatContext *ctx, uint8_t *buf,
int only_for_stream_id)
{ {
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
int size, i, private_stream_coded, id; int size, i, private_stream_coded, id;
@@ -138,10 +139,12 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str
put_bits(&pb, 16, 0); put_bits(&pb, 16, 0);
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
put_bits(&pb, 22, s->mux_rate); /* maximum bit rate of the multiplexed stream */ /* maximum bit rate of the multiplexed stream */
put_bits(&pb, 22, s->mux_rate);
put_bits(&pb, 1, 1); /* marker */ put_bits(&pb, 1, 1); /* marker */
if (s->is_vcd && only_for_stream_id == VIDEO_ID) { if (s->is_vcd && only_for_stream_id == VIDEO_ID) {
/* This header applies only to the video stream (see VCD standard p. IV-7)*/ /* This header applies only to the video stream
* (see VCD standard p. IV-7) */
put_bits(&pb, 6, 0); put_bits(&pb, 6, 0);
} else } else
put_bits(&pb, 6, s->audio_bound); put_bits(&pb, 6, s->audio_bound);
@@ -167,7 +170,8 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str
put_bits(&pb, 1, 1); /* marker */ put_bits(&pb, 1, 1); /* marker */
if (s->is_vcd && (only_for_stream_id & 0xe0) == AUDIO_ID) { if (s->is_vcd && (only_for_stream_id & 0xe0) == AUDIO_ID) {
/* This header applies only to the audio stream (see VCD standard p. IV-7)*/ /* This header applies only to the audio stream
* (see VCD standard p. IV-7) */
put_bits(&pb, 5, 0); put_bits(&pb, 5, 0);
} else } else
put_bits(&pb, 5, s->video_bound); put_bits(&pb, 5, s->video_bound);
@@ -179,10 +183,10 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str
put_bits(&pb, 8, 0xff); /* reserved byte */ put_bits(&pb, 8, 0xff); /* reserved byte */
/* DVD-Video Stream_bound entries /* DVD-Video Stream_bound entries
id (0xB9) video, maximum P-STD for stream 0xE0. (P-STD_buffer_bound_scale = 1) * id (0xB9) video, maximum P-STD for stream 0xE0. (P-STD_buffer_bound_scale = 1)
id (0xB8) audio, maximum P-STD for any MPEG audio (0xC0 to 0xC7) streams. If there are none set to 4096 (32x128). (P-STD_buffer_bound_scale = 0) * id (0xB8) audio, maximum P-STD for any MPEG audio (0xC0 to 0xC7) streams. If there are none set to 4096 (32x128). (P-STD_buffer_bound_scale = 0)
id (0xBD) private stream 1 (audio other than MPEG and subpictures). (P-STD_buffer_bound_scale = 1) * id (0xBD) private stream 1 (audio other than MPEG and subpictures). (P-STD_buffer_bound_scale = 1)
id (0xBF) private stream 2, NAV packs, set to 2x1024. */ * id (0xBF) private stream 2, NAV packs, set to 2x1024. */
if (s->is_dvd) { if (s->is_dvd) {
int P_STD_max_video = 0; int P_STD_max_video = 0;
@@ -195,9 +199,11 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str
id = stream->id; id = stream->id;
if (id == 0xbd && stream->max_buffer_size > P_STD_max_mpeg_PS1) { if (id == 0xbd && stream->max_buffer_size > P_STD_max_mpeg_PS1) {
P_STD_max_mpeg_PS1 = stream->max_buffer_size; P_STD_max_mpeg_PS1 = stream->max_buffer_size;
} else if (id >= 0xc0 && id <= 0xc7 && stream->max_buffer_size > P_STD_max_mpeg_audio) { } else if (id >= 0xc0 && id <= 0xc7 &&
stream->max_buffer_size > P_STD_max_mpeg_audio) {
P_STD_max_mpeg_audio = stream->max_buffer_size; P_STD_max_mpeg_audio = stream->max_buffer_size;
} else if (id == 0xe0 && stream->max_buffer_size > P_STD_max_video) { } else if (id == 0xe0 &&
stream->max_buffer_size > P_STD_max_video) {
P_STD_max_video = stream->max_buffer_size; P_STD_max_video = stream->max_buffer_size;
} }
} }
@@ -227,20 +233,17 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str
put_bits(&pb, 2, 3); put_bits(&pb, 2, 3);
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
put_bits(&pb, 13, 2); put_bits(&pb, 13, 2);
} } else {
else {
/* audio stream info */ /* audio stream info */
private_stream_coded = 0; private_stream_coded = 0;
for (i = 0; i < ctx->nb_streams; i++) { for (i = 0; i < ctx->nb_streams; i++) {
StreamInfo *stream = ctx->streams[i]->priv_data; StreamInfo *stream = ctx->streams[i]->priv_data;
/* For VCDs, only include the stream info for the stream /* For VCDs, only include the stream info for the stream
that the pack which contains this system belongs to. * that the pack which contains this system belongs to.
(see VCD standard p. IV-7) */ * (see VCD standard p. IV-7) */
if ( !s->is_vcd || stream->id==only_for_stream_id if (!s->is_vcd || stream->id == only_for_stream_id ||
|| only_for_stream_id==0) { only_for_stream_id == 0) {
id = stream->id; id = stream->id;
if (id < 0xc0) { if (id < 0xc0) {
/* special case for private streams (AC-3 uses that) */ /* special case for private streams (AC-3 uses that) */
@@ -329,12 +332,14 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
s->audio_bound = 0; s->audio_bound = 0;
s->video_bound = 0; s->video_bound = 0;
mpa_id = AUDIO_ID; mpa_id = AUDIO_ID;
ac3_id = AC3_ID; ac3_id = AC3_ID;
dts_id = DTS_ID; dts_id = DTS_ID;
mpv_id = VIDEO_ID; mpv_id = VIDEO_ID;
mps_id = SUB_ID; mps_id = SUB_ID;
lpcm_id = LPCM_ID; lpcm_id = LPCM_ID;
for (i = 0; i < ctx->nb_streams; i++) { for (i = 0; i < ctx->nb_streams; i++) {
st = ctx->streams[i]; st = ctx->streams[i];
stream = av_mallocz(sizeof(StreamInfo)); stream = av_mallocz(sizeof(StreamInfo));
@@ -378,7 +383,7 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
} }
/* This value HAS to be used for VCD (see VCD standard, p. IV-7). /* This value HAS to be used for VCD (see VCD standard, p. IV-7).
Right now it is also used for everything else.*/ * Right now it is also used for everything else. */
stream->max_buffer_size = 4 * 1024; stream->max_buffer_size = 4 * 1024;
s->audio_bound++; s->audio_bound++;
break; break;
@@ -387,10 +392,12 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
if (st->codec->rc_buffer_size) if (st->codec->rc_buffer_size)
stream->max_buffer_size = 6 * 1024 + st->codec->rc_buffer_size / 8; stream->max_buffer_size = 6 * 1024 + st->codec->rc_buffer_size / 8;
else { else {
av_log(ctx, AV_LOG_WARNING, "VBV buffer size not set, using default size of 130KB\n" av_log(ctx, AV_LOG_WARNING,
"VBV buffer size not set, using default size of 130KB\n"
"If you want the mpeg file to be compliant to some specification\n" "If you want the mpeg file to be compliant to some specification\n"
"Like DVD, VCD or others, make sure you set the correct buffer size\n"); "Like DVD, VCD or others, make sure you set the correct buffer size\n");
stream->max_buffer_size = 230*1024; //FIXME this is probably too small as default // FIXME: this is probably too small as default
stream->max_buffer_size = 230 * 1024;
} }
if (stream->max_buffer_size > 1024 * 8191) { if (stream->max_buffer_size > 1024 * 8191) {
av_log(ctx, AV_LOG_WARNING, "buffer size %d, too large\n", stream->max_buffer_size); av_log(ctx, AV_LOG_WARNING, "buffer size %d, too large\n", stream->max_buffer_size);
@@ -437,7 +444,7 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
s->mux_rate = (s->user_mux_rate + (8 * 50) - 1) / (8 * 50); s->mux_rate = (s->user_mux_rate + (8 * 50) - 1) / (8 * 50);
} else { } else {
/* we increase slightly the bitrate to take into account the /* we increase slightly the bitrate to take into account the
headers. XXX: compute it exactly */ * headers. XXX: compute it exactly */
bitrate += bitrate / 20; bitrate += bitrate / 20;
bitrate += 10000; bitrate += 10000;
s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);
@@ -451,23 +458,23 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
double overhead_rate; double overhead_rate;
/* The VCD standard mandates that the mux_rate field is 3528 /* The VCD standard mandates that the mux_rate field is 3528
(see standard p. IV-6). * (see standard p. IV-6).
The value is actually "wrong", i.e. if you calculate * The value is actually "wrong", i.e. if you calculate
it using the normal formula and the 75 sectors per second transfer * it using the normal formula and the 75 sectors per second transfer
rate you get a different value because the real pack size is 2324, * rate you get a different value because the real pack size is 2324,
not 2352. But the standard explicitly specifies that the mux_rate * not 2352. But the standard explicitly specifies that the mux_rate
field in the header must have this value.*/ * field in the header must have this value. */
// s->mux_rate = 2352 * 75 / 50; /* = 3528 */ // s->mux_rate = 2352 * 75 / 50; /* = 3528 */
/* The VCD standard states that the muxed stream must be /* The VCD standard states that the muxed stream must be
exactly 75 packs / second (the data rate of a single speed cdrom). * exactly 75 packs / second (the data rate of a single speed cdrom).
Since the video bitrate (probably 1150000 bits/sec) will be below * Since the video bitrate (probably 1150000 bits/sec) will be below
the theoretical maximum we have to add some padding packets * the theoretical maximum we have to add some padding packets
to make up for the lower data rate. * to make up for the lower data rate.
(cf. VCD standard p. IV-6 )*/ * (cf. VCD standard p. IV-6 ) */
/* Add the header overhead to the data rate. /* Add the header overhead to the data rate.
2279 data bytes per audio pack, 2294 data bytes per video pack*/ * 2279 data bytes per audio pack, 2294 data bytes per video pack */
overhead_rate = ((audio_bitrate / 8.0) / 2279) * (2324 - 2279); overhead_rate = ((audio_bitrate / 8.0) / 2279) * (2324 - 2279);
overhead_rate += ((video_bitrate / 8.0) / 2294) * (2324 - 2294); overhead_rate += ((video_bitrate / 8.0) / 2294) * (2324 - 2294);
overhead_rate *= 8; overhead_rate *= 8;
@@ -492,8 +499,8 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
s->system_header_freq = s->pack_header_freq * 40; s->system_header_freq = s->pack_header_freq * 40;
else if (s->is_vcd) else if (s->is_vcd)
/* the standard mandates that there are only two system headers /* the standard mandates that there are only two system headers
in the whole file: one in the first packet of each stream. * in the whole file: one in the first packet of each stream.
(see standard p. IV-7 and IV-8) */ * (see standard p. IV-7 and IV-8) */
s->system_header_freq = 0x7fffffff; s->system_header_freq = 0x7fffffff;
else else
s->system_header_freq = s->pack_header_freq * 5; s->system_header_freq = s->pack_header_freq * 5;
@@ -505,50 +512,47 @@ static av_cold int mpeg_mux_init(AVFormatContext *ctx)
s->system_header_size = get_system_header_size(ctx); s->system_header_size = get_system_header_size(ctx);
s->last_scr = AV_NOPTS_VALUE; s->last_scr = AV_NOPTS_VALUE;
return 0; return 0;
fail: fail:
for(i=0;i<ctx->nb_streams;i++) { for (i = 0; i < ctx->nb_streams; i++)
av_free(ctx->streams[i]->priv_data); av_free(ctx->streams[i]->priv_data);
}
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
static inline void put_timestamp(AVIOContext *pb, int id, int64_t timestamp) static inline void put_timestamp(AVIOContext *pb, int id, int64_t timestamp)
{ {
avio_w8(pb, avio_w8(pb, (id << 4) | (((timestamp >> 30) & 0x07) << 1) | 1);
(id << 4) |
(((timestamp >> 30) & 0x07) << 1) |
1);
avio_wb16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); avio_wb16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1));
avio_wb16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1)); avio_wb16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1));
} }
/* return the number of padding bytes that should be inserted into /* return the number of padding bytes that should be inserted into
the multiplexed stream.*/ * the multiplexed stream. */
static int get_vcd_padding_size(AVFormatContext *ctx, int64_t pts) static int get_vcd_padding_size(AVFormatContext *ctx, int64_t pts)
{ {
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
int pad_bytes = 0; int pad_bytes = 0;
if (s->vcd_padding_bitrate > 0 && pts!=AV_NOPTS_VALUE) if (s->vcd_padding_bitrate > 0 && pts != AV_NOPTS_VALUE) {
{
int64_t full_pad_bytes; int64_t full_pad_bytes;
full_pad_bytes = (int64_t)((s->vcd_padding_bitrate * (pts / 90000.0)) / 8.0); //FIXME this is wrong // FIXME: this is wrong
full_pad_bytes =
(int64_t)((s->vcd_padding_bitrate * (pts / 90000.0)) / 8.0);
pad_bytes = (int)(full_pad_bytes - s->vcd_padding_bytes_written); pad_bytes = (int)(full_pad_bytes - s->vcd_padding_bytes_written);
if (pad_bytes < 0) if (pad_bytes < 0)
/* might happen if we have already padded to a later timestamp. This /* might happen if we have already padded to a later timestamp. This
can occur if another stream has already advanced further.*/ * can occur if another stream has already advanced further. */
pad_bytes = 0; pad_bytes = 0;
} }
return pad_bytes; return pad_bytes;
} }
/* Write an MPEG padding packet header. */ /* Write an MPEG padding packet header. */
static void put_padding_packet(AVFormatContext *ctx, AVIOContext *pb,int packet_bytes) static void put_padding_packet(AVFormatContext *ctx, AVIOContext *pb,
int packet_bytes)
{ {
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
int i; int i;
@@ -565,7 +569,8 @@ static void put_padding_packet(AVFormatContext *ctx, AVIOContext *pb,int packet_
avio_w8(pb, 0xff); avio_w8(pb, 0xff);
} }
static int get_nb_frames(AVFormatContext *ctx, StreamInfo *stream, int len){ static int get_nb_frames(AVFormatContext *ctx, StreamInfo *stream, int len)
{
int nb_frames = 0; int nb_frames = 0;
PacketDesc *pkt_desc = stream->premux_packet; PacketDesc *pkt_desc = stream->premux_packet;
@@ -592,7 +597,8 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
int zero_trail_bytes = 0; int zero_trail_bytes = 0;
int pad_packet_bytes = 0; int pad_packet_bytes = 0;
int pes_flags; int pes_flags;
int general_pack = 0; /*"general" pack without data specific to one stream?*/ /* "general" pack without data specific to one stream? */
int general_pack = 0;
int nb_frames; int nb_frames;
id = stream->id; id = stream->id;
@@ -609,8 +615,8 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
if (s->is_vcd) { if (s->is_vcd) {
/* there is exactly one system header for each stream in a VCD MPEG, /* there is exactly one system header for each stream in a VCD MPEG,
One in the very first video packet and one in the very first * One in the very first video packet and one in the very first
audio packet (see VCD standard p. IV-7 and IV-8).*/ * audio packet (see VCD standard p. IV-7 and IV-8). */
if (stream->packet_number == 0) { if (stream->packet_number == 0) {
size = put_system_header(ctx, buf_ptr, id); size = put_system_header(ctx, buf_ptr, id);
@@ -649,13 +655,16 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
buf_ptr = buffer; buf_ptr = buffer;
s->packet_number++; s->packet_number++;
stream->align_iframe = 0; stream->align_iframe = 0;
scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet // FIXME: rounding and first few bytes of each packet
scr += s->packet_size * 90000LL /
(s->mux_rate * 50LL);
size = put_pack_header(ctx, buf_ptr, scr); size = put_pack_header(ctx, buf_ptr, scr);
s->last_scr = scr; s->last_scr = scr;
buf_ptr += size; buf_ptr += size;
/* GOP Start */ /* GOP Start */
} else if (stream->bytes_to_iframe < PES_bytes_to_fill) { } else if (stream->bytes_to_iframe < PES_bytes_to_fill) {
pad_packet_bytes = PES_bytes_to_fill - stream->bytes_to_iframe; pad_packet_bytes = PES_bytes_to_fill -
stream->bytes_to_iframe;
} }
} }
} else { } else {
@@ -672,26 +681,26 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
if (s->is_vcd && (id & 0xe0) == AUDIO_ID) if (s->is_vcd && (id & 0xe0) == AUDIO_ID)
/* The VCD standard demands that 20 zero bytes follow /* The VCD standard demands that 20 zero bytes follow
each audio pack (see standard p. IV-8).*/ * each audio pack (see standard p. IV-8). */
zero_trail_bytes += 20; zero_trail_bytes += 20;
if ((s->is_vcd && stream->packet_number==0) if ((s->is_vcd && stream->packet_number == 0) ||
|| (s->is_svcd && s->packet_number==0)) { (s->is_svcd && s->packet_number == 0)) {
/* for VCD the first pack of each stream contains only the pack header, /* for VCD the first pack of each stream contains only the pack header,
the system header and lots of padding (see VCD standard p. IV-6). * the system header and lots of padding (see VCD standard p. IV-6).
In the case of an audio pack, 20 zero bytes are also added at * In the case of an audio pack, 20 zero bytes are also added at
the end.*/ * the end. */
/* For SVCD we fill the very first pack to increase compatibility with /* For SVCD we fill the very first pack to increase compatibility with
some DVD players. Not mandated by the standard.*/ * some DVD players. Not mandated by the standard. */
if (s->is_svcd) if (s->is_svcd)
general_pack = 1; /* the system header refers to both streams and no stream data*/ /* the system header refers to both streams and no stream data */
general_pack = 1;
pad_packet_bytes = packet_size - zero_trail_bytes; pad_packet_bytes = packet_size - zero_trail_bytes;
} }
packet_size -= pad_packet_bytes + zero_trail_bytes; packet_size -= pad_packet_bytes + zero_trail_bytes;
if (packet_size > 0) { if (packet_size > 0) {
/* packet header size */ /* packet header size */
packet_size -= 6; packet_size -= 6;
@@ -736,7 +745,8 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
timestamp_len += 5; timestamp_len += 5;
if (pts != AV_NOPTS_VALUE) if (pts != AV_NOPTS_VALUE)
timestamp_len += s->is_mpeg2 ? 5 : 4; timestamp_len += s->is_mpeg2 ? 5 : 4;
pts=dts= AV_NOPTS_VALUE; pts =
dts = AV_NOPTS_VALUE;
header_len -= timestamp_len; header_len -= timestamp_len;
if (s->is_dvd && stream->align_iframe) { if (s->is_dvd && stream->align_iframe) {
pad_packet_bytes += timestamp_len; pad_packet_bytes += timestamp_len;
@@ -749,14 +759,14 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
stuffing_size += payload_size - trailer_size; stuffing_size += payload_size - trailer_size;
} }
if (pad_packet_bytes > 0 && pad_packet_bytes <= 7) { // can't use padding, so use stuffing // can't use padding, so use stuffing
if (pad_packet_bytes > 0 && pad_packet_bytes <= 7) {
packet_size += pad_packet_bytes; packet_size += pad_packet_bytes;
payload_size += pad_packet_bytes; // undo the previous adjustment payload_size += pad_packet_bytes; // undo the previous adjustment
if (stuffing_size < 0) { if (stuffing_size < 0)
stuffing_size = pad_packet_bytes; stuffing_size = pad_packet_bytes;
} else { else
stuffing_size += pad_packet_bytes; stuffing_size += pad_packet_bytes;
}
pad_packet_bytes = 0; pad_packet_bytes = 0;
} }
@@ -797,9 +807,9 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
} }
/* Both the MPEG-2 and the SVCD standards demand that the /* Both the MPEG-2 and the SVCD standards demand that the
P-STD_buffer_size field be included in the first packet of * P-STD_buffer_size field be included in the first packet of
every stream. (see SVCD standard p. 26 V.2.3.1 and V.2.3.2 * every stream. (see SVCD standard p. 26 V.2.3.1 and V.2.3.2
and MPEG-2 standard 2.7.7) */ * and MPEG-2 standard 2.7.7) */
if (stream->packet_number == 0) if (stream->packet_number == 0)
pes_flags |= 0x01; pes_flags |= 0x01;
@@ -820,7 +830,6 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
else else
avio_wb16(ctx->pb, 0x6000 | stream->max_buffer_size / 1024); avio_wb16(ctx->pb, 0x6000 | stream->max_buffer_size / 1024);
} }
} else { } else {
if (pts != AV_NOPTS_VALUE) { if (pts != AV_NOPTS_VALUE) {
if (dts != pts) { if (dts != pts) {
@@ -836,7 +845,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
if (s->is_mpeg2) { if (s->is_mpeg2) {
/* special stuffing byte that is always written /* special stuffing byte that is always written
to prevent accidental generation of start codes. */ * to prevent accidental generation of start codes. */
avio_w8(ctx->pb, 0xff); avio_w8(ctx->pb, 0xff);
for (i = 0; i < stuffing_size; i++) for (i = 0; i < stuffing_size; i++)
@@ -861,7 +870,8 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
/* output data */ /* output data */
assert(payload_size - stuffing_size <= av_fifo_size(stream->fifo)); assert(payload_size - stuffing_size <= av_fifo_size(stream->fifo));
av_fifo_generic_read(stream->fifo, ctx->pb, payload_size - stuffing_size, (void*)avio_write); av_fifo_generic_read(stream->fifo, ctx->pb,
payload_size - stuffing_size, (void*)avio_write);
stream->bytes_to_iframe -= payload_size - stuffing_size; stream->bytes_to_iframe -= payload_size - stuffing_size;
} else { } else {
payload_size = payload_size =
@@ -879,8 +889,8 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
s->packet_number++; s->packet_number++;
/* only increase the stream packet number if this pack actually contains /* only increase the stream packet number if this pack actually contains
something that is specific to this stream! I.e. a dedicated header * something that is specific to this stream! I.e. a dedicated header
or some data.*/ * or some data. */
if (!general_pack) if (!general_pack)
stream->packet_number++; stream->packet_number++;
@@ -890,10 +900,10 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
static void put_vcd_padding_sector(AVFormatContext *ctx) static void put_vcd_padding_sector(AVFormatContext *ctx)
{ {
/* There are two ways to do this padding: writing a sector/pack /* There are two ways to do this padding: writing a sector/pack
of 0 values, or writing an MPEG padding pack. Both seem to * of 0 values, or writing an MPEG padding pack. Both seem to
work with most decoders, BUT the VCD standard only allows a 0-sector * work with most decoders, BUT the VCD standard only allows a 0-sector
(see standard p. IV-4, IV-5). * (see standard p. IV-4, IV-5).
So a 0-sector it is...*/ * So a 0-sector it is... */
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
int i; int i;
@@ -906,14 +916,14 @@ static void put_vcd_padding_sector(AVFormatContext *ctx)
avio_flush(ctx->pb); avio_flush(ctx->pb);
/* increasing the packet number is correct. The SCR of the following packs /* increasing the packet number is correct. The SCR of the following packs
is calculated from the packet_number and it has to include the padding * is calculated from the packet_number and it has to include the padding
sector (it represents the sector index, not the MPEG pack index) * sector (it represents the sector index, not the MPEG pack index)
(see VCD standard p. IV-6)*/ * (see VCD standard p. IV-6) */
s->packet_number++; s->packet_number++;
} }
static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr){ static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr)
// MpegMuxContext *s = ctx->priv_data; {
int i; int i;
for (i = 0; i < ctx->nb_streams; i++) { for (i = 0; i < ctx->nb_streams; i++) {
@@ -921,8 +931,8 @@ static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr){
StreamInfo *stream = st->priv_data; StreamInfo *stream = st->priv_data;
PacketDesc *pkt_desc; PacketDesc *pkt_desc;
while((pkt_desc= stream->predecode_packet) while ((pkt_desc = stream->predecode_packet) &&
&& scr > pkt_desc->dts){ //FIXME > vs >= scr > pkt_desc->dts) { // FIXME: > vs >=
if (stream->buffer_index < pkt_desc->size || if (stream->buffer_index < pkt_desc->size ||
stream->predecode_packet == stream->premux_packet) { stream->predecode_packet == stream->premux_packet) {
av_log(ctx, AV_LOG_ERROR, av_log(ctx, AV_LOG_ERROR,
@@ -931,7 +941,6 @@ static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr){
break; break;
} }
stream->buffer_index -= pkt_desc->size; stream->buffer_index -= pkt_desc->size;
stream->predecode_packet = pkt_desc->next; stream->predecode_packet = pkt_desc->next;
av_freep(&pkt_desc); av_freep(&pkt_desc);
} }
@@ -940,7 +949,8 @@ static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr){
return 0; return 0;
} }
static int output_packet(AVFormatContext *ctx, int flush){ static int output_packet(AVFormatContext *ctx, int flush)
{
MpegMuxContext *s = ctx->priv_data; MpegMuxContext *s = ctx->priv_data;
AVStream *st; AVStream *st;
StreamInfo *stream; StreamInfo *stream;
@@ -962,7 +972,7 @@ retry:
PacketDesc *next_pkt = stream->premux_packet; PacketDesc *next_pkt = stream->premux_packet;
/* for subtitle, a single PES packet must be generated, /* for subtitle, a single PES packet must be generated,
so we flush after every single subtitle packet */ * so we flush after every single subtitle packet */
if (s->packet_size > avail_data && !flush if (s->packet_size > avail_data && !flush
&& st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) && st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
return 0; return 0;
@@ -1002,7 +1012,8 @@ retry:
return 0; return 0;
if (scr >= best_dts + 1 && !ignore_constraints) { if (scr >= best_dts + 1 && !ignore_constraints) {
av_log(ctx, AV_LOG_ERROR, "packet too large, ignoring buffer limits to mux it\n"); av_log(ctx, AV_LOG_ERROR,
"packet too large, ignoring buffer limits to mux it\n");
ignore_constraints = 1; ignore_constraints = 1;
} }
scr = FFMAX(best_dts + 1, scr); scr = FFMAX(best_dts + 1, scr);
@@ -1033,27 +1044,33 @@ retry:
timestamp_packet->dts / 90000.0, timestamp_packet->dts / 90000.0,
timestamp_packet->pts / 90000.0, timestamp_packet->pts / 90000.0,
scr / 90000.0, best_i); scr / 90000.0, best_i);
es_size= flush_packet(ctx, best_i, timestamp_packet->pts, timestamp_packet->dts, scr, trailer_size); es_size = flush_packet(ctx, best_i, timestamp_packet->pts,
timestamp_packet->dts, scr, trailer_size);
} else { } else {
assert(av_fifo_size(stream->fifo) == trailer_size); assert(av_fifo_size(stream->fifo) == trailer_size);
es_size= flush_packet(ctx, best_i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, scr, trailer_size); es_size = flush_packet(ctx, best_i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, scr,
trailer_size);
} }
if (s->is_vcd) { if (s->is_vcd) {
/* Write one or more padding sectors, if necessary, to reach /* Write one or more padding sectors, if necessary, to reach
the constant overall bitrate.*/ * the constant overall bitrate. */
int vcd_pad_bytes; int vcd_pad_bytes;
while((vcd_pad_bytes = get_vcd_padding_size(ctx,stream->premux_packet->pts) ) >= s->packet_size){ //FIXME pts cannot be correct here // FIXME: pts cannot be correct here
while ((vcd_pad_bytes = get_vcd_padding_size(ctx, stream->premux_packet->pts)) >= s->packet_size) {
put_vcd_padding_sector(ctx); put_vcd_padding_sector(ctx);
s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet // FIXME: rounding and first few bytes of each packet
s->last_scr += s->packet_size * 90000LL / (s->mux_rate * 50LL);
} }
} }
stream->buffer_index += es_size; stream->buffer_index += es_size;
s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet // FIXME: rounding and first few bytes of each packet
s->last_scr += s->packet_size * 90000LL / (s->mux_rate * 50LL);
while(stream->premux_packet && stream->premux_packet->unwritten_size <= es_size){ while (stream->premux_packet &&
stream->premux_packet->unwritten_size <= es_size) {
es_size -= stream->premux_packet->unwritten_size; es_size -= stream->premux_packet->unwritten_size;
stream->premux_packet = stream->premux_packet->next; stream->premux_packet = stream->premux_packet->next;
} }
@@ -1068,16 +1085,17 @@ retry:
static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
{ {
MpegMuxContext *s = ctx->priv_data;
int stream_index = pkt->stream_index; int stream_index = pkt->stream_index;
int size = pkt->size; int size = pkt->size;
uint8_t *buf = pkt->data; uint8_t *buf = pkt->data;
MpegMuxContext *s = ctx->priv_data;
AVStream *st = ctx->streams[stream_index]; AVStream *st = ctx->streams[stream_index];
StreamInfo *stream = st->priv_data; StreamInfo *stream = st->priv_data;
int64_t pts, dts; int64_t pts, dts;
PacketDesc *pkt_desc; PacketDesc *pkt_desc;
int preload; int preload;
const int is_iframe = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY); const int is_iframe = st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
(pkt->flags & AV_PKT_FLAG_KEY);
preload = av_rescale(s->preload, 90000, AV_TIME_BASE); preload = av_rescale(s->preload, 90000, AV_TIME_BASE);
@@ -1119,7 +1137,10 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
return -1; return -1;
if (s->is_dvd) { if (s->is_dvd) {
if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder) // min VOBU length 0.4 seconds (mpucoder)
if (is_iframe &&
(s->packet_number == 0 ||
(pts - stream->vobu_start_pts >= 36000))) {
stream->bytes_to_iframe = av_fifo_size(stream->fifo); stream->bytes_to_iframe = av_fifo_size(stream->fifo);
stream->align_iframe = 1; stream->align_iframe = 1;
stream->vobu_start_pts = pts; stream->vobu_start_pts = pts;
@@ -1137,7 +1158,6 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
static int mpeg_mux_end(AVFormatContext *ctx) static int mpeg_mux_end(AVFormatContext *ctx)
{ {
// MpegMuxContext *s = ctx->priv_data;
StreamInfo *stream; StreamInfo *stream;
int i; int i;
@@ -1150,8 +1170,8 @@ static int mpeg_mux_end(AVFormatContext *ctx)
} }
/* End header according to MPEG1 systems standard. We do not write /* End header according to MPEG1 systems standard. We do not write
it as it is usually not needed by decoders and because it * it as it is usually not needed by decoders and because it
complicates MPEG stream concatenation. */ * complicates MPEG stream concatenation. */
// avio_wb32(ctx->pb, ISO_11172_END_CODE); // avio_wb32(ctx->pb, ISO_11172_END_CODE);
// avio_flush(ctx->pb); // avio_flush(ctx->pb);
@@ -1196,6 +1216,7 @@ AVOutputFormat ff_mpeg1system_muxer = {
.priv_class = &mpeg_class, .priv_class = &mpeg_class,
}; };
#endif #endif
#if CONFIG_MPEG1VCD_MUXER #if CONFIG_MPEG1VCD_MUXER
MPEGENC_CLASS(vcd) MPEGENC_CLASS(vcd)
AVOutputFormat ff_mpeg1vcd_muxer = { AVOutputFormat ff_mpeg1vcd_muxer = {
@@ -1211,6 +1232,7 @@ AVOutputFormat ff_mpeg1vcd_muxer = {
.priv_class = &vcd_class, .priv_class = &vcd_class,
}; };
#endif #endif
#if CONFIG_MPEG2VOB_MUXER #if CONFIG_MPEG2VOB_MUXER
MPEGENC_CLASS(vob) MPEGENC_CLASS(vob)
AVOutputFormat ff_mpeg2vob_muxer = { AVOutputFormat ff_mpeg2vob_muxer = {