FFmpeg
signature_lookup.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Gerion Entrup
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 /**
22  * @file
23  * MPEG-7 video signature calculation and lookup filter
24  */
25 
26 #include "signature.h"
27 
28 #define HOUGH_MAX_OFFSET 90
29 #define MAX_FRAMERATE 60
30 
31 #define DIR_PREV 0
32 #define DIR_NEXT 1
33 #define DIR_PREV_END 2
34 #define DIR_NEXT_END 3
35 
36 #define STATUS_NULL 0
37 #define STATUS_END_REACHED 1
38 #define STATUS_BEGIN_REACHED 2
39 
40 static void sll_free(MatchingInfo **sll)
41 {
42  while (*sll) {
43  MatchingInfo *tmp = *sll;
44  *sll = tmp->next;
45  tmp->next = NULL;
46  av_free(tmp);
47  }
48 }
49 
50 static void fill_l1distlut(uint8_t lut[])
51 {
52  int i, j, tmp_i, tmp_j,count;
53  uint8_t dist;
54 
55  for (i = 0, count = 0; i < 242; i++) {
56  for (j = i + 1; j < 243; j++, count++) {
57  /* ternary distance between i and j */
58  dist = 0;
59  tmp_i = i; tmp_j = j;
60  do {
61  dist += FFABS((tmp_j % 3) - (tmp_i % 3));
62  tmp_j /= 3;
63  tmp_i /= 3;
64  } while (tmp_i > 0 || tmp_j > 0);
65  lut[count] = dist;
66  }
67  }
68 }
69 
70 static unsigned int intersection_word(const uint8_t *first, const uint8_t *second)
71 {
72  unsigned int val=0,i;
73  for (i = 0; i < 28; i += 4) {
74  val += av_popcount( (first[i] & second[i] ) << 24 |
75  (first[i+1] & second[i+1]) << 16 |
76  (first[i+2] & second[i+2]) << 8 |
77  (first[i+3] & second[i+3]) );
78  }
79  val += av_popcount( (first[28] & second[28]) << 16 |
80  (first[29] & second[29]) << 8 |
81  (first[30] & second[30]) );
82  return val;
83 }
84 
85 static unsigned int union_word(const uint8_t *first, const uint8_t *second)
86 {
87  unsigned int val=0,i;
88  for (i = 0; i < 28; i += 4) {
89  val += av_popcount( (first[i] | second[i] ) << 24 |
90  (first[i+1] | second[i+1]) << 16 |
91  (first[i+2] | second[i+2]) << 8 |
92  (first[i+3] | second[i+3]) );
93  }
94  val += av_popcount( (first[28] | second[28]) << 16 |
95  (first[29] | second[29]) << 8 |
96  (first[30] | second[30]) );
97  return val;
98 }
99 
100 static unsigned int get_l1dist(AVFilterContext *ctx, SignatureContext *sc, const uint8_t *first, const uint8_t *second)
101 {
102  unsigned int i;
103  unsigned int dist = 0;
104  uint8_t f, s;
105 
106  for (i = 0; i < SIGELEM_SIZE/5; i++) {
107  if (first[i] != second[i]) {
108  f = first[i];
109  s = second[i];
110  if (f > s) {
111  /* little variation of gauss sum formula */
112  dist += sc->l1distlut[243*242/2 - (243-s)*(242-s)/2 + f - s - 1];
113  } else {
114  dist += sc->l1distlut[243*242/2 - (243-f)*(242-f)/2 + s - f - 1];
115  }
116  }
117  }
118  return dist;
119 }
120 
121 /**
122  * calculates the jaccard distance and evaluates a pair of coarse signatures as good
123  * @return 0 if pair is bad, 1 otherwise
124  */
126 {
127  int jaccarddist, i, composdist = 0, cwthcount = 0;
128  for (i = 0; i < 5; i++) {
129  if ((jaccarddist = intersection_word(first->data[i], second->data[i])) > 0) {
130  jaccarddist /= union_word(first->data[i], second->data[i]);
131  }
132  if (jaccarddist >= sc->thworddist) {
133  if (++cwthcount > 2) {
134  /* more than half (5/2) of distances are too wide */
135  return 0;
136  }
137  }
138  composdist += jaccarddist;
139  if (composdist > sc->thcomposdist) {
140  return 0;
141  }
142  }
143  return 1;
144 }
145 
146 /**
147  * step through the coarsesignatures as long as a good candidate is found
148  * @return 0 if no candidate is found, 1 otherwise
149  */
151 {
152  /* go one coarsesignature foreword */
153  if (!start) {
154  if ((*second)->next) {
155  *second = (*second)->next;
156  } else if ((*first)->next) {
157  *second = secondstart;
158  *first = (*first)->next;
159  } else {
160  return 0;
161  }
162  }
163 
164  while (1) {
165  if (get_jaccarddist(sc, *first, *second))
166  return 1;
167 
168  /* next signature */
169  if ((*second)->next) {
170  *second = (*second)->next;
171  } else if ((*first)->next) {
172  *second = secondstart;
173  *first = (*first)->next;
174  } else {
175  return 0;
176  }
177  }
178 }
179 
180 /**
181  * compares framesignatures and sorts out signatures with a l1 distance above a given threshold.
182  * Then tries to find out offset and differences between framerates with a hough transformation
183  */
185 {
186  FineSignature *f, *s;
187  size_t i, j, k, l, hmax = 0, score;
188  int framerate, offset, l1dist;
189  double m;
190  MatchingInfo cands = { 0 }, *c = &cands;
191 
192  struct {
193  uint8_t size;
194  unsigned int dist;
195  FineSignature *a;
196  uint8_t b_pos[COARSE_SIZE];
198  } pairs[COARSE_SIZE];
199 
200  typedef struct hspace_elem {
201  int dist;
202  size_t score;
203  FineSignature *a;
204  FineSignature *b;
205  } hspace_elem;
206 
207  /* houghspace */
208  hspace_elem **hspace = av_malloc(MAX_FRAMERATE * sizeof(*hspace));
209  hspace_elem *hspaces;
210 
211  if (!hspace)
212  return NULL;
213  /* initialize houghspace */
214  hspaces = av_malloc((2 * HOUGH_MAX_OFFSET + 1) * sizeof(*hspaces) * MAX_FRAMERATE);
215  if (!hspaces)
216  goto error;
217  for (i = 0; i < MAX_FRAMERATE; i++) {
218  hspace[i] = hspaces + i * (2 * HOUGH_MAX_OFFSET + 1);
219  for (j = 0; j < 2 * HOUGH_MAX_OFFSET + 1; j++) {
220  hspace[i][j].score = 0;
221  hspace[i][j].dist = 99999;
222  }
223  }
224 
225  /* l1 distances */
226  for (i = 0, f = first; i < COARSE_SIZE && f->next; i++, f = f->next) {
227  pairs[i].size = 0;
228  pairs[i].dist = 99999;
229  pairs[i].a = f;
230  for (j = 0, s = second; j < COARSE_SIZE && s->next; j++, s = s->next) {
231  /* l1 distance of finesignature */
232  l1dist = get_l1dist(ctx, sc, f->framesig, s->framesig);
233  if (l1dist < sc->thl1) {
234  if (l1dist < pairs[i].dist) {
235  pairs[i].size = 1;
236  pairs[i].dist = l1dist;
237  pairs[i].b_pos[0] = j;
238  pairs[i].b[0] = s;
239  } else if (l1dist == pairs[i].dist) {
240  pairs[i].b[pairs[i].size] = s;
241  pairs[i].b_pos[pairs[i].size] = j;
242  pairs[i].size++;
243  }
244  }
245  }
246  }
247  /* last incomplete coarsesignature */
248  if (f->next == NULL) {
249  for (; i < COARSE_SIZE; i++) {
250  pairs[i].size = 0;
251  pairs[i].dist = 99999;
252  }
253  }
254 
255  /* hough transformation */
256  for (i = 0; i < COARSE_SIZE; i++) {
257  for (j = 0; j < pairs[i].size; j++) {
258  for (k = i + 1; k < COARSE_SIZE; k++) {
259  for (l = 0; l < pairs[k].size; l++) {
260  if (pairs[i].b[j] != pairs[k].b[l]) {
261  /* linear regression */
262  m = (pairs[k].b_pos[l]-pairs[i].b_pos[j]) / (k-i); /* good value between 0.0 - 2.0 */
263  framerate = (int) (m*30 + 0.5); /* round up to 0 - 60 */
264  if (framerate>0 && framerate <= MAX_FRAMERATE) {
265  offset = pairs[i].b_pos[j] - ((int) (m*i + 0.5)); /* only second part has to be rounded up */
267  if (pairs[i].dist < pairs[k].dist) {
268  if (pairs[i].dist < hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) {
269  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist = pairs[i].dist;
270  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].a = pairs[i].a;
271  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].b = pairs[i].b[j];
272  }
273  } else {
274  if (pairs[k].dist < hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) {
275  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist = pairs[k].dist;
276  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].a = pairs[k].a;
277  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].b = pairs[k].b[l];
278  }
279  }
280 
281  score = hspace[framerate-1][offset+HOUGH_MAX_OFFSET].score + 1;
282  if (score > hmax )
283  hmax = score;
284  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].score = score;
285  }
286  }
287  }
288  }
289  }
290  }
291  }
292 
293  if (hmax > 0) {
294  hmax = (int) (0.7*hmax);
295  for (i = 0; i < MAX_FRAMERATE; i++) {
296  for (j = 0; j < HOUGH_MAX_OFFSET; j++) {
297  if (hmax < hspace[i][j].score) {
298  c->next = av_malloc(sizeof(MatchingInfo));
299  c = c->next;
300  if (!c) {
301  sll_free(&cands.next);
302  goto error;
303  }
304  c->framerateratio = (i+1.0) / 30;
305  c->score = hspace[i][j].score;
306  c->offset = j-90;
307  c->first = hspace[i][j].a;
308  c->second = hspace[i][j].b;
309  c->next = NULL;
310 
311  /* not used */
312  c->meandist = 0;
313  c->matchframes = 0;
314  c->whole = 0;
315  }
316  }
317  }
318  }
319  error:
320  av_freep(&hspace);
321  av_free(hspaces);
322  return cands.next;
323 }
324 
325 static int iterate_frame(double frr, FineSignature **a, FineSignature **b, int fcount, int *bcount, int dir)
326 {
327  int step;
328 
329  /* between 1 and 2, because frr is between 1 and 2 */
330  step = ((int) 0.5 + fcount * frr) /* current frame */
331  -((int) 0.5 + (fcount-1) * frr);/* last frame */
332 
333  if (dir == DIR_NEXT) {
334  if (frr >= 1.0) {
335  if ((*a)->next) {
336  *a = (*a)->next;
337  } else {
338  return DIR_NEXT_END;
339  }
340 
341  if (step == 1) {
342  if ((*b)->next) {
343  *b = (*b)->next;
344  (*bcount)++;
345  } else {
346  return DIR_NEXT_END;
347  }
348  } else {
349  if ((*b)->next && (*b)->next->next) {
350  *b = (*b)->next->next;
351  (*bcount)++;
352  } else {
353  return DIR_NEXT_END;
354  }
355  }
356  } else {
357  if ((*b)->next) {
358  *b = (*b)->next;
359  (*bcount)++;
360  } else {
361  return DIR_NEXT_END;
362  }
363 
364  if (step == 1) {
365  if ((*a)->next) {
366  *a = (*a)->next;
367  } else {
368  return DIR_NEXT_END;
369  }
370  } else {
371  if ((*a)->next && (*a)->next->next) {
372  *a = (*a)->next->next;
373  } else {
374  return DIR_NEXT_END;
375  }
376  }
377  }
378  return DIR_NEXT;
379  } else {
380  if (frr >= 1.0) {
381  if ((*a)->prev) {
382  *a = (*a)->prev;
383  } else {
384  return DIR_PREV_END;
385  }
386 
387  if (step == 1) {
388  if ((*b)->prev) {
389  *b = (*b)->prev;
390  (*bcount)++;
391  } else {
392  return DIR_PREV_END;
393  }
394  } else {
395  if ((*b)->prev && (*b)->prev->prev) {
396  *b = (*b)->prev->prev;
397  (*bcount)++;
398  } else {
399  return DIR_PREV_END;
400  }
401  }
402  } else {
403  if ((*b)->prev) {
404  *b = (*b)->prev;
405  (*bcount)++;
406  } else {
407  return DIR_PREV_END;
408  }
409 
410  if (step == 1) {
411  if ((*a)->prev) {
412  *a = (*a)->prev;
413  } else {
414  return DIR_PREV_END;
415  }
416  } else {
417  if ((*a)->prev && (*a)->prev->prev) {
418  *a = (*a)->prev->prev;
419  } else {
420  return DIR_PREV_END;
421  }
422  }
423  }
424  return DIR_PREV;
425  }
426 }
427 
429 {
430  int dist, distsum = 0, bcount = 1, dir = DIR_NEXT;
431  int fcount = 0, goodfcount = 0, gooda = 0, goodb = 0;
432  double meandist, minmeandist = bestmatch.meandist;
433  int tolerancecount = 0;
434  FineSignature *a, *b, *aprev, *bprev;
435  int status = STATUS_NULL;
436 
437  for (; infos != NULL; infos = infos->next) {
438  a = infos->first;
439  b = infos->second;
440  while (1) {
441  dist = get_l1dist(ctx, sc, a->framesig, b->framesig);
442 
443  if (dist > sc->thl1) {
444  if (a->confidence >= 1 || b->confidence >= 1) {
445  /* bad frame (because high different information) */
446  tolerancecount++;
447  }
448 
449  if (tolerancecount > 2) {
450  a = aprev;
451  b = bprev;
452  if (dir == DIR_NEXT) {
453  /* turn around */
454  a = infos->first;
455  b = infos->second;
456  dir = DIR_PREV;
457  } else {
458  break;
459  }
460  }
461  } else {
462  /* good frame */
463  distsum += dist;
464  goodfcount++;
465  tolerancecount=0;
466 
467  aprev = a;
468  bprev = b;
469 
470  if (a->confidence < 1) gooda++;
471  if (b->confidence < 1) goodb++;
472  }
473 
474  fcount++;
475 
476  dir = iterate_frame(infos->framerateratio, &a, &b, fcount, &bcount, dir);
477  if (dir == DIR_NEXT_END) {
479  a = infos->first;
480  b = infos->second;
481  dir = iterate_frame(infos->framerateratio, &a, &b, fcount, &bcount, DIR_PREV);
482  }
483 
484  if (dir == DIR_PREV_END) {
486  break;
487  }
488 
489  if (sc->thdi != 0 && bcount >= sc->thdi) {
490  break; /* enough frames found */
491  }
492  }
493 
494  if (bcount < sc->thdi)
495  continue; /* matching sequence is too short */
496  if ((double) goodfcount / (double) fcount < sc->thit)
497  continue;
498  if ((double) goodfcount*0.5 < FFMAX(gooda, goodb))
499  continue;
500 
501  meandist = (double) goodfcount / (double) distsum;
502 
503  if (meandist < minmeandist ||
505  mode == MODE_FAST){
506  minmeandist = meandist;
507  /* bestcandidate in this iteration */
508  bestmatch.meandist = meandist;
509  bestmatch.matchframes = bcount;
510  bestmatch.framerateratio = infos->framerateratio;
511  bestmatch.score = infos->score;
512  bestmatch.offset = infos->offset;
513  bestmatch.first = infos->first;
514  bestmatch.second = infos->second;
515  bestmatch.whole = 0; /* will be set to true later */
516  bestmatch.next = NULL;
517  }
518 
519  /* whole sequence is automatically best match */
521  bestmatch.whole = 1;
522  break;
523  }
524 
525  /* first matching sequence is enough, finding the best one is not necessary */
526  if (mode == MODE_FAST) {
527  break;
528  }
529  }
530  return bestmatch;
531 }
532 
534 {
535  CoarseSignature *cs, *cs2;
536  MatchingInfo *infos;
537  MatchingInfo bestmatch;
538  MatchingInfo *i;
539 
540  cs = first->coarsesiglist;
541  cs2 = second->coarsesiglist;
542 
543  /* score of bestmatch is 0, if no match is found */
544  bestmatch.score = 0;
545  bestmatch.meandist = 99999;
546  bestmatch.whole = 0;
547 
549 
550  /* stage 1: coarsesignature matching */
551  if (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 1) == 0)
552  return bestmatch; /* no candidate found */
553  do {
554  av_log(ctx, AV_LOG_DEBUG, "Stage 1: got coarsesignature pair. "
555  "indices of first frame: %"PRIu32" and %"PRIu32"\n",
556  cs->first->index, cs2->first->index);
557  /* stage 2: l1-distance and hough-transform */
558  av_log(ctx, AV_LOG_DEBUG, "Stage 2: calculate matching parameters\n");
559  infos = get_matching_parameters(ctx, sc, cs->first, cs2->first);
560  if (av_log_get_level() == AV_LOG_DEBUG) {
561  for (i = infos; i != NULL; i = i->next) {
562  av_log(ctx, AV_LOG_DEBUG, "Stage 2: matching pair at %"PRIu32" and %"PRIu32", "
563  "ratio %f, offset %d\n", i->first->index, i->second->index,
564  i->framerateratio, i->offset);
565  }
566  }
567  /* stage 3: evaluation */
568  av_log(ctx, AV_LOG_DEBUG, "Stage 3: evaluate\n");
569  if (infos) {
570  bestmatch = evaluate_parameters(ctx, sc, infos, bestmatch, mode);
571  av_log(ctx, AV_LOG_DEBUG, "Stage 3: best matching pair at %"PRIu32" and %"PRIu32", "
572  "ratio %f, offset %d, score %d, %d frames matching\n",
573  bestmatch.first->index, bestmatch.second->index,
574  bestmatch.framerateratio, bestmatch.offset, bestmatch.score, bestmatch.matchframes);
575  sll_free(&infos);
576  }
577  } while (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 0) && !bestmatch.whole);
578  return bestmatch;
579 
580 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
MatchingInfo::framerateratio
double framerateratio
Definition: signature.h:92
MAX_FRAMERATE
#define MAX_FRAMERATE
Definition: signature_lookup.c:29
StreamContext::coarsesiglist
CoarseSignature * coarsesiglist
Definition: signature.h:114
MatchingInfo::meandist
double meandist
Definition: signature.h:91
MatchingInfo
Definition: signature.h:90
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
COARSE_SIZE
#define COARSE_SIZE
Definition: signature.h:39
MatchingInfo::whole
int whole
Definition: signature.h:96
b
#define b
Definition: input.c:41
MatchingInfo::score
int score
Definition: signature.h:93
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_popcount
#define av_popcount
Definition: common.h:152
SignatureContext::l1distlut
uint8_t l1distlut[243 *242/2]
Definition: signature.h:141
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
FineSignature::index
uint32_t index
Definition: signature.h:76
fill_l1distlut
static void fill_l1distlut(uint8_t lut[])
Definition: signature_lookup.c:50
lookup_signatures
static MatchingInfo lookup_signatures(AVFilterContext *ctx, SignatureContext *sc, StreamContext *first, StreamContext *second, int mode)
Definition: signature_lookup.c:533
val
static double val(void *priv, double ch)
Definition: aeval.c:78
SignatureContext::thdi
int thdi
Definition: signature.h:137
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
evaluate_parameters
static MatchingInfo evaluate_parameters(AVFilterContext *ctx, SignatureContext *sc, MatchingInfo *infos, MatchingInfo bestmatch, int mode)
Definition: signature_lookup.c:428
STATUS_END_REACHED
#define STATUS_END_REACHED
Definition: signature_lookup.c:37
STATUS_NULL
#define STATUS_NULL
Definition: signature_lookup.c:36
MODE_FAST
@ MODE_FAST
Definition: signature.h:44
CoarseSignature::first
struct FineSignature * first
Definition: signature.h:84
s
#define s(width, name)
Definition: cbs_vp9.c:198
SIGELEM_SIZE
#define SIGELEM_SIZE
Definition: signature.h:37
HOUGH_MAX_OFFSET
#define HOUGH_MAX_OFFSET
Definition: signature_lookup.c:28
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
av_log_get_level
int av_log_get_level(void)
Get the current log level.
Definition: log.c:442
framerate
float framerate
Definition: av1_levels.c:29
NULL
#define NULL
Definition: coverity.c:32
signature.h
DIR_PREV
#define DIR_PREV
Definition: signature_lookup.c:31
get_matching_parameters
static MatchingInfo * get_matching_parameters(AVFilterContext *ctx, SignatureContext *sc, FineSignature *first, FineSignature *second)
compares framesignatures and sorts out signatures with a l1 distance above a given threshold.
Definition: signature_lookup.c:184
double
double
Definition: af_crystalizer.c:131
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
MatchingInfo::offset
int offset
Definition: signature.h:94
StreamContext
Definition: transcode.c:53
f
f
Definition: af_crystalizer.c:121
sll_free
static void sll_free(MatchingInfo **sll)
Definition: signature_lookup.c:40
get_jaccarddist
static int get_jaccarddist(SignatureContext *sc, CoarseSignature *first, CoarseSignature *second)
calculates the jaccard distance and evaluates a pair of coarse signatures as good
Definition: signature_lookup.c:125
iterate_frame
static int iterate_frame(double frr, FineSignature **a, FineSignature **b, int fcount, int *bcount, int dir)
Definition: signature_lookup.c:325
size
int size
Definition: twinvq_data.h:10344
union_word
static unsigned int union_word(const uint8_t *first, const uint8_t *second)
Definition: signature_lookup.c:85
DIR_PREV_END
#define DIR_PREV_END
Definition: signature_lookup.c:33
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
DIR_NEXT_END
#define DIR_NEXT_END
Definition: signature_lookup.c:34
SignatureContext::thcomposdist
int thcomposdist
Definition: signature.h:135
get_l1dist
static unsigned int get_l1dist(AVFilterContext *ctx, SignatureContext *sc, const uint8_t *first, const uint8_t *second)
Definition: signature_lookup.c:100
FineSignature
Definition: signature.h:72
SignatureContext
Definition: signature.h:127
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
DIR_NEXT
#define DIR_NEXT
Definition: signature_lookup.c:32
SignatureContext::thl1
int thl1
Definition: signature.h:136
find_next_coarsecandidate
static int find_next_coarsecandidate(SignatureContext *sc, CoarseSignature *secondstart, CoarseSignature **first, CoarseSignature **second, int start)
step through the coarsesignatures as long as a good candidate is found
Definition: signature_lookup.c:150
CoarseSignature::data
uint8_t data[5][31]
Definition: signature.h:83
status
ov_status_e status
Definition: dnn_backend_openvino.c:120
CoarseSignature::next
struct CoarseSignature * next
Definition: signature.h:86
mode
mode
Definition: ebur128.h:83
SignatureContext::thworddist
int thworddist
Definition: signature.h:134
MatchingInfo::second
struct FineSignature * second
Definition: signature.h:98
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
MatchingInfo::next
struct MatchingInfo * next
Definition: signature.h:99
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
MatchingInfo::first
struct FineSignature * first
Definition: signature.h:97
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
intersection_word
static unsigned int intersection_word(const uint8_t *first, const uint8_t *second)
Definition: signature_lookup.c:70
STATUS_BEGIN_REACHED
#define STATUS_BEGIN_REACHED
Definition: signature_lookup.c:38
int
int
Definition: ffmpeg_filter.c:409
CoarseSignature
Definition: signature.h:82
MatchingInfo::matchframes
int matchframes
Definition: signature.h:95