Instead of just updating statistics and leaving the work to the call site, have it actually do the work.
Showing the changes to libavfilter (3 of 3 files). Show all
Unified · Split
| @@ -1235,13 +1235,7 @@ static int take_samples(AVFilterLink *link, unsigned min, unsigned max, · 1234 unmodified lines | |||
| 1235 | frame = ff_framequeue_peek(&link->fifo, 0); | 1235 | frame = ff_framequeue_peek(&link->fifo, 0); |
| 1236 | av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n, | 1236 | av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n, |
| 1237 | link->channels, link->format); | 1237 | link->channels, link->format); |
| 1238 | frame->nb_samples -= n; | 1238 | ff_framequeue_skip_samples(&link->fifo, n, link->time_base); |
| 1239 | av_samples_copy(frame->extended_data, frame->extended_data, 0, n, | ||
| 1240 | frame->nb_samples, link->channels, link->format); | ||
| 1241 | if (frame->pts != AV_NOPTS_VALUE) | ||
| 1242 | frame->pts += av_rescale_q(n, av_make_q(1, link->sample_rate), link->time_base); | ||
| 1243 | ff_framequeue_update_peeked(&link->fifo, 0); | ||
| 1244 | ff_framequeue_skip_samples(&link->fifo, n); | ||
| 1245 | } | 1239 | } |
| 1246 | 1240 | ||
| 1247 | *rframe = buf; | 1241 | *rframe = buf; |
| @@ -121,3 +121,30 @@ AVFrame *ff_framequeue_peek(FFFrameQueue *fq, size_t idx) · 120 unmodified lines | |||
| 121 | check_consistency(fq); | 121 | check_consistency(fq); |
| 122 | return b->frame; | 122 | return b->frame; |
| 123 | } | 123 | } |
| 124 | |||
| 125 | void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base) | ||
| 126 | { | ||
| 127 | FFFrameBucket *b; | ||
| 128 | size_t bytes; | ||
| 129 | int planar, planes, i; | ||
| 130 | |||
| 131 | check_consistency(fq); | ||
| 132 | av_assert1(fq->queued); | ||
| 133 | b = bucket(fq, 0); | ||
| 134 | av_assert1(samples < b->frame->nb_samples); | ||
| 135 | planar = av_sample_fmt_is_planar(b->frame->format); | ||
| 136 | planes = planar ? b->frame->channels : 1; | ||
| 137 | bytes = samples * av_get_bytes_per_sample(b->frame->format); | ||
| 138 | if (!planar) | ||
| 139 | bytes *= b->frame->channels; | ||
| 140 | if (b->frame->pts != AV_NOPTS_VALUE) | ||
| 141 | b->frame->pts += av_rescale_q(samples, av_make_q(1, b->frame->sample_rate), time_base); | ||
| 142 | b->frame->nb_samples -= samples; | ||
| 143 | b->frame->linesize[0] -= bytes; | ||
| 144 | for (i = 0; i < planes; i++) | ||
| 145 | b->frame->extended_data[i] += bytes; | ||
| 146 | for (i = 0; i < planes && i < AV_NUM_DATA_POINTERS; i++) | ||
| 147 | b->frame->data[i] = b->frame->extended_data[i]; | ||
| 148 | fq->total_samples_tail += samples; | ||
| 149 | ff_framequeue_update_peeked(fq, 0); | ||
| 150 | } | ||
| @@ -161,14 +161,13 @@ static inline void ff_framequeue_update_peeked(FFFrameQueue *fq, size_t idx) · 160 unmodified lines | |||
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | /** | 163 | /** |
| 164 | * Update the sample count in the queue. | 164 | * Skip samples from the first frame in the queue. |
| 165 | * | 165 | * |
| 166 | * This function must be used when the first frame was accessed using | 166 | * This function must be used when the first frame was accessed using |
| 167 | * ff_framequeue_peek() and samples were removed from it. | 167 | * ff_framequeue_peek() and samples were consumed from it. |
| 168 | * It adapts the data pointers and timestamps of the head frame to account | ||
| 169 | * for the skipped samples. | ||
| 168 | */ | 170 | */ |
| 169 | static inline void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t n) | 171 | void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base); |
| 170 | { | ||
| 171 | fq->total_samples_tail += n; | ||
| 172 | } | ||
| 173 | 172 | ||
| 174 | #endif /* AVFILTER_FRAMEQUEUE_H */ | 173 | #endif /* AVFILTER_FRAMEQUEUE_H */ |