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 = NULL, *c = NULL;
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_array(MAX_FRAMERATE, sizeof(hspace_elem *));
209 
210  /* initialize houghspace */
211  for (i = 0; i < MAX_FRAMERATE; i++) {
212  hspace[i] = av_malloc_array(2 * HOUGH_MAX_OFFSET + 1, sizeof(hspace_elem));
213  for (j = 0; j < 2 * HOUGH_MAX_OFFSET + 1; j++) {
214  hspace[i][j].score = 0;
215  hspace[i][j].dist = 99999;
216  }
217  }
218 
219  /* l1 distances */
220  for (i = 0, f = first; i < COARSE_SIZE && f->next; i++, f = f->next) {
221  pairs[i].size = 0;
222  pairs[i].dist = 99999;
223  pairs[i].a = f;
224  for (j = 0, s = second; j < COARSE_SIZE && s->next; j++, s = s->next) {
225  /* l1 distance of finesignature */
226  l1dist = get_l1dist(ctx, sc, f->framesig, s->framesig);
227  if (l1dist < sc->thl1) {
228  if (l1dist < pairs[i].dist) {
229  pairs[i].size = 1;
230  pairs[i].dist = l1dist;
231  pairs[i].b_pos[0] = j;
232  pairs[i].b[0] = s;
233  } else if (l1dist == pairs[i].dist) {
234  pairs[i].b[pairs[i].size] = s;
235  pairs[i].b_pos[pairs[i].size] = j;
236  pairs[i].size++;
237  }
238  }
239  }
240  }
241  /* last incomplete coarsesignature */
242  if (f->next == NULL) {
243  for (; i < COARSE_SIZE; i++) {
244  pairs[i].size = 0;
245  pairs[i].dist = 99999;
246  }
247  }
248 
249  /* hough transformation */
250  for (i = 0; i < COARSE_SIZE; i++) {
251  for (j = 0; j < pairs[i].size; j++) {
252  for (k = i + 1; k < COARSE_SIZE; k++) {
253  for (l = 0; l < pairs[k].size; l++) {
254  if (pairs[i].b[j] != pairs[k].b[l]) {
255  /* linear regression */
256  m = (pairs[k].b_pos[l]-pairs[i].b_pos[j]) / (k-i); /* good value between 0.0 - 2.0 */
257  framerate = (int) (m*30 + 0.5); /* round up to 0 - 60 */
258  if (framerate>0 && framerate <= MAX_FRAMERATE) {
259  offset = pairs[i].b_pos[j] - ((int) (m*i + 0.5)); /* only second part has to be rounded up */
261  if (pairs[i].dist < pairs[k].dist) {
262  if (pairs[i].dist < hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) {
263  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist = pairs[i].dist;
264  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].a = pairs[i].a;
265  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].b = pairs[i].b[j];
266  }
267  } else {
268  if (pairs[k].dist < hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) {
269  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist = pairs[k].dist;
270  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].a = pairs[k].a;
271  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].b = pairs[k].b[l];
272  }
273  }
274 
275  score = hspace[framerate-1][offset+HOUGH_MAX_OFFSET].score + 1;
276  if (score > hmax )
277  hmax = score;
278  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].score = score;
279  }
280  }
281  }
282  }
283  }
284  }
285  }
286 
287  if (hmax > 0) {
288  hmax = (int) (0.7*hmax);
289  for (i = 0; i < MAX_FRAMERATE; i++) {
290  for (j = 0; j < HOUGH_MAX_OFFSET; j++) {
291  if (hmax < hspace[i][j].score) {
292  if (c == NULL) {
293  c = av_malloc(sizeof(MatchingInfo));
294  if (!c)
295  av_log(ctx, AV_LOG_FATAL, "Could not allocate memory");
296  cands = c;
297  } else {
298  c->next = av_malloc(sizeof(MatchingInfo));
299  if (!c->next)
300  av_log(ctx, AV_LOG_FATAL, "Could not allocate memory");
301  c = c->next;
302 
303  }
304  if (!c) {
305  sll_free(&cands);
306  goto error;
307  }
308  c->framerateratio = (i+1.0) / 30;
309  c->score = hspace[i][j].score;
310  c->offset = j-90;
311  c->first = hspace[i][j].a;
312  c->second = hspace[i][j].b;
313  c->next = NULL;
314 
315  /* not used */
316  c->meandist = 0;
317  c->matchframes = 0;
318  c->whole = 0;
319  }
320  }
321  }
322  }
323  error:
324  for (i = 0; i < MAX_FRAMERATE; i++) {
325  av_freep(&hspace[i]);
326  }
327  av_freep(&hspace);
328  return cands;
329 }
330 
331 static int iterate_frame(double frr, FineSignature **a, FineSignature **b, int fcount, int *bcount, int dir)
332 {
333  int step;
334 
335  /* between 1 and 2, because frr is between 1 and 2 */
336  step = ((int) 0.5 + fcount * frr) /* current frame */
337  -((int) 0.5 + (fcount-1) * frr);/* last frame */
338 
339  if (dir == DIR_NEXT) {
340  if (frr >= 1.0) {
341  if ((*a)->next) {
342  *a = (*a)->next;
343  } else {
344  return DIR_NEXT_END;
345  }
346 
347  if (step == 1) {
348  if ((*b)->next) {
349  *b = (*b)->next;
350  (*bcount)++;
351  } else {
352  return DIR_NEXT_END;
353  }
354  } else {
355  if ((*b)->next && (*b)->next->next) {
356  *b = (*b)->next->next;
357  (*bcount)++;
358  } else {
359  return DIR_NEXT_END;
360  }
361  }
362  } else {
363  if ((*b)->next) {
364  *b = (*b)->next;
365  (*bcount)++;
366  } else {
367  return DIR_NEXT_END;
368  }
369 
370  if (step == 1) {
371  if ((*a)->next) {
372  *a = (*a)->next;
373  } else {
374  return DIR_NEXT_END;
375  }
376  } else {
377  if ((*a)->next && (*a)->next->next) {
378  *a = (*a)->next->next;
379  } else {
380  return DIR_NEXT_END;
381  }
382  }
383  }
384  return DIR_NEXT;
385  } else {
386  if (frr >= 1.0) {
387  if ((*a)->prev) {
388  *a = (*a)->prev;
389  } else {
390  return DIR_PREV_END;
391  }
392 
393  if (step == 1) {
394  if ((*b)->prev) {
395  *b = (*b)->prev;
396  (*bcount)++;
397  } else {
398  return DIR_PREV_END;
399  }
400  } else {
401  if ((*b)->prev && (*b)->prev->prev) {
402  *b = (*b)->prev->prev;
403  (*bcount)++;
404  } else {
405  return DIR_PREV_END;
406  }
407  }
408  } else {
409  if ((*b)->prev) {
410  *b = (*b)->prev;
411  (*bcount)++;
412  } else {
413  return DIR_PREV_END;
414  }
415 
416  if (step == 1) {
417  if ((*a)->prev) {
418  *a = (*a)->prev;
419  } else {
420  return DIR_PREV_END;
421  }
422  } else {
423  if ((*a)->prev && (*a)->prev->prev) {
424  *a = (*a)->prev->prev;
425  } else {
426  return DIR_PREV_END;
427  }
428  }
429  }
430  return DIR_PREV;
431  }
432 }
433 
435 {
436  int dist, distsum = 0, bcount = 1, dir = DIR_NEXT;
437  int fcount = 0, goodfcount = 0, gooda = 0, goodb = 0;
438  double meandist, minmeandist = bestmatch.meandist;
439  int tolerancecount = 0;
440  FineSignature *a, *b, *aprev, *bprev;
441  int status = STATUS_NULL;
442 
443  for (; infos != NULL; infos = infos->next) {
444  a = infos->first;
445  b = infos->second;
446  while (1) {
447  dist = get_l1dist(ctx, sc, a->framesig, b->framesig);
448 
449  if (dist > sc->thl1) {
450  if (a->confidence >= 1 || b->confidence >= 1) {
451  /* bad frame (because high different information) */
452  tolerancecount++;
453  }
454 
455  if (tolerancecount > 2) {
456  a = aprev;
457  b = bprev;
458  if (dir == DIR_NEXT) {
459  /* turn around */
460  a = infos->first;
461  b = infos->second;
462  dir = DIR_PREV;
463  } else {
464  break;
465  }
466  }
467  } else {
468  /* good frame */
469  distsum += dist;
470  goodfcount++;
471  tolerancecount=0;
472 
473  aprev = a;
474  bprev = b;
475 
476  if (a->confidence < 1) gooda++;
477  if (b->confidence < 1) goodb++;
478  }
479 
480  fcount++;
481 
482  dir = iterate_frame(infos->framerateratio, &a, &b, fcount, &bcount, dir);
483  if (dir == DIR_NEXT_END) {
485  a = infos->first;
486  b = infos->second;
487  dir = iterate_frame(infos->framerateratio, &a, &b, fcount, &bcount, DIR_PREV);
488  }
489 
490  if (dir == DIR_PREV_END) {
492  break;
493  }
494 
495  if (sc->thdi != 0 && bcount >= sc->thdi) {
496  break; /* enough frames found */
497  }
498  }
499 
500  if (bcount < sc->thdi)
501  continue; /* matching sequence is too short */
502  if ((double) goodfcount / (double) fcount < sc->thit)
503  continue;
504  if ((double) goodfcount*0.5 < FFMAX(gooda, goodb))
505  continue;
506 
507  meandist = (double) goodfcount / (double) distsum;
508 
509  if (meandist < minmeandist ||
511  mode == MODE_FAST){
512  minmeandist = meandist;
513  /* bestcandidate in this iteration */
514  bestmatch.meandist = meandist;
515  bestmatch.matchframes = bcount;
516  bestmatch.framerateratio = infos->framerateratio;
517  bestmatch.score = infos->score;
518  bestmatch.offset = infos->offset;
519  bestmatch.first = infos->first;
520  bestmatch.second = infos->second;
521  bestmatch.whole = 0; /* will be set to true later */
522  bestmatch.next = NULL;
523  }
524 
525  /* whole sequence is automatically best match */
527  bestmatch.whole = 1;
528  break;
529  }
530 
531  /* first matching sequence is enough, finding the best one is not necessary */
532  if (mode == MODE_FAST) {
533  break;
534  }
535  }
536  return bestmatch;
537 }
538 
540 {
541  CoarseSignature *cs, *cs2;
542  MatchingInfo *infos;
543  MatchingInfo bestmatch;
544  MatchingInfo *i;
545 
546  cs = first->coarsesiglist;
547  cs2 = second->coarsesiglist;
548 
549  /* score of bestmatch is 0, if no match is found */
550  bestmatch.score = 0;
551  bestmatch.meandist = 99999;
552  bestmatch.whole = 0;
553 
555 
556  /* stage 1: coarsesignature matching */
557  if (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 1) == 0)
558  return bestmatch; /* no candidate found */
559  do {
560  av_log(ctx, AV_LOG_DEBUG, "Stage 1: got coarsesignature pair. "
561  "indices of first frame: %"PRIu32" and %"PRIu32"\n",
562  cs->first->index, cs2->first->index);
563  /* stage 2: l1-distance and hough-transform */
564  av_log(ctx, AV_LOG_DEBUG, "Stage 2: calculate matching parameters\n");
565  infos = get_matching_parameters(ctx, sc, cs->first, cs2->first);
566  if (av_log_get_level() == AV_LOG_DEBUG) {
567  for (i = infos; i != NULL; i = i->next) {
568  av_log(ctx, AV_LOG_DEBUG, "Stage 2: matching pair at %"PRIu32" and %"PRIu32", "
569  "ratio %f, offset %d\n", i->first->index, i->second->index,
570  i->framerateratio, i->offset);
571  }
572  }
573  /* stage 3: evaluation */
574  av_log(ctx, AV_LOG_DEBUG, "Stage 3: evaluate\n");
575  if (infos) {
576  bestmatch = evaluate_parameters(ctx, sc, infos, bestmatch, mode);
577  av_log(ctx, AV_LOG_DEBUG, "Stage 3: best matching pair at %"PRIu32" and %"PRIu32", "
578  "ratio %f, offset %d, score %d, %d frames matching\n",
579  bestmatch.first->index, bestmatch.second->index,
580  bestmatch.framerateratio, bestmatch.offset, bestmatch.score, bestmatch.matchframes);
581  sll_free(&infos);
582  }
583  } while (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 0) && !bestmatch.whole);
584  return bestmatch;
585 
586 }
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:150
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:539
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:434
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:65
av_log_get_level
int av_log_get_level(void)
Get the current log level.
Definition: log.c:437
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:331
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
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AV_LOG_FATAL
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:174
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:119
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:397
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:368
CoarseSignature
Definition: signature.h:82
MatchingInfo::matchframes
int matchframes
Definition: signature.h:95