|  |  | @@ -34,6 +34,8 @@ | 
		
	
		
			
			|  |  |  | #include "libavutil/opt.h" | 
		
	
		
			
			|  |  |  | #include "libavutil/parseutils.h" | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #define FF_INTERNAL_FIELDS 1 | 
		
	
		
			
			|  |  |  | #include "framequeue.h" | 
		
	
		
			
			|  |  |  | #include "avfilter.h" | 
		
	
		
			
			|  |  |  | #include "internal.h" | 
		
	
		
			
			|  |  |  | #include "video.h" | 
		
	
	
		
			
				|  |  | @@ -137,13 +139,45 @@ static int request_frame(AVFilterLink *outlink) | 
		
	
		
			
			|  |  |  | AVFrame *buf; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL); | 
		
	
		
			
			|  |  |  | buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, | 
		
	
		
			
			|  |  |  | outlink->time_base) + s->frames_out; | 
		
	
		
			
			|  |  |  | if (av_fifo_size(s->fifo)) { | 
		
	
		
			
			|  |  |  | buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, | 
		
	
		
			
			|  |  |  | outlink->time_base) + s->frames_out; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if ((ret = ff_filter_frame(outlink, buf)) < 0) | 
		
	
		
			
			|  |  |  | return ret; | 
		
	
		
			
			|  |  |  | if ((ret = ff_filter_frame(outlink, buf)) < 0) | 
		
	
		
			
			|  |  |  | return ret; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->frames_out++; | 
		
	
		
			
			|  |  |  | s->frames_out++; | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | /* This is the last frame, we may have to duplicate it to match | 
		
	
		
			
			|  |  |  | * the last frame duration */ | 
		
	
		
			
			|  |  |  | int j; | 
		
	
		
			
			|  |  |  | int delta = av_rescale_q_rnd(ctx->inputs[0]->current_pts - s->first_pts, | 
		
	
		
			
			|  |  |  | ctx->inputs[0]->time_base, | 
		
	
		
			
			|  |  |  | outlink->time_base, s->rounding) - s->frames_out ; | 
		
	
		
			
			|  |  |  | /* if the delta is equal to 1, it means we just need to output | 
		
	
		
			
			|  |  |  | * the last frame. Greater than 1 means we will need duplicate | 
		
	
		
			
			|  |  |  | * delta-1 frames */ | 
		
	
		
			
			|  |  |  | if (delta > 0 ) { | 
		
	
		
			
			|  |  |  | for (j = 0; j < delta; j++) { | 
		
	
		
			
			|  |  |  | AVFrame *dup = av_frame_clone(buf); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n"); | 
		
	
		
			
			|  |  |  | dup->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, | 
		
	
		
			
			|  |  |  | outlink->time_base) + s->frames_out; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if ((ret = ff_filter_frame(outlink, dup)) < 0) | 
		
	
		
			
			|  |  |  | return ret; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->frames_out++; | 
		
	
		
			
			|  |  |  | if (j > 0) s->dup++; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | /* for delta less or equal to 0, we should drop the frame, | 
		
	
		
			
			|  |  |  | * otherwise, we will have one or more extra frames */ | 
		
	
		
			
			|  |  |  | av_frame_free(&buf); | 
		
	
		
			
			|  |  |  | s->drop++; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | 
 |