#include <errno.h>
#include <limits.h>
#if HAVE_ISATTY
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#if HAVE_UNISTD_H
#include <unistd.h>
#endif
+#endif
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
av_buffersrc_add_ref(ist->filters[i]->filter,
avfilter_ref_buffer(ref, ~0),
AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT |
- AV_BUFFERSRC_FLAG_NO_COPY);
+ AV_BUFFERSRC_FLAG_NO_COPY |
+ AV_BUFFERSRC_FLAG_PUSH);
}
-static void sub2video_update(InputStream *ist, AVSubtitle *sub, int64_t pts)
+static void sub2video_update(InputStream *ist, AVSubtitle *sub)
{
int w = ist->sub2video.w, h = ist->sub2video.h;
AVFilterBufferRef *ref = ist->sub2video.ref;
int8_t *dst;
int dst_linesize;
int i;
+ int64_t pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ist->st->time_base);
if (!ref)
return;
av_freep(&output_streams[i]->forced_keyframes);
av_freep(&output_streams[i]->avfilter);
+ av_freep(&output_streams[i]->logfile_prefix);
av_freep(&output_streams[i]->filtered_frame);
av_freep(&output_streams[i]);
}
int64_t max = ost->st->cur_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
if (ost->st->cur_dts && ost->st->cur_dts != AV_NOPTS_VALUE && max > pkt->dts) {
av_log(s, max - pkt->dts > 2 || avctx->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG,
- "st:%d PTS: %"PRId64" DTS: %"PRId64" < %"PRId64" invalid, cliping\n", pkt->stream_index, pkt->pts, pkt->dts, max);
+ "st:%d PTS: %"PRId64" DTS: %"PRId64" < %"PRId64" invalid, clipping\n", pkt->stream_index, pkt->pts, pkt->dts, max);
if(pkt->pts >= pkt->dts)
pkt->pts = FFMAX(pkt->pts, max);
pkt->dts = max;
}
}
+static void close_output_stream(OutputStream *ost)
+{
+ OutputFile *of = output_files[ost->file_index];
+
+ ost->finished = 1;
+ if (of->shortest) {
+ int i;
+ for (i = 0; i < of->ctx->nb_streams; i++)
+ output_streams[of->ost_index + i]->finished = 1;
+ }
+}
+
static int check_recording_time(OutputStream *ost)
{
OutputFile *of = output_files[ost->file_index];
if (of->recording_time != INT64_MAX &&
av_compare_ts(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, of->recording_time,
AV_TIME_BASE_Q) >= 0) {
- ost->finished = 1;
+ close_output_stream(ost);
return 0;
}
return 1;
av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
}
+ audio_size += pkt.size;
write_frame(s, &pkt, ost);
- audio_size += pkt.size;
av_free_packet(&pkt);
}
}
static void do_subtitle_out(AVFormatContext *s,
OutputStream *ost,
InputStream *ist,
- AVSubtitle *sub,
- int64_t pts)
+ AVSubtitle *sub)
{
int subtitle_out_max_size = 1024 * 1024;
int subtitle_out_size, nb, i;
AVCodecContext *enc;
AVPacket pkt;
+ int64_t pts;
- if (pts == AV_NOPTS_VALUE) {
+ if (sub->pts == AV_NOPTS_VALUE) {
av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
if (exit_on_error)
exit_program(1);
nb = 1;
/* shift timestamp to honor -ss and make check_recording_time() work with -t */
- pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q)
- - output_files[ost->file_index]->start_time;
+ pts = sub->pts - output_files[ost->file_index]->start_time;
for (i = 0; i < nb; i++) {
ost->sync_opts = av_rescale_q(pts, AV_TIME_BASE_Q, enc->time_base);
if (!check_recording_time(ost))
else
pkt.pts += 90 * sub->end_display_time;
}
- write_frame(s, &pkt, ost);
subtitle_size += pkt.size;
+ write_frame(s, &pkt, ost);
}
}
pkt.pts = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base);
pkt.flags |= AV_PKT_FLAG_KEY;
- write_frame(s, &pkt, ost);
video_size += pkt.size;
+ write_frame(s, &pkt, ost);
} else {
int got_packet;
AVFrame big_picture;
av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
}
- write_frame(s, &pkt, ost);
frame_size = pkt.size;
video_size += pkt.size;
+ write_frame(s, &pkt, ost);
av_free_packet(&pkt);
/* if two pass, output log */
AVCodecContext *enc;
int frame_number, vid, i;
double bitrate;
- int64_t pts = INT64_MAX;
+ int64_t pts = INT64_MIN;
static int64_t last_time = -1;
static int qp_histogram[52];
int hours, mins, secs, us;
vid = 1;
}
/* compute min output value */
- pts = FFMIN(pts, av_rescale_q(ost->st->pts.val,
- ost->st->time_base, AV_TIME_BASE_Q));
+ if ((is_last_report || !ost->finished) && ost->st->pts.val != AV_NOPTS_VALUE)
+ pts = FFMAX(pts, av_rescale_q(ost->st->pts.val,
+ ost->st->time_base, AV_TIME_BASE_Q));
}
secs = pts / AV_TIME_BASE;
if (of->recording_time != INT64_MAX &&
ist->pts >= of->recording_time + of->start_time) {
- ost->finished = 1;
+ close_output_stream(ost);
return;
}
if (!*got_output || ret < 0) {
if (!pkt->size) {
for (i = 0; i < ist->nb_filters; i++)
- av_buffersrc_add_ref(ist->filters[i]->filter, NULL,
- AV_BUFFERSRC_FLAG_NO_COPY);
+ av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
}
return ret;
}
decoded_frame_tb,
(AVRational){1, ist->st->codec->sample_rate});
for (i = 0; i < ist->nb_filters; i++)
- av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame, 0);
+ av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame,
+ AV_BUFFERSRC_FLAG_PUSH);
decoded_frame->pts = AV_NOPTS_VALUE;
if (!*got_output || ret < 0) {
if (!pkt->size) {
for (i = 0; i < ist->nb_filters; i++)
- av_buffersrc_add_ref(ist->filters[i]->filter, NULL, AV_BUFFERSRC_FLAG_NO_COPY);
+ av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
}
return ret;
}
buf->refcount++;
av_buffersrc_add_ref(ist->filters[i]->filter, fb,
AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT |
- AV_BUFFERSRC_FLAG_NO_COPY);
+ AV_BUFFERSRC_FLAG_NO_COPY |
+ AV_BUFFERSRC_FLAG_PUSH);
} else
- if(av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame, 0)<0) {
+ if(av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame, AV_BUFFERSRC_FLAG_PUSH)<0) {
av_log(NULL, AV_LOG_FATAL, "Failed to inject frame into filter network\n");
exit_program(1);
}
static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
{
AVSubtitle subtitle;
- int64_t pts = pkt->pts;
int i, ret = avcodec_decode_subtitle2(ist->st->codec,
&subtitle, got_output, pkt);
if (ret < 0 || !*got_output) {
if (ist->fix_sub_duration) {
if (ist->prev_sub.got_output) {
- int end = av_rescale_q(pts - ist->prev_sub.pts, ist->st->time_base,
- (AVRational){ 1, 1000 });
+ int end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts,
+ 1000, AV_TIME_BASE);
if (end < ist->prev_sub.subtitle.end_display_time) {
av_log(ist->st->codec, AV_LOG_DEBUG,
"Subtitle duration reduced from %d to %d\n",
ist->prev_sub.subtitle.end_display_time = end;
}
}
- FFSWAP(int64_t, pts, ist->prev_sub.pts);
FFSWAP(int, *got_output, ist->prev_sub.got_output);
FFSWAP(int, ret, ist->prev_sub.ret);
FFSWAP(AVSubtitle, subtitle, ist->prev_sub.subtitle);
}
+ sub2video_update(ist, &subtitle);
+
if (!*got_output || !subtitle.num_rects)
return ret;
rate_emu_sleep(ist);
- sub2video_update(ist, &subtitle, pkt->pts);
-
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost = output_streams[i];
if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
continue;
- do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle, pts);
+ do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle);
}
avsubtitle_free(&subtitle);
} else if(!(oc->oformat->flags & AVFMT_VARIABLE_FPS)
&& strcmp(oc->oformat->name, "mov") && strcmp(oc->oformat->name, "mp4") && strcmp(oc->oformat->name, "3gp")
&& strcmp(oc->oformat->name, "3g2") && strcmp(oc->oformat->name, "psp") && strcmp(oc->oformat->name, "ipod")
+ && strcmp(oc->oformat->name, "f4v")
) {
- if( copy_tb<0 && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base)
+ if( copy_tb<0 && icodec->time_base.den
+ && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base)
&& av_q2d(ist->st->time_base) < 1.0/500
|| copy_tb==0){
codec->time_base = icodec->time_base;
}
if (ist)
- ist->decoding_needed = 1;
+ ist->decoding_needed++;
ost->encoding_needed = 1;
if (!ost->filter &&
if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if (ost->filter && !ost->frame_rate.num)
ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter);
+ if (ist && !ost->frame_rate.num)
+ ost->frame_rate = ist->framerate;
if (ist && !ost->frame_rate.num)
ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25, 1};
// ost->frame_rate = ist->st->avg_frame_rate.num ? ist->st->avg_frame_rate : (AVRational){25, 1};
FILE *f;
snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
- pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,
+ ost->logfile_prefix ? ost->logfile_prefix :
+ DEFAULT_PASS_LOGFILENAME_PREFIX,
i);
if (!strcmp(ost->enc->name, "libx264")) {
av_dict_set(&ost->opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
if (ost->frame_number >= ost->max_frames) {
int j;
for (j = 0; j < of->ctx->nb_streams; j++)
- output_streams[of->ost_index + j]->finished = 1;
+ close_output_stream(output_streams[of->ost_index + j]);
continue;
}
output_streams[i]->unavailable = 0;
}
-static void close_output_stream(OutputStream *ost)
-{
- OutputFile *of = output_files[ost->file_index];
-
- ost->finished = 1;
- if (of->shortest) {
- int i;
- for (i = 0; i < of->ctx->nb_streams; i++)
- output_streams[of->ost_index + i]->finished = 1;
- }
-}
-
/**
* @return
* - 0 -- one packet was read and processed
goto discard_packet;
if(!ist->wrap_correction_done && input_files[file_index]->ctx->start_time != AV_NOPTS_VALUE && ist->st->pts_wrap_bits < 64){
- uint64_t stime = av_rescale_q(input_files[file_index]->ctx->start_time, AV_TIME_BASE_Q, ist->st->time_base);
- uint64_t stime2= stime + (1LL<<ist->st->pts_wrap_bits);
+ int64_t stime = av_rescale_q(input_files[file_index]->ctx->start_time, AV_TIME_BASE_Q, ist->st->time_base);
+ int64_t stime2= stime + (1ULL<<ist->st->pts_wrap_bits);
ist->wrap_correction_done = 1;
- if(pkt.dts != AV_NOPTS_VALUE && pkt.dts > stime && pkt.dts - stime > stime2 - pkt.dts) {
- pkt.dts -= 1LL<<ist->st->pts_wrap_bits;
+
+ if(stime2 > stime && pkt.dts != AV_NOPTS_VALUE && pkt.dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
+ pkt.dts -= 1ULL<<ist->st->pts_wrap_bits;
ist->wrap_correction_done = 0;
}
- if(pkt.pts != AV_NOPTS_VALUE && pkt.pts > stime && pkt.pts - stime > stime2 - pkt.pts) {
- pkt.pts -= 1LL<<ist->st->pts_wrap_bits;
+ if(stime2 > stime && pkt.pts != AV_NOPTS_VALUE && pkt.pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
+ pkt.pts -= 1ULL<<ist->st->pts_wrap_bits;
ist->wrap_correction_done = 0;
}
}
{
int idx = locate_option(argc, argv, options, "cpuflags");
if (idx && argv[idx + 1])
- opt_cpuflags("cpuflags", argv[idx + 1]);
+ opt_cpuflags(NULL, "cpuflags", argv[idx + 1]);
}
int main(int argc, char **argv)