aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2022-02-18 16:00:55 +0100
committerPaul B Mahol <onemda@gmail.com>2022-02-18 17:12:46 +0100
commitcca6fe7fe0482d06391fb34858aa9e3d59b590b2 (patch)
treeeda20e410635cf1cfa0fbb9bc71ef6050fc3acdb
parentb40419c99b4ab1588c425cedde11fa820aa74695 (diff)
downloadffmpeg-cca6fe7fe0482d06391fb34858aa9e3d59b590b2.tar.gz
avfilter/vf_xmedian: refactor slice function
-rw-r--r--libavfilter/vf_xmedian.c145
1 files changed, 57 insertions, 88 deletions
diff --git a/libavfilter/vf_xmedian.c b/libavfilter/vf_xmedian.c
index f9dc0f7ecf..28d8e6d4e9 100644
--- a/libavfilter/vf_xmedian.c
+++ b/libavfilter/vf_xmedian.c
@@ -45,7 +45,7 @@ typedef struct XMedianContext {
int depth;
int max;
int nb_planes;
- int linesize[4];
+ int linesizes[4];
int width[4];
int height[4];
@@ -107,101 +107,70 @@ typedef struct ThreadData {
AVFrame **in, *out;
} ThreadData;
-static int comparei(const void *p1, const void *p2)
+static int compare8(const void *p1, const void *p2)
{
- int left = *(const int *)p1;
- int right = *(const int *)p2;
+ int left = *(const uint8_t *)p1;
+ int right = *(const uint8_t *)p2;
return FFDIFFSIGN(left, right);
}
-static int median_frames16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+static int compare16(const void *p1, const void *p2)
{
- XMedianContext *s = ctx->priv;
- ThreadData *td = arg;
- AVFrame **in = td->in;
- AVFrame *out = td->out;
- const int nb_inputs = s->nb_inputs;
- const int radius = s->radius;
- const int index = s->index;
- int values[256];
-
- for (int p = 0; p < s->nb_planes; p++) {
- const int slice_start = (s->height[p] * jobnr) / nb_jobs;
- const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
- uint16_t *dst = (uint16_t *)(out->data[p] + slice_start * out->linesize[p]);
-
- if (!((1 << p) & s->planes)) {
- av_image_copy_plane((uint8_t *)dst, out->linesize[p],
- in[radius]->data[p] + slice_start * in[radius]->linesize[p],
- in[radius]->linesize[p],
- s->linesize[p], slice_end - slice_start);
- continue;
- }
-
- for (int y = slice_start; y < slice_end; y++) {
- for (int x = 0; x < s->width[p]; x++) {
- for (int i = 0; i < nb_inputs; i++) {
- const uint16_t *src = (const uint16_t *)(in[i]->data[p] + y * in[i]->linesize[p]);
- values[i] = src[x];
- }
-
- AV_QSORT(values, nb_inputs, int, comparei);
- if (nb_inputs & 1)
- dst[x] = values[index];
- else
- dst[x] = (values[index] + values[index - 1]) >> 1;
- }
-
- dst += out->linesize[p] / 2;
- }
- }
-
- return 0;
+ int left = *(const uint16_t *)p1;
+ int right = *(const uint16_t *)p2;
+ return FFDIFFSIGN(left, right);
}
-static int median_frames8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
-{
- XMedianContext *s = ctx->priv;
- ThreadData *td = arg;
- AVFrame **in = td->in;
- AVFrame *out = td->out;
- const int nb_inputs = s->nb_inputs;
- const int radius = s->radius;
- const int index = s->index;
- int values[256];
-
- for (int p = 0; p < s->nb_planes; p++) {
- const int slice_start = (s->height[p] * jobnr) / nb_jobs;
- const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
- uint8_t *dst = out->data[p] + slice_start * out->linesize[p];
-
- if (!((1 << p) & s->planes)) {
- av_image_copy_plane(dst, out->linesize[p],
- in[radius]->data[p] + slice_start * in[radius]->linesize[p],
- in[radius]->linesize[p],
- s->linesize[p], slice_end - slice_start);
- continue;
- }
-
- for (int y = slice_start; y < slice_end; y++) {
- for (int x = 0; x < s->width[p]; x++) {
- for (int i = 0; i < nb_inputs; i++)
- values[i] = in[i]->data[p][y * in[i]->linesize[p] + x];
-
- AV_QSORT(values, nb_inputs, int, comparei);
- if (nb_inputs & 1)
- dst[x] = values[index];
- else
- dst[x] = (values[index] + values[index - 1]) >> 1;
- }
-
- dst += out->linesize[p];
- }
- }
-
- return 0;
+#define MEDIAN_SLICE(name, type, comparei) \
+static int median_frames ## name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
+{ \
+ XMedianContext *s = ctx->priv; \
+ ThreadData *td = arg; \
+ AVFrame **in = td->in; \
+ AVFrame *out = td->out; \
+ const int nb_inputs = s->nb_inputs; \
+ const int radius = s->radius; \
+ const int index = s->index; \
+ type values[256]; \
+ \
+ for (int p = 0; p < s->nb_planes; p++) { \
+ const int slice_start = (s->height[p] * jobnr) / nb_jobs; \
+ const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs; \
+ type *dst = (type *)(out->data[p] + slice_start * out->linesize[p]); \
+ ptrdiff_t dst_linesize = out->linesize[p] / sizeof(type); \
+ \
+ if (!((1 << p) & s->planes)) { \
+ av_image_copy_plane((uint8_t *)dst, out->linesize[p], \
+ in[radius]->data[p] + slice_start * in[radius]->linesize[p], \
+ in[radius]->linesize[p], \
+ s->linesizes[p], slice_end - slice_start); \
+ continue; \
+ } \
+ \
+ for (int y = slice_start; y < slice_end; y++) { \
+ for (int x = 0; x < s->width[p]; x++) { \
+ for (int i = 0; i < nb_inputs; i++) { \
+ const type *src = (const type *)(in[i]->data[p] + y * in[i]->linesize[p]); \
+ values[i] = src[x]; \
+ } \
+ \
+ AV_QSORT(values, nb_inputs, type, comparei); \
+ if (nb_inputs & 1) \
+ dst[x] = values[index]; \
+ else \
+ dst[x] = (values[index] + values[index - 1]) >> 1; \
+ } \
+ \
+ dst += dst_linesize; \
+ } \
+ } \
+ \
+ return 0; \
}
+MEDIAN_SLICE(8, uint8_t, compare8)
+MEDIAN_SLICE(16, uint16_t, compare16)
+
static int process_frame(FFFrameSync *fs)
{
AVFilterContext *ctx = fs->parent;
@@ -267,7 +236,7 @@ static int config_output(AVFilterLink *outlink)
else
s->median_frames = median_frames16;
- if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
+ if ((ret = av_image_fill_linesizes(s->linesizes, inlink->format, inlink->w)) < 0)
return ret;
s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, s->desc->log2_chroma_w);