|
|
@@ -60,6 +60,7 @@ |
|
|
#include "libavutil/bprint.h" |
|
|
#include "libavutil/bprint.h" |
|
|
#include "libavutil/time.h" |
|
|
#include "libavutil/time.h" |
|
|
#include "libavutil/threadmessage.h" |
|
|
#include "libavutil/threadmessage.h" |
|
|
|
|
|
#include "libavcodec/mathops.h" |
|
|
#include "libavformat/os_support.h" |
|
|
#include "libavformat/os_support.h" |
|
|
|
|
|
|
|
|
# include "libavfilter/avcodec.h" |
|
|
# include "libavfilter/avcodec.h" |
|
|
@@ -914,6 +915,12 @@ static void do_video_out(AVFormatContext *s, |
|
|
duration = lrintf(av_frame_get_pkt_duration(next_picture) * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)); |
|
|
duration = lrintf(av_frame_get_pkt_duration(next_picture) * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!next_picture) { |
|
|
|
|
|
//end, flushing |
|
|
|
|
|
nb0_frames = nb_frames = mid_pred(ost->last_nb0_frames[0], |
|
|
|
|
|
ost->last_nb0_frames[1], |
|
|
|
|
|
ost->last_nb0_frames[2]); |
|
|
|
|
|
} else { |
|
|
delta0 = sync_ipts - ost->sync_opts; |
|
|
delta0 = sync_ipts - ost->sync_opts; |
|
|
delta = delta0 + duration; |
|
|
delta = delta0 + duration; |
|
|
|
|
|
|
|
|
@@ -985,9 +992,16 @@ static void do_video_out(AVFormatContext *s, |
|
|
default: |
|
|
default: |
|
|
av_assert0(0); |
|
|
av_assert0(0); |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number); |
|
|
nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number); |
|
|
nb0_frames = FFMIN(nb0_frames, nb_frames); |
|
|
nb0_frames = FFMIN(nb0_frames, nb_frames); |
|
|
|
|
|
|
|
|
|
|
|
memmove(ost->last_nb0_frames + 1, |
|
|
|
|
|
ost->last_nb0_frames, |
|
|
|
|
|
sizeof(ost->last_nb0_frames[0]) * (FF_ARRAY_ELEMS(ost->last_nb0_frames) - 1)); |
|
|
|
|
|
ost->last_nb0_frames[0] = nb0_frames; |
|
|
|
|
|
|
|
|
if (nb0_frames == 0 && ost->last_droped) { |
|
|
if (nb0_frames == 0 && ost->last_droped) { |
|
|
nb_frames_drop++; |
|
|
nb_frames_drop++; |
|
|
av_log(NULL, AV_LOG_VERBOSE, |
|
|
av_log(NULL, AV_LOG_VERBOSE, |
|
|
@@ -1003,7 +1017,7 @@ static void do_video_out(AVFormatContext *s, |
|
|
nb_frames_dup += nb_frames - (nb0_frames && ost->last_droped) - (nb_frames > nb0_frames); |
|
|
nb_frames_dup += nb_frames - (nb0_frames && ost->last_droped) - (nb_frames > nb0_frames); |
|
|
av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1); |
|
|
av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1); |
|
|
} |
|
|
} |
|
|
ost->last_droped = nb_frames == nb0_frames; |
|
|
|
|
|
|
|
|
ost->last_droped = nb_frames == nb0_frames && next_picture; |
|
|
|
|
|
|
|
|
/* duplicates frame if needed */ |
|
|
/* duplicates frame if needed */ |
|
|
for (i = 0; i < nb_frames; i++) { |
|
|
for (i = 0; i < nb_frames; i++) { |
|
|
@@ -1156,6 +1170,7 @@ static void do_video_out(AVFormatContext *s, |
|
|
if (!ost->last_frame) |
|
|
if (!ost->last_frame) |
|
|
ost->last_frame = av_frame_alloc(); |
|
|
ost->last_frame = av_frame_alloc(); |
|
|
av_frame_unref(ost->last_frame); |
|
|
av_frame_unref(ost->last_frame); |
|
|
|
|
|
if (next_picture) |
|
|
av_frame_ref(ost->last_frame, next_picture); |
|
|
av_frame_ref(ost->last_frame, next_picture); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -1219,7 +1234,7 @@ static void finish_output_stream(OutputStream *ost) |
|
|
* |
|
|
* |
|
|
* @return 0 for success, <0 for severe errors |
|
|
* @return 0 for success, <0 for severe errors |
|
|
*/ |
|
|
*/ |
|
|
static int reap_filters(void) |
|
|
|
|
|
|
|
|
static int reap_filters(int flush) |
|
|
{ |
|
|
{ |
|
|
AVFrame *filtered_frame = NULL; |
|
|
AVFrame *filtered_frame = NULL; |
|
|
int i; |
|
|
int i; |
|
|
@@ -1249,6 +1264,9 @@ static int reap_filters(void) |
|
|
if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { |
|
|
if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { |
|
|
av_log(NULL, AV_LOG_WARNING, |
|
|
av_log(NULL, AV_LOG_WARNING, |
|
|
"Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret)); |
|
|
"Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret)); |
|
|
|
|
|
} else if (flush) { |
|
|
|
|
|
if (filter->inputs[0]->type == AVMEDIA_TYPE_VIDEO) |
|
|
|
|
|
do_video_out(of->ctx, ost, NULL, AV_NOPTS_VALUE); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
@@ -3741,10 +3759,10 @@ static int transcode_from_filter(FilterGraph *graph, InputStream **best_ist) |
|
|
*best_ist = NULL; |
|
|
*best_ist = NULL; |
|
|
ret = avfilter_graph_request_oldest(graph->graph); |
|
|
ret = avfilter_graph_request_oldest(graph->graph); |
|
|
if (ret >= 0) |
|
|
if (ret >= 0) |
|
|
return reap_filters(); |
|
|
|
|
|
|
|
|
return reap_filters(0); |
|
|
|
|
|
|
|
|
if (ret == AVERROR_EOF) { |
|
|
if (ret == AVERROR_EOF) { |
|
|
ret = reap_filters(); |
|
|
|
|
|
|
|
|
ret = reap_filters(1); |
|
|
for (i = 0; i < graph->nb_outputs; i++) |
|
|
for (i = 0; i < graph->nb_outputs; i++) |
|
|
close_output_stream(graph->outputs[i]->ost); |
|
|
close_output_stream(graph->outputs[i]->ost); |
|
|
return ret; |
|
|
return ret; |
|
|
@@ -3810,10 +3828,11 @@ static int transcode_step(void) |
|
|
ost->unavailable = 1; |
|
|
ost->unavailable = 1; |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (ret < 0) |
|
|
if (ret < 0) |
|
|
return ret == AVERROR_EOF ? 0 : ret; |
|
|
return ret == AVERROR_EOF ? 0 : ret; |
|
|
|
|
|
|
|
|
return reap_filters(); |
|
|
|
|
|
|
|
|
return reap_filters(0); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
|