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 "libavutil/mem.h"
27 #include "signature.h"
28 
29 #define HOUGH_MAX_OFFSET 90
30 #define MAX_FRAMERATE 60
31 
32 #define DIR_PREV 0
33 #define DIR_NEXT 1
34 #define DIR_PREV_END 2
35 #define DIR_NEXT_END 3
36 
37 #define STATUS_NULL 0
38 #define STATUS_END_REACHED 1
39 #define STATUS_BEGIN_REACHED 2
40 
41 static void sll_free(MatchingInfo **sll)
42 {
43  while (*sll) {
44  MatchingInfo *tmp = *sll;
45  *sll = tmp->next;
46  tmp->next = NULL;
47  av_free(tmp);
48  }
49 }
50 
51 static void fill_l1distlut(uint8_t lut[])
52 {
53  int i, j, tmp_i, tmp_j,count;
54  uint8_t dist;
55 
56  for (i = 0, count = 0; i < 242; i++) {
57  for (j = i + 1; j < 243; j++, count++) {
58  /* ternary distance between i and j */
59  dist = 0;
60  tmp_i = i; tmp_j = j;
61  do {
62  dist += FFABS((tmp_j % 3) - (tmp_i % 3));
63  tmp_j /= 3;
64  tmp_i /= 3;
65  } while (tmp_i > 0 || tmp_j > 0);
66  lut[count] = dist;
67  }
68  }
69 }
70 
71 static unsigned int intersection_word(const uint8_t *first, const uint8_t *second)
72 {
73  unsigned int val=0,i;
74  for (i = 0; i < 28; i += 4) {
75  val += av_popcount( (first[i] & second[i] ) << 24 |
76  (first[i+1] & second[i+1]) << 16 |
77  (first[i+2] & second[i+2]) << 8 |
78  (first[i+3] & second[i+3]) );
79  }
80  val += av_popcount( (first[28] & second[28]) << 16 |
81  (first[29] & second[29]) << 8 |
82  (first[30] & second[30]) );
83  return val;
84 }
85 
86 static unsigned int union_word(const uint8_t *first, const uint8_t *second)
87 {
88  unsigned int val=0,i;
89  for (i = 0; i < 28; i += 4) {
90  val += av_popcount( (first[i] | second[i] ) << 24 |
91  (first[i+1] | second[i+1]) << 16 |
92  (first[i+2] | second[i+2]) << 8 |
93  (first[i+3] | second[i+3]) );
94  }
95  val += av_popcount( (first[28] | second[28]) << 16 |
96  (first[29] | second[29]) << 8 |
97  (first[30] | second[30]) );
98  return val;
99 }
100 
101 static unsigned int get_l1dist(AVFilterContext *ctx, SignatureContext *sc, const uint8_t *first, const uint8_t *second)
102 {
103  unsigned int i;
104  unsigned int dist = 0;
105  uint8_t f, s;
106 
107  for (i = 0; i < SIGELEM_SIZE/5; i++) {
108  if (first[i] != second[i]) {
109  f = first[i];
110  s = second[i];
111  if (f > s) {
112  /* little variation of gauss sum formula */
113  dist += sc->l1distlut[243*242/2 - (243-s)*(242-s)/2 + f - s - 1];
114  } else {
115  dist += sc->l1distlut[243*242/2 - (243-f)*(242-f)/2 + s - f - 1];
116  }
117  }
118  }
119  return dist;
120 }
121 
122 /**
123  * calculates the jaccard distance and evaluates a pair of coarse signatures as good
124  * @return 0 if pair is bad, 1 otherwise
125  */
127 {
128  int jaccarddist, i, composdist = 0, cwthcount = 0;
129  for (i = 0; i < 5; i++) {
130  if ((jaccarddist = (1 << 16) * intersection_word(first->data[i], second->data[i])) > 0) {
131  jaccarddist /= union_word(first->data[i], second->data[i]);
132  }
133  jaccarddist = (1 << 16) - jaccarddist;
134  if (jaccarddist >= sc->thworddist) {
135  if (++cwthcount > 2) {
136  /* more than half (5/2) of distances are too wide */
137  return 0;
138  }
139  }
140  composdist += jaccarddist;
141  if (composdist > sc->thcomposdist) {
142  return 0;
143  }
144  }
145  return 1;
146 }
147 
148 /**
149  * step through the coarsesignatures as long as a good candidate is found
150  * @return 0 if no candidate is found, 1 otherwise
151  */
153 {
154  /* go one coarsesignature foreword */
155  if (!start) {
156  if ((*second)->next) {
157  *second = (*second)->next;
158  } else if ((*first)->next) {
159  *second = secondstart;
160  *first = (*first)->next;
161  } else {
162  return 0;
163  }
164  }
165 
166  while (1) {
167  if (get_jaccarddist(sc, *first, *second))
168  return 1;
169 
170  /* next signature */
171  if ((*second)->next) {
172  *second = (*second)->next;
173  } else if ((*first)->next) {
174  *second = secondstart;
175  *first = (*first)->next;
176  } else {
177  return 0;
178  }
179  }
180 }
181 
182 /**
183  * compares framesignatures and sorts out signatures with a l1 distance above a given threshold.
184  * Then tries to find out offset and differences between framerates with a hough transformation
185  */
187 {
188  FineSignature *f, *s;
189  size_t i, j, k, l, hmax = 0, score;
190  int framerate, offset, l1dist;
191  double m;
192  MatchingInfo cands = { 0 }, *c = &cands;
193 
194  struct {
195  uint8_t size;
196  unsigned int dist;
197  FineSignature *a;
198  uint8_t b_pos[COARSE_SIZE];
200  } pairs[COARSE_SIZE];
201 
202  typedef struct hspace_elem {
203  int dist;
204  size_t score;
205  FineSignature *a;
206  FineSignature *b;
207  } hspace_elem;
208 
209  /* houghspace */
210  hspace_elem **hspace = av_malloc(MAX_FRAMERATE * sizeof(*hspace));
211  hspace_elem *hspaces;
212 
213  if (!hspace)
214  return NULL;
215  /* initialize houghspace */
216  hspaces = av_malloc((2 * HOUGH_MAX_OFFSET + 1) * sizeof(*hspaces) * MAX_FRAMERATE);
217  if (!hspaces)
218  goto error;
219  for (i = 0; i < MAX_FRAMERATE; i++) {
220  hspace[i] = hspaces + i * (2 * HOUGH_MAX_OFFSET + 1);
221  for (j = 0; j < 2 * HOUGH_MAX_OFFSET + 1; j++) {
222  hspace[i][j].score = 0;
223  hspace[i][j].dist = 99999;
224  }
225  }
226 
227  /* l1 distances */
228  for (i = 0, f = first; i < COARSE_SIZE && f->next; i++, f = f->next) {
229  pairs[i].size = 0;
230  pairs[i].dist = 99999;
231  pairs[i].a = f;
232  for (j = 0, s = second; j < COARSE_SIZE && s->next; j++, s = s->next) {
233  /* l1 distance of finesignature */
234  l1dist = get_l1dist(ctx, sc, f->framesig, s->framesig);
235  if (l1dist < sc->thl1) {
236  if (l1dist < pairs[i].dist) {
237  pairs[i].size = 1;
238  pairs[i].dist = l1dist;
239  pairs[i].b_pos[0] = j;
240  pairs[i].b[0] = s;
241  } else if (l1dist == pairs[i].dist) {
242  pairs[i].b[pairs[i].size] = s;
243  pairs[i].b_pos[pairs[i].size] = j;
244  pairs[i].size++;
245  }
246  }
247  }
248  }
249  /* last incomplete coarsesignature */
250  if (f->next == NULL) {
251  for (; i < COARSE_SIZE; i++) {
252  pairs[i].size = 0;
253  pairs[i].dist = 99999;
254  }
255  }
256 
257  /* hough transformation */
258  for (i = 0; i < COARSE_SIZE; i++) {
259  for (j = 0; j < pairs[i].size; j++) {
260  for (k = i + 1; k < COARSE_SIZE; k++) {
261  for (l = 0; l < pairs[k].size; l++) {
262  if (pairs[i].b[j] != pairs[k].b[l]) {
263  /* linear regression */
264  m = (pairs[k].b_pos[l]-pairs[i].b_pos[j]) / (k-i); /* good value between 0.0 - 2.0 */
265  framerate = (int) (m*30 + 0.5); /* round up to 0 - 60 */
266  if (framerate>0 && framerate <= MAX_FRAMERATE) {
267  offset = pairs[i].b_pos[j] - ((int) (m*i + 0.5)); /* only second part has to be rounded up */
269  if (pairs[i].dist < pairs[k].dist) {
270  if (pairs[i].dist < hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) {
271  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist = pairs[i].dist;
272  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].a = pairs[i].a;
273  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].b = pairs[i].b[j];
274  }
275  } else {
276  if (pairs[k].dist < hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist) {
277  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].dist = pairs[k].dist;
278  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].a = pairs[k].a;
279  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].b = pairs[k].b[l];
280  }
281  }
282 
283  score = hspace[framerate-1][offset+HOUGH_MAX_OFFSET].score + 1;
284  if (score > hmax )
285  hmax = score;
286  hspace[framerate-1][offset+HOUGH_MAX_OFFSET].score = score;
287  }
288  }
289  }
290  }
291  }
292  }
293  }
294 
295  if (hmax > 0) {
296  hmax = (int) (0.7*hmax);
297  for (i = 0; i < MAX_FRAMERATE; i++) {
298  for (j = 0; j < HOUGH_MAX_OFFSET; j++) {
299  if (hmax < hspace[i][j].score) {
300  c->next = av_malloc(sizeof(MatchingInfo));
301  c = c->next;
302  if (!c) {
303  sll_free(&cands.next);
304  goto error;
305  }
306  c->framerateratio = (i+1.0) / 30;
307  c->score = hspace[i][j].score;
308  c->offset = j-90;
309  c->first = hspace[i][j].a;
310  c->second = hspace[i][j].b;
311  c->next = NULL;
312 
313  /* not used */
314  c->meandist = 0;
315  c->matchframes = 0;
316  c->whole = 0;
317  }
318  }
319  }
320  }
321  error:
322  av_freep(&hspace);
323  av_free(hspaces);
324  return cands.next;
325 }
326 
327 static int iterate_frame(double frr, FineSignature **a, FineSignature **b, int fcount, int *bcount, int dir)
328 {
329  int step;
330 
331  /* between 1 and 2, because frr is between 1 and 2 */
332  step = ((int) 0.5 + fcount * frr) /* current frame */
333  -((int) 0.5 + (fcount-1) * frr);/* last frame */
334 
335  if (dir == DIR_NEXT) {
336  if (frr >= 1.0) {
337  if ((*a)->next) {
338  *a = (*a)->next;
339  } else {
340  return DIR_NEXT_END;
341  }
342 
343  if (step == 1) {
344  if ((*b)->next) {
345  *b = (*b)->next;
346  (*bcount)++;
347  } else {
348  return DIR_NEXT_END;
349  }
350  } else {
351  if ((*b)->next && (*b)->next->next) {
352  *b = (*b)->next->next;
353  (*bcount)++;
354  } else {
355  return DIR_NEXT_END;
356  }
357  }
358  } else {
359  if ((*b)->next) {
360  *b = (*b)->next;
361  (*bcount)++;
362  } else {
363  return DIR_NEXT_END;
364  }
365 
366  if (step == 1) {
367  if ((*a)->next) {
368  *a = (*a)->next;
369  } else {
370  return DIR_NEXT_END;
371  }
372  } else {
373  if ((*a)->next && (*a)->next->next) {
374  *a = (*a)->next->next;
375  } else {
376  return DIR_NEXT_END;
377  }
378  }
379  }
380  return DIR_NEXT;
381  } else {
382  if (frr >= 1.0) {
383  if ((*a)->prev) {
384  *a = (*a)->prev;
385  } else {
386  return DIR_PREV_END;
387  }
388 
389  if (step == 1) {
390  if ((*b)->prev) {
391  *b = (*b)->prev;
392  (*bcount)++;
393  } else {
394  return DIR_PREV_END;
395  }
396  } else {
397  if ((*b)->prev && (*b)->prev->prev) {
398  *b = (*b)->prev->prev;
399  (*bcount)++;
400  } else {
401  return DIR_PREV_END;
402  }
403  }
404  } else {
405  if ((*b)->prev) {
406  *b = (*b)->prev;
407  (*bcount)++;
408  } else {
409  return DIR_PREV_END;
410  }
411 
412  if (step == 1) {
413  if ((*a)->prev) {
414  *a = (*a)->prev;
415  } else {
416  return DIR_PREV_END;
417  }
418  } else {
419  if ((*a)->prev && (*a)->prev->prev) {
420  *a = (*a)->prev->prev;
421  } else {
422  return DIR_PREV_END;
423  }
424  }
425  }
426  return DIR_PREV;
427  }
428 }
429 
431 {
432  int dist, distsum = 0, bcount = 1, dir = DIR_NEXT;
433  int fcount = 0, goodfcount = 0, gooda = 0, goodb = 0;
434  double meandist, minmeandist = bestmatch.meandist;
435  int tolerancecount = 0;
436  FineSignature *a, *b, *aprev, *bprev;
437  int status = STATUS_NULL;
438 
439  for (; infos != NULL; infos = infos->next) {
440  a = infos->first;
441  b = infos->second;
442  while (1) {
443  dist = get_l1dist(ctx, sc, a->framesig, b->framesig);
444 
445  if (dist > sc->thl1) {
446  if (a->confidence >= 1 || b->confidence >= 1) {
447  /* bad frame (because high different information) */
448  tolerancecount++;
449  }
450 
451  if (tolerancecount > 2) {
452  if (dir == DIR_NEXT) {
453  /* turn around */
454  a = infos->first;
455  b = infos->second;
456  dir = DIR_PREV;
457  } else {
458  a = aprev;
459  b = bprev;
460  break;
461  }
462  }
463  } else {
464  /* good frame */
465  distsum += dist;
466  goodfcount++;
467  tolerancecount=0;
468 
469  aprev = a;
470  bprev = b;
471 
472  if (a->confidence < 1) gooda++;
473  if (b->confidence < 1) goodb++;
474  }
475 
476  fcount++;
477 
478  dir = iterate_frame(infos->framerateratio, &a, &b, fcount, &bcount, dir);
479  if (dir == DIR_NEXT_END) {
481  a = infos->first;
482  b = infos->second;
483  dir = iterate_frame(infos->framerateratio, &a, &b, fcount, &bcount, DIR_PREV);
484  }
485 
486  if (dir == DIR_PREV_END) {
488  break;
489  }
490 
491  if (sc->thdi != 0 && bcount >= sc->thdi) {
492  break; /* enough frames found */
493  }
494  }
495 
496  if (bcount < sc->thdi)
497  continue; /* matching sequence is too short */
498  if ((double) goodfcount / (double) fcount < sc->thit)
499  continue;
500  if ((double) goodfcount*0.5 <= FFMAX(gooda, goodb))
501  continue;
502 
503  meandist = (double) distsum / (double) goodfcount;
504 
505  if (meandist < minmeandist ||
507  mode == MODE_FAST){
508  minmeandist = meandist;
509  /* bestcandidate in this iteration */
510  bestmatch.meandist = meandist;
511  bestmatch.matchframes = bcount;
512  bestmatch.framerateratio = infos->framerateratio;
513  bestmatch.score = infos->score;
514  bestmatch.offset = infos->offset;
515  bestmatch.first = infos->first;
516  bestmatch.second = infos->second;
517  bestmatch.whole = 0; /* will be set to true later */
518  bestmatch.next = NULL;
519  }
520 
521  /* whole sequence is automatically best match */
523  bestmatch.whole = 1;
524  break;
525  }
526 
527  /* first matching sequence is enough, finding the best one is not necessary */
528  if (mode == MODE_FAST) {
529  break;
530  }
531  }
532  return bestmatch;
533 }
534 
536 {
537  CoarseSignature *cs, *cs2;
538  MatchingInfo *infos;
539  MatchingInfo bestmatch;
540  MatchingInfo *i;
541 
542  cs = first->coarsesiglist;
543  cs2 = second->coarsesiglist;
544 
545  /* score of bestmatch is 0, if no match is found */
546  bestmatch.score = 0;
547  bestmatch.meandist = 99999;
548  bestmatch.whole = 0;
549 
551 
552  /* stage 1: coarsesignature matching */
553  if (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 1) == 0)
554  return bestmatch; /* no candidate found */
555  do {
556  av_log(ctx, AV_LOG_DEBUG, "Stage 1: got coarsesignature pair. "
557  "indices of first frame: %"PRIu32" and %"PRIu32"\n",
558  cs->first->index, cs2->first->index);
559  /* stage 2: l1-distance and hough-transform */
560  av_log(ctx, AV_LOG_DEBUG, "Stage 2: calculate matching parameters\n");
561  infos = get_matching_parameters(ctx, sc, cs->first, cs2->first);
562  if (av_log_get_level() == AV_LOG_DEBUG) {
563  for (i = infos; i != NULL; i = i->next) {
564  av_log(ctx, AV_LOG_DEBUG, "Stage 2: matching pair at %"PRIu32" and %"PRIu32", "
565  "ratio %f, offset %d\n", i->first->index, i->second->index,
566  i->framerateratio, i->offset);
567  }
568  }
569  /* stage 3: evaluation */
570  av_log(ctx, AV_LOG_DEBUG, "Stage 3: evaluate\n");
571  if (infos) {
572  bestmatch = evaluate_parameters(ctx, sc, infos, bestmatch, mode);
573  av_log(ctx, AV_LOG_DEBUG, "Stage 3: best matching pair at %"PRIu32" and %"PRIu32", "
574  "ratio %f, offset %d, score %d, %d frames matching\n",
575  bestmatch.first->index, bestmatch.second->index,
576  bestmatch.framerateratio, bestmatch.offset, bestmatch.score, bestmatch.matchframes);
577  sll_free(&infos);
578  }
579  } while (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 0) && !bestmatch.whole);
580  return bestmatch;
581 
582 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
MatchingInfo::framerateratio
double framerateratio
Definition: signature.h:92
MAX_FRAMERATE
#define MAX_FRAMERATE
Definition: signature_lookup.c:30
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:154
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:51
lookup_signatures
static MatchingInfo lookup_signatures(AVFilterContext *ctx, SignatureContext *sc, StreamContext *first, StreamContext *second, int mode)
Definition: signature_lookup.c:535
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:430
STATUS_END_REACHED
#define STATUS_END_REACHED
Definition: signature_lookup.c:38
STATUS_NULL
#define STATUS_NULL
Definition: signature_lookup.c:37
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:29
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:49
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
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:32
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:186
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:54
f
f
Definition: af_crystalizer.c:121
sll_free
static void sll_free(MatchingInfo **sll)
Definition: signature_lookup.c:41
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:126
iterate_frame
static int iterate_frame(double frr, FineSignature **a, FineSignature **b, int fcount, int *bcount, int dir)
Definition: signature_lookup.c:327
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:86
DIR_PREV_END
#define DIR_PREV_END
Definition: signature_lookup.c:34
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:35
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:101
FineSignature
Definition: signature.h:72
SignatureContext
Definition: signature.h:127
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
DIR_NEXT
#define DIR_NEXT
Definition: signature_lookup.c:33
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:152
CoarseSignature::data
uint8_t data[5][31]
Definition: signature.h:83
status
ov_status_e status
Definition: dnn_backend_openvino.c:101
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
mem.h
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:71
STATUS_BEGIN_REACHED
#define STATUS_BEGIN_REACHED
Definition: signature_lookup.c:39
int
int
Definition: ffmpeg_filter.c:424
CoarseSignature
Definition: signature.h:82
MatchingInfo::matchframes
int matchframes
Definition: signature.h:95