You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	lavfi: replace link.closed by link.status.
The status field can carry any error code instead of just EOF. Also only update it through a wrapper function and provide a timestamp. Update the few filters that used it directly.
This commit is contained in:
		| @@ -178,9 +178,20 @@ int avfilter_link_get_channels(AVFilterLink *link) | ||||
|     return link->channels; | ||||
| } | ||||
|  | ||||
| void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts) | ||||
| { | ||||
|     ff_avfilter_link_set_out_status(link, status, pts); | ||||
| } | ||||
|  | ||||
| void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts) | ||||
| { | ||||
|     link->status = status; | ||||
|     ff_update_link_current_pts(link, pts); | ||||
| } | ||||
|  | ||||
| void avfilter_link_set_closed(AVFilterLink *link, int closed) | ||||
| { | ||||
|     link->closed = closed; | ||||
|     ff_avfilter_link_set_out_status(link, closed ? AVERROR_EOF : 0, AV_NOPTS_VALUE); | ||||
| } | ||||
|  | ||||
| int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, | ||||
| @@ -346,8 +357,8 @@ int ff_request_frame(AVFilterLink *link) | ||||
|     int ret = -1; | ||||
|     FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1); | ||||
|  | ||||
|     if (link->closed) | ||||
|         return AVERROR_EOF; | ||||
|     if (link->status) | ||||
|         return link->status; | ||||
|     if (link->srcpad->request_frame) | ||||
|         ret = link->srcpad->request_frame(link); | ||||
|     else if (link->src->inputs[0]) | ||||
| @@ -358,8 +369,8 @@ int ff_request_frame(AVFilterLink *link) | ||||
|         ret = ff_filter_frame_framed(link, pbuf); | ||||
|     } | ||||
|     if (ret < 0) { | ||||
|         if (ret == AVERROR_EOF) | ||||
|             link->closed = 1; | ||||
|         if (ret != AVERROR(EAGAIN) && ret != link->status) | ||||
|             ff_avfilter_link_set_in_status(link, ret, AV_NOPTS_VALUE); | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| @@ -1005,9 +1016,9 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) | ||||
|     AVFilterCommand *cmd= link->dst->command_queue; | ||||
|     int64_t pts; | ||||
|  | ||||
|     if (link->closed) { | ||||
|     if (link->status) { | ||||
|         av_frame_free(&frame); | ||||
|         return AVERROR_EOF; | ||||
|         return link->status; | ||||
|     } | ||||
|  | ||||
|     if (!(filter_frame = dst->filter_frame)) | ||||
|   | ||||
| @@ -490,16 +490,16 @@ struct AVFilterLink { | ||||
|     int max_samples; | ||||
|  | ||||
|     /** | ||||
|      * True if the link is closed. | ||||
|      * If set, all attempts of start_frame, filter_frame or request_frame | ||||
|      * will fail with AVERROR_EOF, and if necessary the reference will be | ||||
|      * destroyed. | ||||
|      * If request_frame returns AVERROR_EOF, this flag is set on the | ||||
|      * Link status. | ||||
|      * If not zero, all attempts of start_frame, filter_frame or request_frame | ||||
|      * will fail with the corresponding code, and if necessary the reference | ||||
|      * will be destroyed. | ||||
|      * If request_frame returns an error, the status is set on the | ||||
|      * corresponding link. | ||||
|      * It can be set also be set by either the source or the destination | ||||
|      * filter. | ||||
|      */ | ||||
|     int closed; | ||||
|     int status; | ||||
|  | ||||
|     /** | ||||
|      * Number of channels. | ||||
|   | ||||
| @@ -134,8 +134,8 @@ int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFr | ||||
|  | ||||
|     /* no picref available, fetch it from the filterchain */ | ||||
|     while (!av_fifo_size(buf->fifo)) { | ||||
|         if (inlink->closed) | ||||
|             return AVERROR_EOF; | ||||
|         if (inlink->status) | ||||
|             return inlink->status; | ||||
|         if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST) | ||||
|             return AVERROR(EAGAIN); | ||||
|         if ((ret = ff_request_frame(inlink)) < 0) | ||||
|   | ||||
| @@ -59,7 +59,7 @@ inline static int push_frame(AVFilterContext *ctx) | ||||
|     for (i = 0; i < ctx->nb_inputs; i++) { | ||||
|         struct FFBufQueue *q = &s->queues[i]; | ||||
|  | ||||
|         if (!q->available && !ctx->inputs[i]->closed) | ||||
|         if (!q->available && !ctx->inputs[i]->status) | ||||
|             return 0; | ||||
|         if (q->available) { | ||||
|             frame = ff_bufqueue_peek(q, 0); | ||||
| @@ -190,7 +190,7 @@ static int request_frame(AVFilterLink *outlink) | ||||
|     int i, ret; | ||||
|  | ||||
|     for (i = 0; i < ctx->nb_inputs; i++) { | ||||
|         if (!s->queues[i].available && !ctx->inputs[i]->closed) { | ||||
|         if (!s->queues[i].available && !ctx->inputs[i]->status) { | ||||
|             ret = ff_request_frame(ctx->inputs[i]); | ||||
|             if (ret != AVERROR_EOF) | ||||
|                 return ret; | ||||
|   | ||||
| @@ -226,6 +226,21 @@ int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, | ||||
|  | ||||
| void ff_update_link_current_pts(AVFilterLink *link, int64_t pts); | ||||
|  | ||||
| /** | ||||
|  * Set the status field of a link from the source filter. | ||||
|  * The pts should reflect the timestamp of the status change, | ||||
|  * in link time base and relative to the frames timeline. | ||||
|  * In particular, for AVERROR_EOF, it should reflect the | ||||
|  * end time of the last frame. | ||||
|  */ | ||||
| void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts); | ||||
|  | ||||
| /** | ||||
|  * Set the status field of a link from the destination filter. | ||||
|  * The pts should probably be left unset (AV_NOPTS_VALUE). | ||||
|  */ | ||||
| void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts); | ||||
|  | ||||
| void ff_command_queue_pop(AVFilterContext *filter); | ||||
|  | ||||
| /* misc trace functions */ | ||||
|   | ||||
| @@ -77,7 +77,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
|     for (i = 0; i < ctx->nb_outputs; i++) { | ||||
|         AVFrame *buf_out; | ||||
|  | ||||
|         if (ctx->outputs[i]->closed) | ||||
|         if (ctx->outputs[i]->status) | ||||
|             continue; | ||||
|         buf_out = av_frame_clone(frame); | ||||
|         if (!buf_out) { | ||||
|   | ||||
| @@ -174,7 +174,8 @@ static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
|             drop = 0; | ||||
|  | ||||
|         if (drop) { | ||||
|             s->eof = inlink->closed = 1; | ||||
|             s->eof = 1; | ||||
|             ff_avfilter_link_set_out_status(inlink, AVERROR_EOF, AV_NOPTS_VALUE); | ||||
|             goto drop; | ||||
|         } | ||||
|     } | ||||
| @@ -305,7 +306,8 @@ static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
|         } | ||||
|  | ||||
|         if (drop) { | ||||
|             s->eof = inlink->closed = 1; | ||||
|             s->eof = 1; | ||||
|             ff_avfilter_link_set_out_status(inlink, AVERROR_EOF, AV_NOPTS_VALUE); | ||||
|             goto drop; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -219,7 +219,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
|         const int idx = s->map[i]; | ||||
|         AVFrame *out; | ||||
|  | ||||
|         if (outlink->closed) | ||||
|         if (outlink->status) | ||||
|             continue; | ||||
|  | ||||
|         out = ff_get_video_buffer(outlink, outlink->w, outlink->h); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user