diff options
author | Anton Khirnov <anton@khirnov.net> | 2012-02-05 14:32:10 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2012-02-07 20:11:11 +0100 |
commit | 1270e12e49c9039fa5fe18cfb45137558d127f92 (patch) | |
tree | 2ff84e541b91ef8c10db23273ff809115303e0fc /avconv.c | |
parent | c9af8326238c37d1a1f0029a158c7ede33836aa3 (diff) | |
download | ffmpeg-1270e12e49c9039fa5fe18cfb45137558d127f92.tar.gz |
avconv: rework -t handling for encoding.
Current code compares the desired recording time with InputStream.pts,
which has a very unclear meaning. Change the code to use actual
timestamps of the frames passed to the encoder.
In several tests, one less frame is encoded, which is more correct.
In the idroq test one more frame is encoded, which is again more
correct.
Behavior with stream copy should be unchanged.
Diffstat (limited to 'avconv.c')
-rw-r--r-- | avconv.c | 47 |
1 files changed, 37 insertions, 10 deletions
@@ -204,6 +204,9 @@ typedef struct OutputStream { // double sync_ipts; /* dts from the AVPacket of the demuxer in second units */ struct InputStream *sync_ist; /* input stream to sync against */ int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number + /* pts of the first frame encoded for this stream, used for limiting + * recording time */ + int64_t first_pts; AVBitStreamFilterContext *bitstream_filters; AVCodec *enc; int64_t max_frames; @@ -918,6 +921,19 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) } } +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->is_past_recording_time = 1; + return 0; + } + return 1; +} + static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size) { int fill_char = 0x00; @@ -958,6 +974,11 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost, av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n"); exit_program(1); } + + if (!check_recording_time(ost)) + return 0; + + ost->sync_opts += frame->nb_samples; } got_packet = 0; @@ -977,9 +998,6 @@ static int encode_audio_frame(AVFormatContext *s, OutputStream *ost, audio_size += pkt.size; } - if (frame) - ost->sync_opts += frame->nb_samples; - return pkt.size; } @@ -1241,6 +1259,10 @@ static void do_subtitle_out(AVFormatContext *s, nb = 1; for (i = 0; i < nb; i++) { + ost->sync_opts = av_rescale_q(pts, ist->st->time_base, enc->time_base); + if (!check_recording_time(ost)) + return; + sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q); // start_display_time is required to be 0 sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); @@ -1382,11 +1404,17 @@ static void do_video_out(AVFormatContext *s, final_picture = in_picture; #endif + if (!ost->frame_number) + ost->first_pts = ost->sync_opts; + /* duplicates frame if needed */ for (i = 0; i < nb_frames; i++) { AVPacket pkt; av_init_packet(&pkt); + if (!check_recording_time(ost)) + return; + if (s->oformat->flags & AVFMT_RAWPICTURE && enc->codec->id == CODEC_ID_RAWVIDEO) { /* raw pictures are written as AVPicture structure to @@ -1723,13 +1751,6 @@ static int check_output_constraints(InputStream *ist, OutputStream *ost) if (of->start_time && ist->pts < of->start_time) return 0; - if (of->recording_time != INT64_MAX && - av_compare_ts(ist->pts, AV_TIME_BASE_Q, of->recording_time + of->start_time, - (AVRational){ 1, 1000000 }) >= 0) { - ost->is_past_recording_time = 1; - return 0; - } - return 1; } @@ -1745,6 +1766,12 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p !ost->copy_initial_nonkeyframes) return; + if (of->recording_time != INT64_MAX && + ist->pts >= of->recording_time + of->start_time) { + ost->is_past_recording_time = 1; + return; + } + /* force the input stream PTS */ if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) audio_size += pkt->size; |