#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_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;
bsfc = next;
}
output_streams[i]->bitstream_filters = NULL;
+ avcodec_free_frame(&output_streams[i]->filtered_frame);
av_freep(&output_streams[i]->forced_keyframes);
av_freep(&output_streams[i]->avfilter);
- av_freep(&output_streams[i]->filtered_frame);
+ av_freep(&output_streams[i]->logfile_prefix);
av_freep(&output_streams[i]);
}
for (i = 0; i < nb_input_files; i++) {
av_freep(&input_files[i]);
}
for (i = 0; i < nb_input_streams; i++) {
- av_freep(&input_streams[i]->decoded_frame);
+ avcodec_free_frame(&input_streams[i]->decoded_frame);
av_dict_free(&input_streams[i]->opts);
free_buffer_pool(&input_streams[i]->buffer_pool);
avfilter_unref_bufferp(&input_streams[i]->sub2video.ref);
}
pkt->stream_index = ost->index;
+
+ if (debug_ts) {
+ av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
+ "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s size:%d\n",
+ av_get_media_type_string(ost->st->codec->codec_type),
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
+ pkt->size
+ );
+ }
+
ret = av_interleaved_write_frame(s, pkt);
if (ret < 0) {
print_error("av_interleaved_write_frame()", ret);
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);
}
}
return;
} else if (nb_frames > 1) {
if (nb_frames > dts_error_threshold * 30) {
- av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skiping\n", nb_frames - 1);
+ av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1);
nb_frames_drop++;
return;
}
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;
!ost->copy_initial_nonkeyframes)
return;
+ if (!ost->frame_number && ist->pts < of->start_time &&
+ !ost->copy_prior_start)
+ return;
+
if (of->recording_time != INT64_MAX &&
ist->pts >= of->recording_time + of->start_time) {
- ost->finished = 1;
+ close_output_stream(ost);
return;
}
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 (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;
}
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)
reset_options(&o, 0);
+ setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
+
av_log_set_flags(AV_LOG_SKIP_REPEATED);
parse_loglevel(argc, argv, options);