s->packet_size = ctx->packet_size;
} else
s->packet_size = 2048;
- if (ctx->max_delay < 0) /* Not set by the caller */
+ if (ctx->max_delay < 0) /* Not set by the caller */
- ctx->max_delay = 0;
+ ctx->max_delay = 0.7*AV_TIME_BASE;
s->vcd_padding_bytes_written = 0;
- s->vcd_padding_bitrate=0;
+ s->vcd_padding_bitrate = 0;
s->audio_bound = 0;
s->video_bound = 0;
avpriv_set_pts_info(st, 64, 1, 90000);
- switch(st->codec->codec_type) {
+ switch (st->codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- if (st->codec->codec_id == AV_CODEC_ID_AC3) {
+ if (!s->is_mpeg2 &&
+ (st->codec->codec_id == AV_CODEC_ID_AC3 ||
+ st->codec->codec_id == AV_CODEC_ID_DTS ||
+ st->codec->codec_id == AV_CODEC_ID_PCM_S16BE))
+ av_log(ctx, AV_LOG_WARNING,
+ "%s in MPEG-1 system streams is not widely supported, "
+ "consider using the vob or the dvd muxer "
+ "to force a MPEG-2 program stream.\n",
+ avcodec_get_name(st->codec->codec_id));
+ if (st->codec->codec_id == AV_CODEC_ID_AC3) {
stream->id = ac3_id++;
} else if (st->codec->codec_id == AV_CODEC_ID_DTS) {
stream->id = dts_id++;
case AVMEDIA_TYPE_VIDEO:
stream->id = mpv_id++;
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 {
- 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"
- "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
+ av_log(ctx, AV_LOG_WARNING,
- "VBV buffer size not set, muxing may fail\n");
++ "VBV buffer size not set, using default size of 130KB\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");
+ // FIXME: this is probably too small as default
+ stream->max_buffer_size = 230 * 1024;
}
+ if (stream->max_buffer_size > 1024 * 8191) {
+ av_log(ctx, AV_LOG_WARNING, "buffer size %d, too large\n", stream->max_buffer_size);
+ stream->max_buffer_size = 1024 * 8191;
+ }
s->video_bound++;
break;
case AVMEDIA_TYPE_SUBTITLE:
video_bitrate += codec_rate;
}
- if (!s->mux_rate) {
+ if (s->user_mux_rate) {
+ s->mux_rate = (s->user_mux_rate + (8 * 50) - 1) / (8 * 50);
+ } else {
/* we increase slightly the bitrate to take into account the
- headers. XXX: compute it exactly */
- bitrate += bitrate / 20;
- bitrate += 10000;
+ * headers. XXX: compute it exactly */
+ bitrate += bitrate / 20;
+ bitrate += 10000;
s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50);
+ if (s->mux_rate >= (1<<22)) {
+ av_log(ctx, AV_LOG_WARNING, "mux rate %d is too large\n", s->mux_rate);
+ s->mux_rate = (1<<22) - 1;
+ }
}
if (s->is_vcd) {
stream->packet_number = 0;
}
s->system_header_size = get_system_header_size(ctx);
- s->last_scr = AV_NOPTS_VALUE;
- s->last_scr = 0;
++ s->last_scr = AV_NOPTS_VALUE;
return 0;
- fail:
- for(i=0;i<ctx->nb_streams;i++) {
+
+ fail:
+ for (i = 0; i < ctx->nb_streams; i++)
av_free(ctx->streams[i]->priv_data);
- }
return AVERROR(ENOMEM);
}
/* output data */
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, &avio_write);
++ payload_size - stuffing_size, (void*)avio_write);
stream->bytes_to_iframe -= payload_size - stuffing_size;
- }else{
- payload_size=
- stuffing_size= 0;
+ } else {
+ payload_size =
+ stuffing_size = 0;
}
if (pad_packet_bytes > 0)
StreamInfo *stream = st->priv_data;
PacketDesc *pkt_desc;
- while((pkt_desc= stream->predecode_packet)
- && scr > pkt_desc->dts){ //FIXME > vs >=
- if(stream->buffer_index < pkt_desc->size ||
- stream->predecode_packet == stream->premux_packet){
+ while ((pkt_desc = stream->predecode_packet) &&
+ scr > pkt_desc->dts) { // FIXME: > vs >=
+ if (stream->buffer_index < pkt_desc->size ||
+ stream->predecode_packet == stream->premux_packet) {
av_log(ctx, AV_LOG_ERROR,
- "buffer underflow i=%d bufi=%d size=%d\n",
+ "buffer underflow st=%d bufi=%d size=%d\n",
i, stream->buffer_index, pkt_desc->size);
break;
}
MpegMuxContext *s = ctx->priv_data;
AVStream *st;
StreamInfo *stream;
- int i, avail_space=0, es_size, trailer_size;
- int best_i= -1;
- int best_score= INT_MIN;
- int ignore_constraints=0;
- int64_t scr= s->last_scr;
+ int i, avail_space = 0, es_size, trailer_size;
+ int best_i = -1;
+ int best_score = INT_MIN;
+ int ignore_constraints = 0;
+ int64_t scr = s->last_scr;
PacketDesc *timestamp_packet;
- const int64_t max_delay= av_rescale(ctx->max_delay, 90000, AV_TIME_BASE);
+ const int64_t max_delay = av_rescale(ctx->max_delay, 90000, AV_TIME_BASE);
retry:
- for(i=0; i<ctx->nb_streams; i++){
+ for (i = 0; i < ctx->nb_streams; i++) {
AVStream *st = ctx->streams[i];
StreamInfo *stream = st->priv_data;
- const int avail_data= av_fifo_size(stream->fifo);
- const int space= stream->max_buffer_size - stream->buffer_index;
- int rel_space= 1024LL*space / stream->max_buffer_size;
- PacketDesc *next_pkt= stream->premux_packet;
+ const int avail_data = av_fifo_size(stream->fifo);
+ const int space = stream->max_buffer_size - stream->buffer_index;
- int rel_space = 1024 * space / stream->max_buffer_size;
++ int rel_space = 1024LL * space / stream->max_buffer_size;
+ PacketDesc *next_pkt = stream->premux_packet;
/* for subtitle, a single PES packet must be generated,
- so we flush after every single subtitle packet */
- if(s->packet_size > avail_data && !flush
- && st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
+ * so we flush after every single subtitle packet */
+ if (s->packet_size > avail_data && !flush
+ && st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
return 0;
- if(avail_data==0)
+ if (avail_data == 0)
continue;
- av_assert0(avail_data>0);
- assert(avail_data > 0);
++ av_assert0(avail_data > 0);
- if(space < s->packet_size && !ignore_constraints)
+ if (space < s->packet_size && !ignore_constraints)
continue;
- if(next_pkt && next_pkt->dts - scr > max_delay)
+ if (next_pkt && next_pkt->dts - scr > max_delay)
continue;
-
+ if ( stream->predecode_packet
+ && stream->predecode_packet->size > stream->buffer_index)
+ rel_space += 1<<28;
- if(rel_space > best_score){
- best_score= rel_space;
- best_i = i;
- avail_space= space;
+ if (rel_space > best_score) {
+ best_score = rel_space;
+ best_i = i;
+ avail_space = space;
}
}
preload = av_rescale(s->preload, 90000, AV_TIME_BASE);
- pts= pkt->pts;
- dts= pkt->dts;
+ pts = pkt->pts;
+ dts = pkt->dts;
- if (pts != AV_NOPTS_VALUE)
- pts += 2 * preload;
- if (dts != AV_NOPTS_VALUE) {
- if (!s->last_scr)
- s->last_scr = dts + preload;
- dts += 2 * preload;
+ if (s->last_scr == AV_NOPTS_VALUE) {
+ if (dts == AV_NOPTS_VALUE || (dts < preload && ctx->avoid_negative_ts) || s->is_dvd) {
+ if (dts != AV_NOPTS_VALUE)
+ s->preload += av_rescale(-dts, AV_TIME_BASE, 90000);
+ s->last_scr = 0;
+ } else {
+ s->last_scr = dts - preload;
+ s->preload = 0;
+ }
+ preload = av_rescale(s->preload, 90000, AV_TIME_BASE);
+ av_log(ctx, AV_LOG_DEBUG, "First SCR: %"PRId64" First DTS: %"PRId64"\n", s->last_scr, dts + preload);
}
+ if (dts != AV_NOPTS_VALUE) dts += preload;
+ if (pts != AV_NOPTS_VALUE) pts += preload;
+
av_dlog(ctx, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n",
dts / 90000.0, pts / 90000.0, pkt->flags,
pkt->stream_index, pts != AV_NOPTS_VALUE);
#define OFFSET(x) offsetof(MpegMuxContext, x)
#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "muxrate", NULL, OFFSET(user_mux_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, ((1<<22) - 1) * (8 * 50), E },
- { "preload", "Initial demux-decode delay in microseconds.", OFFSET(preload), AV_OPT_TYPE_INT, {.i64 = 500000}, 0, INT_MAX, E},
- { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
++ { "muxrate", NULL, OFFSET(user_mux_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, ((1<<22) - 1) * (8 * 50), E },
+ { "preload", "Initial demux-decode delay in microseconds.", OFFSET(preload), AV_OPT_TYPE_INT, { .i64 = 500000 }, 0, INT_MAX, E },
{ NULL },
};