X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Ff_reverse.c;h=1e27264dd6204ad762437ca8844a767e77991c2d;hb=0c820b15254f9b9b3d2e29347e329b719f0e001c;hp=5bf71b38edb68db5e10625400d94ed46b25a7bab;hpb=aebc5b2284db1f40a5b3e2e9a2bf406f606436c7;p=ffmpeg diff --git a/libavfilter/f_reverse.c b/libavfilter/f_reverse.c index 5bf71b38edb..1e27264dd62 100644 --- a/libavfilter/f_reverse.c +++ b/libavfilter/f_reverse.c @@ -58,6 +58,11 @@ static av_cold void uninit(AVFilterContext *ctx) { ReverseContext *s = ctx->priv; + while (s->nb_frames > 0) { + av_frame_free(&s->frames[s->nb_frames - 1]); + s->nb_frames--; + } + av_freep(&s->pts); av_freep(&s->frames); } @@ -103,6 +108,7 @@ static int request_frame(AVFilterLink *outlink) AVFrame *out = s->frames[s->nb_frames - 1]; out->pts = s->pts[s->flush_idx++]; ret = ff_filter_frame(outlink, out); + s->frames[s->nb_frames - 1] = NULL; s->nb_frames--; } @@ -154,7 +160,7 @@ static int query_formats(AVFilterContext *ctx) if (ret < 0) return ret; - ret = ff_set_common_formats(ctx, ff_planar_sample_fmts()); + ret = ff_set_common_formats(ctx, ff_all_formats(AVMEDIA_TYPE_AUDIO)); if (ret < 0) return ret; @@ -164,11 +170,92 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_samplerates(ctx, formats); } +static void reverse_samples_planar(AVFrame *out) +{ + for (int p = 0; p < out->channels; p++) { + switch (out->format) { + case AV_SAMPLE_FMT_U8P: { + uint8_t *dst = (uint8_t *)out->extended_data[p]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(uint8_t, dst[i], dst[j]); + } + break; + case AV_SAMPLE_FMT_S16P: { + int16_t *dst = (int16_t *)out->extended_data[p]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(int16_t, dst[i], dst[j]); + } + break; + case AV_SAMPLE_FMT_S32P: { + int32_t *dst = (int32_t *)out->extended_data[p]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(int32_t, dst[i], dst[j]); + } + break; + case AV_SAMPLE_FMT_FLTP: { + float *dst = (float *)out->extended_data[p]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(float, dst[i], dst[j]); + } + break; + case AV_SAMPLE_FMT_DBLP: { + double *dst = (double *)out->extended_data[p]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + FFSWAP(double, dst[i], dst[j]); + } + break; + } + } +} + +static void reverse_samples_packed(AVFrame *out) +{ + const int channels = out->channels; + + switch (out->format) { + case AV_SAMPLE_FMT_U8: { + uint8_t *dst = (uint8_t *)out->extended_data[0]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + for (int p = 0; p < channels; p++) + FFSWAP(uint8_t, dst[i * channels + p], dst[j * channels + p]); + } + break; + case AV_SAMPLE_FMT_S16: { + int16_t *dst = (int16_t *)out->extended_data[0]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + for (int p = 0; p < channels; p++) + FFSWAP(int16_t, dst[i * channels + p], dst[j * channels + p]); + } + break; + case AV_SAMPLE_FMT_S32: { + int32_t *dst = (int32_t *)out->extended_data[0]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + for (int p = 0; p < channels; p++) + FFSWAP(int32_t, dst[i * channels + p], dst[j * channels + p]); + } + break; + case AV_SAMPLE_FMT_FLT: { + float *dst = (float *)out->extended_data[0]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + for (int p = 0; p < channels; p++) + FFSWAP(float, dst[i * channels + p], dst[j * channels + p]); + } + break; + case AV_SAMPLE_FMT_DBL: { + double *dst = (double *)out->extended_data[0]; + for (int i = 0, j = out->nb_samples - 1; i < j; i++, j--) + for (int p = 0; p < channels; p++) + FFSWAP(double, dst[i * channels + p], dst[j * channels + p]); + } + break; + } +} + static int areverse_request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; ReverseContext *s = ctx->priv; - int ret, p, i, j; + int ret; ret = ff_request_frame(ctx->inputs[0]); @@ -176,42 +263,12 @@ static int areverse_request_frame(AVFilterLink *outlink) AVFrame *out = s->frames[s->nb_frames - 1]; out->pts = s->pts[s->flush_idx++]; - for (p = 0; p < outlink->channels; p++) { - switch (outlink->format) { - case AV_SAMPLE_FMT_U8P: { - uint8_t *dst = (uint8_t *)out->extended_data[p]; - for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) - FFSWAP(uint8_t, dst[i], dst[j]); - } - break; - case AV_SAMPLE_FMT_S16P: { - int16_t *dst = (int16_t *)out->extended_data[p]; - for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) - FFSWAP(int16_t, dst[i], dst[j]); - } - break; - case AV_SAMPLE_FMT_S32P: { - int32_t *dst = (int32_t *)out->extended_data[p]; - for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) - FFSWAP(int32_t, dst[i], dst[j]); - } - break; - case AV_SAMPLE_FMT_FLTP: { - float *dst = (float *)out->extended_data[p]; - for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) - FFSWAP(float, dst[i], dst[j]); - } - break; - case AV_SAMPLE_FMT_DBLP: { - double *dst = (double *)out->extended_data[p]; - for (i = 0, j = out->nb_samples - 1; i < j; i++, j--) - FFSWAP(double, dst[i], dst[j]); - } - break; - } - } - + if (av_sample_fmt_is_planar(out->format)) + reverse_samples_planar(out); + else + reverse_samples_packed(out); ret = ff_filter_frame(outlink, out); + s->frames[s->nb_frames - 1] = NULL; s->nb_frames--; }