Filters can use min_samples/max_samples if the number is constant or activate and ff_inlink_consume_samples().
Unified · Split
| @@ -490,14 +490,6 @@ struct AVFilterLink { · 489 unmodified lines | ||
| 490 | 490 | struct AVFilterChannelLayouts *in_channel_layouts; |
| 491 | 491 | struct AVFilterChannelLayouts *out_channel_layouts; |
| 492 | 492 | |
| 493 | − /** | |
| 494 | − * Audio only, the destination filter sets this to a non-zero value to | |
| 495 | − * request that buffers with the given number of samples should be sent to | |
| 496 | − * it. | |
| 497 | − * Last buffer before EOF will be padded with silence. | |
| 498 | − */ | |
| 499 | − int request_samples; | |
| 500 | − | |
| 501 | 493 | /** stage of the initialization of the link properties (dimensions, etc) */ |
| 502 | 494 | enum { |
| 503 | 495 | AVLINK_UNINIT = 0, ///< not started |
| @@ -143,112 +143,19 @@ static int calc_ptr_alignment(AVFrame *frame) · 142 unmodified lines | ||
| 143 | 143 | return min_align; |
| 144 | 144 | } |
| 145 | 145 | |
| 146 | −static int return_audio_frame(AVFilterContext *ctx) | |
| 147 | −{ | |
| 148 | − AVFilterLink *link = ctx->outputs[0]; | |
| 149 | − FifoContext *s = ctx->priv; | |
| 150 | − AVFrame *head = s->root.next ? s->root.next->frame : NULL; | |
| 151 | − AVFrame *out; | |
| 152 | − int ret; | |
| 153 | − | |
| 154 | − /* if head is NULL then we're flushing the remaining samples in out */ | |
| 155 | − if (!head && !s->out) | |
| 156 | − return AVERROR_EOF; | |
| 157 | − | |
| 158 | − if (!s->out && | |
| 159 | − head->nb_samples >= link->request_samples && | |
| 160 | − calc_ptr_alignment(head) >= 32) { | |
| 161 | − if (head->nb_samples == link->request_samples) { | |
| 162 | − out = head; | |
| 163 | − queue_pop(s); | |
| 164 | − } else { | |
| 165 | − out = av_frame_clone(head); | |
| 166 | − if (!out) | |
| 167 | − return AVERROR(ENOMEM); | |
| 168 | − | |
| 169 | − out->nb_samples = link->request_samples; | |
| 170 | − buffer_offset(link, head, link->request_samples); | |
| 171 | − } | |
| 172 | − } else { | |
| 173 | − int nb_channels = link->channels; | |
| 174 | − | |
| 175 | − if (!s->out) { | |
| 176 | − s->out = ff_get_audio_buffer(link, link->request_samples); | |
| 177 | − if (!s->out) | |
| 178 | − return AVERROR(ENOMEM); | |
| 179 | − | |
| 180 | − s->out->nb_samples = 0; | |
| 181 | − s->out->pts = head->pts; | |
| 182 | − s->allocated_samples = link->request_samples; | |
| 183 | − } else if (link->request_samples != s->allocated_samples) { | |
| 184 | − av_log(ctx, AV_LOG_ERROR, "request_samples changed before the " | |
| 185 | − "buffer was returned.\n"); | |
| 186 | − return AVERROR(EINVAL); | |
| 187 | − } | |
| 188 | − | |
| 189 | − while (s->out->nb_samples < s->allocated_samples) { | |
| 190 | − int len; | |
| 191 | − | |
| 192 | − if (!s->root.next) { | |
| 193 | − ret = ff_request_frame(ctx->inputs[0]); | |
| 194 | − if (ret == AVERROR_EOF) { | |
| 195 | − av_samples_set_silence(s->out->extended_data, | |
| 196 | − s->out->nb_samples, | |
| 197 | − s->allocated_samples - | |
| 198 | − s->out->nb_samples, | |
| 199 | − nb_channels, link->format); | |
| 200 | − s->out->nb_samples = s->allocated_samples; | |
| 201 | − break; | |
| 202 | − } else if (ret < 0) | |
| 203 | − return ret; | |
| 204 | − if (!s->root.next) | |
| 205 | − return 0; | |
| 206 | − } | |
| 207 | − head = s->root.next->frame; | |
| 208 | − | |
| 209 | − len = FFMIN(s->allocated_samples - s->out->nb_samples, | |
| 210 | − head->nb_samples); | |
| 211 | − | |
| 212 | − av_samples_copy(s->out->extended_data, head->extended_data, | |
| 213 | − s->out->nb_samples, 0, len, nb_channels, | |
| 214 | − link->format); | |
| 215 | − s->out->nb_samples += len; | |
| 216 | − | |
| 217 | − if (len == head->nb_samples) { | |
| 218 | − av_frame_free(&head); | |
| 219 | − queue_pop(s); | |
| 220 | − } else { | |
| 221 | − buffer_offset(link, head, len); | |
| 222 | − } | |
| 223 | − } | |
| 224 | − out = s->out; | |
| 225 | − s->out = NULL; | |
| 226 | − } | |
| 227 | − return ff_filter_frame(link, out); | |
| 228 | −} | |
| 229 | − | |
| 230 | 146 | static int request_frame(AVFilterLink *outlink) |
| 231 | 147 | { |
| 232 | 148 | FifoContext *s = outlink->src->priv; |
| 233 | 149 | int ret = 0; |
| 234 | 150 | |
| 235 | 151 | if (!s->root.next) { |
| 236 | − if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0) { | |
| 237 | − if (ret == AVERROR_EOF && outlink->request_samples) | |
| 238 | − return return_audio_frame(outlink->src); | |
| 152 | + if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0) | |
| 239 | 153 | return ret; |
| 240 | − } | |
| 241 | 154 | if (!s->root.next) |
| 242 | 155 | return 0; |
| 243 | 156 | } |
| 244 | − | |
| 245 | − if (outlink->request_samples) { | |
| 246 | − return return_audio_frame(outlink->src); | |
| 247 | − } else { | |
| 248 | − ret = ff_filter_frame(outlink, s->root.next->frame); | |
| 249 | − queue_pop(s); | |
| 250 | − } | |
| 251 | − | |
| 157 | + ret = ff_filter_frame(outlink, s->root.next->frame); | |
| 158 | + queue_pop(s); | |
| 252 | 159 | return ret; |
| 253 | 160 | } |
| 254 | 161 | |