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 | 1235 | frame = ff_framequeue_peek(&link->fifo, 0); |
| 1236 | 1236 | av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n, |
| 1237 | 1237 | link->channels, link->format); |
| 1238 | − frame->nb_samples -= n; | |
| 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); | |
| 1238 | + ff_framequeue_skip_samples(&link->fifo, n, link->time_base); | |
| 1245 | 1239 | } |
| 1246 | 1240 | |
| 1247 | 1241 | *rframe = buf; |
| @@ -121,3 +121,30 @@ AVFrame *ff_framequeue_peek(FFFrameQueue *fq, size_t idx) · 120 unmodified lines | ||
| 121 | 121 | check_consistency(fq); |
| 122 | 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 | 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) | |
| 170 | −{ | |
| 171 | − fq->total_samples_tail += n; | |
| 172 | −} | |
| 171 | +void ff_framequeue_skip_samples(FFFrameQueue *fq, size_t samples, AVRational time_base); | |
| 173 | 172 | |
| 174 | 173 | #endif /* AVFILTER_FRAMEQUEUE_H */ |