Unified · Split
| @@ -149,6 +149,9 @@ typedef struct BiquadsContext { · 148 unmodified lines | |||
| 149 | ChanCache *cache; | 149 | ChanCache *cache; |
| 150 | int block_align; | 150 | int block_align; |
| 151 | 151 | ||
| 152 | int64_t pts; | ||
| 153 | int nb_samples; | ||
| 154 | |||
| 152 | void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len, | 155 | void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len, |
| 153 | double *i1, double *i2, double *o1, double *o2, | 156 | double *i1, double *i2, double *o1, double *o2, |
| 154 | double b0, double b1, double b2, double a0, double a1, double a2, int *clippings, | 157 | double b0, double b1, double b2, double a0, double a1, double a2, int *clippings, |
| @@ -995,7 +998,6 @@ static int config_filter(AVFilterLink *outlink, int reset) · 840 unmodified lines | |||
| 995 | return AVERROR(ENOMEM); | 998 | return AVERROR(ENOMEM); |
| 996 | av_samples_set_silence(s->block[i]->extended_data, 0, s->block_samples * 2, | 999 | av_samples_set_silence(s->block[i]->extended_data, 0, s->block_samples * 2, |
| 997 | s->block[i]->ch_layout.nb_channels, s->block[i]->format); | 1000 | s->block[i]->ch_layout.nb_channels, s->block[i]->format); |
| 998 | |||
| 999 | } | 1001 | } |
| 1000 | } | 1002 | } |
| 1001 | 1003 | ||
| @@ -1142,6 +1144,7 @@ static int config_output(AVFilterLink *outlink) · 140 unmodified lines | |||
| 1142 | 1144 | ||
| 1143 | typedef struct ThreadData { | 1145 | typedef struct ThreadData { |
| 1144 | AVFrame *in, *out; | 1146 | AVFrame *in, *out; |
| 1147 | int eof; | ||
| 1145 | } ThreadData; | 1148 | } ThreadData; |
| 1146 | 1149 | ||
| 1147 | static void reverse_samples(AVFrame *out, AVFrame *in, int p, | 1150 | static void reverse_samples(AVFrame *out, AVFrame *in, int p, |
| @@ -1194,7 +1197,6 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job · 46 unmodified lines | |||
| 1194 | enum AVChannel channel = av_channel_layout_channel_from_index(&inlink->ch_layout, ch); | 1197 | enum AVChannel channel = av_channel_layout_channel_from_index(&inlink->ch_layout, ch); |
| 1195 | 1198 | ||
| 1196 | if (av_channel_layout_index_from_channel(&s->ch_layout, channel) < 0) { | 1199 | if (av_channel_layout_index_from_channel(&s->ch_layout, channel) < 0) { |
| 1197 | |||
| 1198 | if (buf != out_buf) | 1200 | if (buf != out_buf) |
| 1199 | memcpy(out_buf->extended_data[ch], buf->extended_data[ch], | 1201 | memcpy(out_buf->extended_data[ch], buf->extended_data[ch], |
| 1200 | buf->nb_samples * s->block_align); | 1202 | buf->nb_samples * s->block_align); |
| @@ -1205,9 +1207,14 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job · 4 unmodified lines | |||
| 1205 | s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples, | 1207 | s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples, |
| 1206 | &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2, | 1208 | &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2, |
| 1207 | s->b0, s->b1, s->b2, s->a0, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); | 1209 | s->b0, s->b1, s->b2, s->a0, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); |
| 1210 | } else if (td->eof) { | ||
| 1211 | memcpy(out_buf->extended_data[ch], s->block[1]->extended_data[ch] + s->block_align * s->block_samples, | ||
| 1212 | s->nb_samples * s->block_align); | ||
| 1208 | } else { | 1213 | } else { |
| 1209 | memcpy(s->block[0]->extended_data[ch] + s->block_align * s->block_samples, buf->extended_data[ch], | 1214 | memcpy(s->block[0]->extended_data[ch] + s->block_align * s->block_samples, buf->extended_data[ch], |
| 1210 | buf->nb_samples * s->block_align); | 1215 | buf->nb_samples * s->block_align); |
| 1216 | memset(s->block[0]->extended_data[ch] + s->block_align * (s->block_samples + buf->nb_samples), | ||
| 1217 | 0, (s->block_samples - buf->nb_samples) * s->block_align); | ||
| 1211 | s->filter(s, s->block[0]->extended_data[ch], s->block[1]->extended_data[ch], s->block_samples, | 1218 | s->filter(s, s->block[0]->extended_data[ch], s->block[1]->extended_data[ch], s->block_samples, |
| 1212 | &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2, | 1219 | &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2, |
| 1213 | s->b0, s->b1, s->b2, s->a0, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); | 1220 | s->b0, s->b1, s->b2, s->a0, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); |
| @@ -1220,15 +1227,17 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job · 6 unmodified lines | |||
| 1220 | s->block_samples, | 1227 | s->block_samples, |
| 1221 | &s->cache[ch].ri1, &s->cache[ch].ri2, &s->cache[ch].ro1, &s->cache[ch].ro2, | 1228 | &s->cache[ch].ri1, &s->cache[ch].ri2, &s->cache[ch].ro1, &s->cache[ch].ro2, |
| 1222 | s->b0, s->b1, s->b2, s->a0, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); | 1229 | s->b0, s->b1, s->b2, s->a0, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); |
| 1223 | reverse_samples(s->block[2], s->block[1], ch, 0, 0, s->block_samples * 2); | 1230 | reverse_samples(s->block[2], s->block[1], ch, 0, 0, 2 * s->block_samples); |
| 1224 | s->cache[ch].ri1 = 0.; | 1231 | s->cache[ch].ri1 = 0.; |
| 1225 | s->cache[ch].ri2 = 0.; | 1232 | s->cache[ch].ri2 = 0.; |
| 1226 | s->cache[ch].ro1 = 0.; | 1233 | s->cache[ch].ro1 = 0.; |
| 1227 | s->cache[ch].ro2 = 0.; | 1234 | s->cache[ch].ro2 = 0.; |
| 1228 | s->filter(s, s->block[2]->extended_data[ch], s->block[2]->extended_data[ch], s->block[2]->nb_samples, | 1235 | s->filter(s, s->block[2]->extended_data[ch], s->block[2]->extended_data[ch], 2 * s->block_samples, |
| 1229 | &s->cache[ch].ri1, &s->cache[ch].ri2, &s->cache[ch].ro1, &s->cache[ch].ro2, | 1236 | &s->cache[ch].ri1, &s->cache[ch].ri2, &s->cache[ch].ro1, &s->cache[ch].ro2, |
| 1230 | s->b0, s->b1, s->b2, s->a0, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); | 1237 | s->b0, s->b1, s->b2, s->a0, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); |
| 1231 | reverse_samples(out_buf, s->block[2], ch, 0, s->block_samples, out_buf->nb_samples); | 1238 | reverse_samples(s->block[1], s->block[2], ch, 0, 0, 2 * s->block_samples); |
| 1239 | memcpy(out_buf->extended_data[ch], s->block[1]->extended_data[ch], | ||
| 1240 | s->block_samples * s->block_align); | ||
| 1232 | memmove(s->block[0]->extended_data[ch], s->block[0]->extended_data[ch] + s->block_align * s->block_samples, | 1241 | memmove(s->block[0]->extended_data[ch], s->block[0]->extended_data[ch] + s->block_align * s->block_samples, |
| 1233 | s->block_samples * s->block_align); | 1242 | s->block_samples * s->block_align); |
| 1234 | } | 1243 | } |
| @@ -1237,14 +1246,14 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job · 2 unmodified lines | |||
| 1237 | return 0; | 1246 | return 0; |
| 1238 | } | 1247 | } |
| 1239 | 1248 | ||
| 1240 | static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | 1249 | static int filter_frame(AVFilterLink *inlink, AVFrame *buf, int eof) |
| 1241 | { | 1250 | { |
| 1242 | AVFilterContext *ctx = inlink->dst; | 1251 | AVFilterContext *ctx = inlink->dst; |
| 1243 | BiquadsContext *s = ctx->priv; | 1252 | BiquadsContext *s = ctx->priv; |
| 1244 | AVFilterLink *outlink = ctx->outputs[0]; | 1253 | AVFilterLink *outlink = ctx->outputs[0]; |
| 1245 | AVFrame *out_buf; | 1254 | AVFrame *out_buf; |
| 1246 | ThreadData td; | 1255 | ThreadData td; |
| 1247 | int ch, ret; | 1256 | int ch, ret, drop = 0; |
| 1248 | 1257 | ||
| 1249 | if (s->bypass) | 1258 | if (s->bypass) |
| 1250 | return ff_filter_frame(outlink, buf); | 1259 | return ff_filter_frame(outlink, buf); |
| @@ -1258,10 +1267,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) · 7 unmodified lines | |||
| 1258 | av_channel_layout_from_string(&s->ch_layout, | 1267 | av_channel_layout_from_string(&s->ch_layout, |
| 1259 | s->ch_layout_str); | 1268 | s->ch_layout_str); |
| 1260 | 1269 | ||
| 1261 | if (av_frame_is_writable(buf)) { | 1270 | if (av_frame_is_writable(buf) && s->block_samples == 0) { |
| 1262 | out_buf = buf; | 1271 | out_buf = buf; |
| 1263 | } else { | 1272 | } else { |
| 1264 | out_buf = ff_get_audio_buffer(outlink, buf->nb_samples); | 1273 | out_buf = ff_get_audio_buffer(outlink, s->block_samples > 0 ? s->block_samples : buf->nb_samples); |
| 1265 | if (!out_buf) { | 1274 | if (!out_buf) { |
| 1266 | av_frame_free(&buf); | 1275 | av_frame_free(&buf); |
| 1267 | return AVERROR(ENOMEM); | 1276 | return AVERROR(ENOMEM); |
| @@ -1269,8 +1278,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) · 1 unmodified line | |||
| 1269 | av_frame_copy_props(out_buf, buf); | 1278 | av_frame_copy_props(out_buf, buf); |
| 1270 | } | 1279 | } |
| 1271 | 1280 | ||
| 1281 | if (s->block_samples > 0 && s->pts == AV_NOPTS_VALUE) | ||
| 1282 | drop = 1; | ||
| 1272 | td.in = buf; | 1283 | td.in = buf; |
| 1273 | td.out = out_buf; | 1284 | td.out = out_buf; |
| 1285 | td.eof = eof; | ||
| 1274 | ff_filter_execute(ctx, filter_channel, &td, NULL, | 1286 | ff_filter_execute(ctx, filter_channel, &td, NULL, |
| 1275 | FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | 1287 | FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); |
| 1276 | 1288 | ||
| @@ -1281,10 +1293,26 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) · 4 unmodified lines | |||
| 1281 | s->cache[ch].clippings = 0; | 1293 | s->cache[ch].clippings = 0; |
| 1282 | } | 1294 | } |
| 1283 | 1295 | ||
| 1296 | if (s->block_samples > 0) { | ||
| 1297 | int nb_samples = buf->nb_samples; | ||
| 1298 | int64_t pts = buf->pts; | ||
| 1299 | |||
| 1300 | out_buf->pts = s->pts; | ||
| 1301 | out_buf->nb_samples = s->nb_samples; | ||
| 1302 | s->pts = pts; | ||
| 1303 | s->nb_samples = nb_samples; | ||
| 1304 | } | ||
| 1305 | |||
| 1284 | if (buf != out_buf) | 1306 | if (buf != out_buf) |
| 1285 | av_frame_free(&buf); | 1307 | av_frame_free(&buf); |
| 1286 | 1308 | ||
| 1287 | return ff_filter_frame(outlink, out_buf); | 1309 | if (!drop) |
| 1310 | return ff_filter_frame(outlink, out_buf); | ||
| 1311 | else { | ||
| 1312 | av_frame_free(&out_buf); | ||
| 1313 | ff_filter_set_ready(ctx, 10); | ||
| 1314 | return 0; | ||
| 1315 | } | ||
| 1288 | } | 1316 | } |
| 1289 | 1317 | ||
| 1290 | static int activate(AVFilterContext *ctx) | 1318 | static int activate(AVFilterContext *ctx) |
| @@ -1293,6 +1321,8 @@ static int activate(AVFilterContext *ctx) · 2 unmodified lines | |||
| 1293 | AVFilterLink *outlink = ctx->outputs[0]; | 1321 | AVFilterLink *outlink = ctx->outputs[0]; |
| 1294 | BiquadsContext *s = ctx->priv; | 1322 | BiquadsContext *s = ctx->priv; |
| 1295 | AVFrame *in = NULL; | 1323 | AVFrame *in = NULL; |
| 1324 | int64_t pts; | ||
| 1325 | int status; | ||
| 1296 | int ret; | 1326 | int ret; |
| 1297 | 1327 | ||
| 1298 | FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); | 1328 | FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); |
| @@ -1305,14 +1335,27 @@ static int activate(AVFilterContext *ctx) · 6 unmodified lines | |||
| 1305 | if (ret < 0) | 1335 | if (ret < 0) |
| 1306 | return ret; | 1336 | return ret; |
| 1307 | if (ret > 0) | 1337 | if (ret > 0) |
| 1308 | return filter_frame(inlink, in); | 1338 | return filter_frame(inlink, in, 0); |
| 1309 | 1339 | ||
| 1310 | if (s->block_samples > 0 && ff_inlink_queued_samples(inlink) >= s->block_samples) { | 1340 | if (s->block_samples > 0 && ff_inlink_queued_samples(inlink) >= s->block_samples) { |
| 1311 | ff_filter_set_ready(ctx, 10); | 1341 | ff_filter_set_ready(ctx, 10); |
| 1312 | return 0; | 1342 | return 0; |
| 1313 | } | 1343 | } |
| 1314 | 1344 | ||
| 1315 | FF_FILTER_FORWARD_STATUS(inlink, outlink); | 1345 | if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { |
| 1346 | if (s->block_samples > 0) { | ||
| 1347 | AVFrame *in = ff_get_audio_buffer(outlink, s->block_samples); | ||
| 1348 | if (!in) | ||
| 1349 | return AVERROR(ENOMEM); | ||
| 1350 | |||
| 1351 | ret = filter_frame(inlink, in, 1); | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | ff_outlink_set_status(outlink, status, pts); | ||
| 1355 | |||
| 1356 | return ret; | ||
| 1357 | } | ||
| 1358 | |||
| 1316 | FF_FILTER_FORWARD_WANTED(outlink, inlink); | 1359 | FF_FILTER_FORWARD_WANTED(outlink, inlink); |
| 1317 | 1360 | ||
| 1318 | return FFERROR_NOT_READY; | 1361 | return FFERROR_NOT_READY; |
| @@ -1365,6 +1408,7 @@ static av_cold int name_##_init(AVFilterContext *ctx) \ · 46 unmodified lines | |||
| 1365 | { \ | 1408 | { \ |
| 1366 | BiquadsContext *s = ctx->priv; \ | 1409 | BiquadsContext *s = ctx->priv; \ |
| 1367 | s->filter_type = name_; \ | 1410 | s->filter_type = name_; \ |
| 1411 | s->pts = AV_NOPTS_VALUE; \ | ||
| 1368 | return 0; \ | 1412 | return 0; \ |
| 1369 | } \ | 1413 | } \ |
| 1370 | \ | 1414 | \ |