| @@ -140,6 +140,12 @@ int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts · 139 unmodified lines |
| 140 | 140 | */ |
| 141 | 141 | void ff_inlink_request_frame(AVFilterLink *link); |
| 142 | 142 | |
| 143 | +/** |
| 144 | + * Set the status on an input link. |
| 145 | + * Also discard all frames in the link's FIFO. |
| 146 | + */ |
| 147 | +void ff_inlink_set_status(AVFilterLink *link, int status); |
| 148 | + |
| 143 | 149 | /** |
| 144 | 150 | * Test if a frame is wanted on an output link. |
| 145 | 151 | */ |
| @@ -148,6 +154,11 @@ static inline int ff_outlink_frame_wanted(AVFilterLink *link) · 2 unmodified lines |
| 148 | 154 | return link->frame_wanted_out; |
| 149 | 155 | } |
| 150 | 156 | |
| 157 | +/** |
| 158 | + * Get the status on an output link. |
| 159 | + */ |
| 160 | +int ff_outlink_get_status(AVFilterLink *link); |
| 161 | + |
| 151 | 162 | /** |
| 152 | 163 | * Set the status field of a link from the source filter. |
| 153 | 164 | * The pts should reflect the timestamp of the status change, |
| @@ -160,4 +171,71 @@ static inline void ff_outlink_set_status(AVFilterLink *link, int status, int64_t · 6 unmodified lines |
| 160 | 171 | ff_avfilter_link_set_in_status(link, status, pts); |
| 161 | 172 | } |
| 162 | 173 | |
| 174 | +/** |
| 175 | + * Forward the status on an output link to an input link. |
| 176 | + * If the status is set, it will discard all queued frames and this macro |
| 177 | + * will return immediately. |
| 178 | + */ |
| 179 | +#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink) do { \ |
| 180 | + int ret = ff_outlink_get_status(outlink); \ |
| 181 | + if (ret) { \ |
| 182 | + ff_inlink_set_status(inlink, ret); \ |
| 183 | + return 0; \ |
| 184 | + } \ |
| 185 | +} while (0) |
| 186 | + |
| 187 | +/** |
| 188 | + * Forward the status on an output link to all input links. |
| 189 | + * If the status is set, it will discard all queued frames and this macro |
| 190 | + * will return immediately. |
| 191 | + */ |
| 192 | +#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter) do { \ |
| 193 | + int ret = ff_outlink_get_status(outlink); \ |
| 194 | + if (ret) { \ |
| 195 | + unsigned i; \ |
| 196 | + for (i = 0; i < filter->nb_inputs; i++) \ |
| 197 | + ff_inlink_set_status(filter->inputs[i], ret); \ |
| 198 | + return 0; \ |
| 199 | + } \ |
| 200 | +} while (0) |
| 201 | + |
| 202 | +/** |
| 203 | + * Acknowledge the status on an input link and forward it to an output link. |
| 204 | + * If the status is set, this macro will return immediately. |
| 205 | + */ |
| 206 | +#define FF_FILTER_FORWARD_STATUS(inlink, outlink) do { \ |
| 207 | + int status; \ |
| 208 | + int64_t pts; \ |
| 209 | + if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { \ |
| 210 | + ff_outlink_set_status(outlink, status, pts); \ |
| 211 | + return 0; \ |
| 212 | + } \ |
| 213 | +} while (0) |
| 214 | + |
| 215 | +/** |
| 216 | + * Acknowledge the status on an input link and forward it to an output link. |
| 217 | + * If the status is set, this macro will return immediately. |
| 218 | + */ |
| 219 | +#define FF_FILTER_FORWARD_STATUS_ALL(inlink, filter) do { \ |
| 220 | + int status; \ |
| 221 | + int64_t pts; \ |
| 222 | + if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { \ |
| 223 | + unsigned i; \ |
| 224 | + for (i = 0; i < filter->nb_outputs; i++) \ |
| 225 | + ff_outlink_set_status(filter->outputs[i], status, pts); \ |
| 226 | + return 0; \ |
| 227 | + } \ |
| 228 | +} while (0) |
| 229 | + |
| 230 | +/** |
| 231 | + * Forward the frame_wanted_out flag from an output link to an input link. |
| 232 | + * If the flag is set, this macro will return immediately. |
| 233 | + */ |
| 234 | +#define FF_FILTER_FORWARD_WANTED(outlink, inlink) do { \ |
| 235 | + if (ff_outlink_frame_wanted(outlink)) { \ |
| 236 | + ff_inlink_request_frame(inlink); \ |
| 237 | + return 0; \ |
| 238 | + } \ |
| 239 | +} while (0) |
| 240 | + |
| 163 | 241 | #endif /* AVFILTER_FILTERS_H */ |