aboutsummaryrefslogtreecommitdiffstats
path: root/avconv.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2012-02-05 14:32:10 +0100
committerAnton Khirnov <anton@khirnov.net>2012-02-07 20:11:11 +0100
commit1270e12e49c9039fa5fe18cfb45137558d127f92 (patch)
tree2ff84e541b91ef8c10db23273ff809115303e0fc /avconv.c
parentc9af8326238c37d1a1f0029a158c7ede33836aa3 (diff)
downloadffmpeg-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.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/avconv.c b/avconv.c
index 876ad1996c..30782e1826 100644
--- a/avconv.c
+++ b/avconv.c
@@ -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;