Merge commit '16b0c929621f84983b83b9735ce973acb12723bc'
* commit '16b0c929621f84983b83b9735ce973acb12723bc': avconv: Add loop option. Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
This commit is contained in:
108
ffmpeg.c
108
ffmpeg.c
@@ -2024,6 +2024,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
|
||||
decoded_frame->pts = av_rescale_delta(decoded_frame_tb, decoded_frame->pts,
|
||||
(AVRational){1, avctx->sample_rate}, decoded_frame->nb_samples, &ist->filter_in_rescale_delta_last,
|
||||
(AVRational){1, avctx->sample_rate});
|
||||
ist->nb_samples = decoded_frame->nb_samples;
|
||||
for (i = 0; i < ist->nb_filters; i++) {
|
||||
if (i < ist->nb_filters - 1) {
|
||||
f = ist->filter_frame;
|
||||
@@ -2261,7 +2262,7 @@ static int send_filter_eof(InputStream *ist)
|
||||
}
|
||||
|
||||
/* pkt = NULL means EOF (needed to flush decoder buffers) */
|
||||
static int process_input_packet(InputStream *ist, const AVPacket *pkt)
|
||||
static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eof)
|
||||
{
|
||||
int ret = 0, i;
|
||||
int got_output = 0;
|
||||
@@ -2370,7 +2371,8 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt)
|
||||
}
|
||||
|
||||
/* after flushing, send an EOF on all the filter inputs attached to the stream */
|
||||
if (!pkt && ist->decoding_needed && !got_output) {
|
||||
/* except when looping we need to flush but not to send an EOF */
|
||||
if (!pkt && ist->decoding_needed && !got_output && !no_eof) {
|
||||
int ret = send_filter_eof(ist);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error marking filters as finished\n");
|
||||
@@ -3606,6 +3608,86 @@ static void reset_eagain(void)
|
||||
output_streams[i]->unavailable = 0;
|
||||
}
|
||||
|
||||
// set duration to max(tmp, duration) in a proper time base and return duration's time_base
|
||||
static AVRational duration_max(int64_t tmp, int64_t *duration, AVRational tmp_time_base,
|
||||
AVRational time_base)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!*duration) {
|
||||
*duration = tmp;
|
||||
return tmp_time_base;
|
||||
}
|
||||
|
||||
ret = av_compare_ts(*duration, time_base, tmp, tmp_time_base);
|
||||
if (ret < 0) {
|
||||
*duration = tmp;
|
||||
return tmp_time_base;
|
||||
}
|
||||
|
||||
return time_base;
|
||||
}
|
||||
|
||||
static int seek_to_start(InputFile *ifile, AVFormatContext *is)
|
||||
{
|
||||
InputStream *ist;
|
||||
AVCodecContext *avctx;
|
||||
int i, ret, has_audio = 0;
|
||||
int64_t duration = 0;
|
||||
|
||||
ret = av_seek_frame(is, -1, is->start_time, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < ifile->nb_streams; i++) {
|
||||
ist = input_streams[ifile->ist_index + i];
|
||||
avctx = ist->dec_ctx;
|
||||
|
||||
// flush decoders
|
||||
if (ist->decoding_needed) {
|
||||
process_input_packet(ist, NULL, 1);
|
||||
avcodec_flush_buffers(avctx);
|
||||
}
|
||||
|
||||
/* duration is the length of the last frame in a stream
|
||||
* when audio stream is present we don't care about
|
||||
* last video frame length because it's not defined exactly */
|
||||
if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && ist->nb_samples)
|
||||
has_audio = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ifile->nb_streams; i++) {
|
||||
ist = input_streams[ifile->ist_index + i];
|
||||
avctx = ist->dec_ctx;
|
||||
|
||||
if (has_audio) {
|
||||
if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && ist->nb_samples) {
|
||||
AVRational sample_rate = {1, avctx->sample_rate};
|
||||
|
||||
duration = av_rescale_q(ist->nb_samples, sample_rate, ist->st->time_base);
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
if (ist->framerate.num) {
|
||||
duration = av_rescale_q(1, ist->framerate, ist->st->time_base);
|
||||
} else if (ist->st->avg_frame_rate.num) {
|
||||
duration = av_rescale_q(1, ist->st->avg_frame_rate, ist->st->time_base);
|
||||
} else duration = 1;
|
||||
}
|
||||
if (!ifile->duration)
|
||||
ifile->time_base = ist->st->time_base;
|
||||
/* the total duration of the stream, max_pts - min_pts is
|
||||
* the duration of the stream without the last frame */
|
||||
duration += ist->max_pts - ist->min_pts;
|
||||
ifile->time_base = duration_max(duration, &ifile->duration, ist->st->time_base,
|
||||
ifile->time_base);
|
||||
}
|
||||
|
||||
ifile->loop--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return
|
||||
* - 0 -- one packet was read and processed
|
||||
@@ -3620,6 +3702,7 @@ static int process_input(int file_index)
|
||||
InputStream *ist;
|
||||
AVPacket pkt;
|
||||
int ret, i, j;
|
||||
int64_t duration;
|
||||
|
||||
is = ifile->ctx;
|
||||
ret = get_input_packet(ifile, &pkt);
|
||||
@@ -3628,6 +3711,11 @@ static int process_input(int file_index)
|
||||
ifile->eagain = 1;
|
||||
return ret;
|
||||
}
|
||||
if ((ret < 0) && (ifile->loop > 1)) {
|
||||
if ((ret = seek_to_start(ifile, is)) < 0)
|
||||
return ret;
|
||||
ret = get_input_packet(ifile, &pkt);
|
||||
}
|
||||
if (ret < 0) {
|
||||
if (ret != AVERROR_EOF) {
|
||||
print_error(is->filename, ret);
|
||||
@@ -3638,7 +3726,7 @@ static int process_input(int file_index)
|
||||
for (i = 0; i < ifile->nb_streams; i++) {
|
||||
ist = input_streams[ifile->ist_index + i];
|
||||
if (ist->decoding_needed) {
|
||||
ret = process_input_packet(ist, NULL);
|
||||
ret = process_input_packet(ist, NULL, 0);
|
||||
if (ret>0)
|
||||
return 0;
|
||||
}
|
||||
@@ -3773,6 +3861,16 @@ static int process_input(int file_index)
|
||||
pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
|
||||
}
|
||||
}
|
||||
|
||||
duration = av_rescale_q(ifile->duration, ifile->time_base, ist->st->time_base);
|
||||
if (pkt.pts != AV_NOPTS_VALUE) {
|
||||
pkt.pts += duration;
|
||||
ist->max_pts = FFMAX(pkt.pts, ist->max_pts);
|
||||
ist->min_pts = FFMIN(pkt.pts, ist->min_pts);
|
||||
}
|
||||
|
||||
if (pkt.dts != AV_NOPTS_VALUE)
|
||||
pkt.dts += duration;
|
||||
|
||||
if ((ist->dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
|
||||
ist->dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) &&
|
||||
@@ -3824,7 +3922,7 @@ static int process_input(int file_index)
|
||||
|
||||
sub2video_heartbeat(ist, pkt.pts);
|
||||
|
||||
process_input_packet(ist, &pkt);
|
||||
process_input_packet(ist, &pkt, 0);
|
||||
|
||||
discard_packet:
|
||||
av_free_packet(&pkt);
|
||||
@@ -3989,7 +4087,7 @@ static int transcode(void)
|
||||
for (i = 0; i < nb_input_streams; i++) {
|
||||
ist = input_streams[i];
|
||||
if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) {
|
||||
process_input_packet(ist, NULL);
|
||||
process_input_packet(ist, NULL, 0);
|
||||
}
|
||||
}
|
||||
flush_encoders();
|
||||
|
Reference in New Issue
Block a user