FFmpeg
vf_signature.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  * @see http://epubs.surrey.ac.uk/531590/1/MPEG-7%20Video%20Signature%20Author%27s%20Copy.pdf
25  */
26 
27 #include <float.h>
28 #include "libavcodec/put_bits.h"
29 #include "libavformat/avformat.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/avstring.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/timestamp.h"
34 #include "avfilter.h"
35 #include "internal.h"
36 #include "signature.h"
37 #include "signature_lookup.c"
38 
39 #define OFFSET(x) offsetof(SignatureContext, x)
40 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
41 #define BLOCK_LCM (int64_t) 476985600
42 
43 static const AVOption signature_options[] = {
44  { "detectmode", "set the detectmode",
45  OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = MODE_OFF}, 0, NB_LOOKUP_MODE-1, FLAGS, "mode" },
46  { "off", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MODE_OFF}, 0, 0, .flags = FLAGS, "mode" },
47  { "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MODE_FULL}, 0, 0, .flags = FLAGS, "mode" },
48  { "fast", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = MODE_FAST}, 0, 0, .flags = FLAGS, "mode" },
49  { "nb_inputs", "number of inputs",
50  OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, FLAGS },
51  { "filename", "filename for output files",
52  OFFSET(filename), AV_OPT_TYPE_STRING, {.str = ""}, 0, NB_FORMATS-1, FLAGS },
53  { "format", "set output format",
54  OFFSET(format), AV_OPT_TYPE_INT, {.i64 = FORMAT_BINARY}, 0, 1, FLAGS , "format" },
55  { "binary", 0, 0, AV_OPT_TYPE_CONST, {.i64=FORMAT_BINARY}, 0, 0, FLAGS, "format" },
56  { "xml", 0, 0, AV_OPT_TYPE_CONST, {.i64=FORMAT_XML}, 0, 0, FLAGS, "format" },
57  { "th_d", "threshold to detect one word as similar",
58  OFFSET(thworddist), AV_OPT_TYPE_INT, {.i64 = 9000}, 1, INT_MAX, FLAGS },
59  { "th_dc", "threshold to detect all words as similar",
60  OFFSET(thcomposdist), AV_OPT_TYPE_INT, {.i64 = 60000}, 1, INT_MAX, FLAGS },
61  { "th_xh", "threshold to detect frames as similar",
62  OFFSET(thl1), AV_OPT_TYPE_INT, {.i64 = 116}, 1, INT_MAX, FLAGS },
63  { "th_di", "minimum length of matching sequence in frames",
64  OFFSET(thdi), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS },
65  { "th_it", "threshold for relation of good to all frames",
66  OFFSET(thit), AV_OPT_TYPE_DOUBLE, {.dbl = 0.5}, 0.0, 1.0, FLAGS },
67  { NULL }
68 };
69 
71 
72 /* all formats with a separate gray value */
73 static const enum AVPixelFormat pix_fmts[] = {
83 };
84 
86 {
87  AVFilterContext *ctx = inlink->dst;
88  SignatureContext *sic = ctx->priv;
90 
91  sc->time_base = inlink->time_base;
92  /* test for overflow */
93  sc->divide = (((uint64_t) inlink->w/32) * (inlink->w/32 + 1) * (inlink->h/32 * inlink->h/32 + 1) > INT64_MAX / (BLOCK_LCM * 255));
94  if (sc->divide) {
95  av_log(ctx, AV_LOG_WARNING, "Input dimension too high for precise calculation, numbers will be rounded.\n");
96  }
97  sc->w = inlink->w;
98  sc->h = inlink->h;
99  return 0;
100 }
101 
102 static int get_block_size(const Block *b)
103 {
104  return (b->to.y - b->up.y + 1) * (b->to.x - b->up.x + 1);
105 }
106 
107 static uint64_t get_block_sum(StreamContext *sc, uint64_t intpic[32][32], const Block *b)
108 {
109  uint64_t sum = 0;
110 
111  int x0, y0, x1, y1;
112 
113  x0 = b->up.x;
114  y0 = b->up.y;
115  x1 = b->to.x;
116  y1 = b->to.y;
117 
118  if (x0-1 >= 0 && y0-1 >= 0) {
119  sum = intpic[y1][x1] + intpic[y0-1][x0-1] - intpic[y1][x0-1] - intpic[y0-1][x1];
120  } else if (x0-1 >= 0) {
121  sum = intpic[y1][x1] - intpic[y1][x0-1];
122  } else if (y0-1 >= 0) {
123  sum = intpic[y1][x1] - intpic[y0-1][x1];
124  } else {
125  sum = intpic[y1][x1];
126  }
127  return sum;
128 }
129 
130 static int cmp(const void *x, const void *y)
131 {
132  const uint64_t *a = x, *b = y;
133  return *a < *b ? -1 : ( *a > *b ? 1 : 0 );
134 }
135 
136 /**
137  * sets the bit at position pos to 1 in data
138  */
139 static void set_bit(uint8_t* data, size_t pos)
140 {
141  uint8_t mask = 1 << 7-(pos%8);
142  data[pos/8] |= mask;
143 }
144 
146 {
147  AVFilterContext *ctx = inlink->dst;
148  SignatureContext *sic = ctx->priv;
150  FineSignature* fs;
151 
152  static const uint8_t pot3[5] = { 3*3*3*3, 3*3*3, 3*3, 3, 1 };
153  /* indexes of words : 210,217,219,274,334 44,175,233,270,273 57,70,103,237,269 100,285,295,337,354 101,102,111,275,296
154  s2usw = sorted to unsorted wordvec: 44 is at index 5, 57 at index 10...
155  */
156  static const unsigned int wordvec[25] = {44,57,70,100,101,102,103,111,175,210,217,219,233,237,269,270,273,274,275,285,295,296,334,337,354};
157  static const uint8_t s2usw[25] = { 5,10,11, 15, 20, 21, 12, 22, 6, 0, 1, 2, 7, 13, 14, 8, 9, 3, 23, 16, 17, 24, 4, 18, 19};
158 
159  uint8_t wordt2b[5] = { 0, 0, 0, 0, 0 }; /* word ternary to binary */
160  uint64_t intpic[32][32];
161  uint64_t rowcount;
162  uint8_t *p = picref->data[0];
163  int inti, intj;
164  int *intjlut;
165 
166  uint64_t conflist[DIFFELEM_SIZE];
167  int f = 0, g = 0, w = 0;
168  int32_t dh1 = 1, dh2 = 1, dw1 = 1, dw2 = 1, a, b;
169  int64_t denom;
170  int i, j, k, ternary;
171  uint64_t blocksum;
172  int blocksize;
173  int64_t th; /* threshold */
174  int64_t sum;
175 
176  int64_t precfactor = (sc->divide) ? 65536 : BLOCK_LCM;
177 
178  /* initialize fs */
179  if (sc->curfinesig) {
180  fs = av_mallocz(sizeof(FineSignature));
181  if (!fs)
182  return AVERROR(ENOMEM);
183  sc->curfinesig->next = fs;
184  fs->prev = sc->curfinesig;
185  sc->curfinesig = fs;
186  } else {
187  fs = sc->curfinesig = sc->finesiglist;
188  sc->curcoarsesig1->first = fs;
189  }
190 
191  fs->pts = picref->pts;
192  fs->index = sc->lastindex++;
193 
194  memset(intpic, 0, sizeof(uint64_t)*32*32);
195  intjlut = av_malloc_array(inlink->w, sizeof(int));
196  if (!intjlut)
197  return AVERROR(ENOMEM);
198  for (i = 0; i < inlink->w; i++) {
199  intjlut[i] = (i*32)/inlink->w;
200  }
201 
202  for (i = 0; i < inlink->h; i++) {
203  inti = (i*32)/inlink->h;
204  for (j = 0; j < inlink->w; j++) {
205  intj = intjlut[j];
206  intpic[inti][intj] += p[j];
207  }
208  p += picref->linesize[0];
209  }
210  av_freep(&intjlut);
211 
212  /* The following calculates a summed area table (intpic) and brings the numbers
213  * in intpic to the same denominator.
214  * So you only have to handle the numinator in the following sections.
215  */
216  dh1 = inlink->h / 32;
217  if (inlink->h % 32)
218  dh2 = dh1 + 1;
219  dw1 = inlink->w / 32;
220  if (inlink->w % 32)
221  dw2 = dw1 + 1;
222  denom = (sc->divide) ? dh1 * dh2 * dw1 * dw2 : 1;
223 
224  for (i = 0; i < 32; i++) {
225  rowcount = 0;
226  a = 1;
227  if (dh2 > 1) {
228  a = ((inlink->h*(i+1))%32 == 0) ? (inlink->h*(i+1))/32 - 1 : (inlink->h*(i+1))/32;
229  a -= ((inlink->h*i)%32 == 0) ? (inlink->h*i)/32 - 1 : (inlink->h*i)/32;
230  a = (a == dh1)? dh2 : dh1;
231  }
232  for (j = 0; j < 32; j++) {
233  b = 1;
234  if (dw2 > 1) {
235  b = ((inlink->w*(j+1))%32 == 0) ? (inlink->w*(j+1))/32 - 1 : (inlink->w*(j+1))/32;
236  b -= ((inlink->w*j)%32 == 0) ? (inlink->w*j)/32 - 1 : (inlink->w*j)/32;
237  b = (b == dw1)? dw2 : dw1;
238  }
239  rowcount += intpic[i][j] * a * b * precfactor / denom;
240  if (i > 0) {
241  intpic[i][j] = intpic[i-1][j] + rowcount;
242  } else {
243  intpic[i][j] = rowcount;
244  }
245  }
246  }
247 
248  denom = (sc->divide) ? 1 : dh1 * dh2 * dw1 * dw2;
249 
250  for (i = 0; i < ELEMENT_COUNT; i++) {
251  const ElemCat* elemcat = elements[i];
252  int64_t* elemsignature;
253  uint64_t* sortsignature;
254 
255  elemsignature = av_malloc_array(elemcat->elem_count, sizeof(int64_t));
256  if (!elemsignature)
257  return AVERROR(ENOMEM);
258  sortsignature = av_malloc_array(elemcat->elem_count, sizeof(int64_t));
259  if (!sortsignature) {
260  av_freep(&elemsignature);
261  return AVERROR(ENOMEM);
262  }
263 
264  for (j = 0; j < elemcat->elem_count; j++) {
265  blocksum = 0;
266  blocksize = 0;
267  for (k = 0; k < elemcat->left_count; k++) {
268  blocksum += get_block_sum(sc, intpic, &elemcat->blocks[j*elemcat->block_count+k]);
269  blocksize += get_block_size(&elemcat->blocks[j*elemcat->block_count+k]);
270  }
271  sum = blocksum / blocksize;
272  if (elemcat->av_elem) {
273  sum -= 128 * precfactor * denom;
274  } else {
275  blocksum = 0;
276  blocksize = 0;
277  for (; k < elemcat->block_count; k++) {
278  blocksum += get_block_sum(sc, intpic, &elemcat->blocks[j*elemcat->block_count+k]);
279  blocksize += get_block_size(&elemcat->blocks[j*elemcat->block_count+k]);
280  }
281  sum -= blocksum / blocksize;
282  conflist[g++] = FFABS(sum * 8 / (precfactor * denom));
283  }
284 
285  elemsignature[j] = sum;
286  sortsignature[j] = FFABS(sum);
287  }
288 
289  /* get threshold */
290  qsort(sortsignature, elemcat->elem_count, sizeof(uint64_t), cmp);
291  th = sortsignature[(int) (elemcat->elem_count*0.333)];
292 
293  /* ternarize */
294  for (j = 0; j < elemcat->elem_count; j++) {
295  if (elemsignature[j] < -th) {
296  ternary = 0;
297  } else if (elemsignature[j] <= th) {
298  ternary = 1;
299  } else {
300  ternary = 2;
301  }
302  fs->framesig[f/5] += ternary * pot3[f%5];
303 
304  if (f == wordvec[w]) {
305  fs->words[s2usw[w]/5] += ternary * pot3[wordt2b[s2usw[w]/5]++];
306  if (w < 24)
307  w++;
308  }
309  f++;
310  }
311  av_freep(&elemsignature);
312  av_freep(&sortsignature);
313  }
314 
315  /* confidence */
316  qsort(conflist, DIFFELEM_SIZE, sizeof(uint64_t), cmp);
317  fs->confidence = FFMIN(conflist[DIFFELEM_SIZE/2], 255);
318 
319  /* coarsesignature */
320  if (sc->coarsecount == 0) {
321  if (sc->curcoarsesig2) {
323  if (!sc->curcoarsesig1)
324  return AVERROR(ENOMEM);
325  sc->curcoarsesig1->first = fs;
326  sc->curcoarsesig2->next = sc->curcoarsesig1;
327  sc->coarseend = sc->curcoarsesig1;
328  }
329  }
330  if (sc->coarsecount == 45) {
331  sc->midcoarse = 1;
333  if (!sc->curcoarsesig2)
334  return AVERROR(ENOMEM);
335  sc->curcoarsesig2->first = fs;
336  sc->curcoarsesig1->next = sc->curcoarsesig2;
337  sc->coarseend = sc->curcoarsesig2;
338  }
339  for (i = 0; i < 5; i++) {
340  set_bit(sc->curcoarsesig1->data[i], fs->words[i]);
341  }
342  /* assuming the actual frame is the last */
343  sc->curcoarsesig1->last = fs;
344  if (sc->midcoarse) {
345  for (i = 0; i < 5; i++) {
346  set_bit(sc->curcoarsesig2->data[i], fs->words[i]);
347  }
348  sc->curcoarsesig2->last = fs;
349  }
350 
351  sc->coarsecount = (sc->coarsecount+1)%90;
352 
353  /* debug printing finesignature */
354  if (av_log_get_level() == AV_LOG_DEBUG) {
355  av_log(ctx, AV_LOG_DEBUG, "input %d, confidence: %d\n", FF_INLINK_IDX(inlink), fs->confidence);
356 
357  av_log(ctx, AV_LOG_DEBUG, "words:");
358  for (i = 0; i < 5; i++) {
359  av_log(ctx, AV_LOG_DEBUG, " %d:", fs->words[i] );
360  av_log(ctx, AV_LOG_DEBUG, " %d", fs->words[i] / pot3[0] );
361  for (j = 1; j < 5; j++)
362  av_log(ctx, AV_LOG_DEBUG, ",%d", fs->words[i] % pot3[j-1] / pot3[j] );
363  av_log(ctx, AV_LOG_DEBUG, ";");
364  }
365  av_log(ctx, AV_LOG_DEBUG, "\n");
366 
367  av_log(ctx, AV_LOG_DEBUG, "framesignature:");
368  for (i = 0; i < SIGELEM_SIZE/5; i++) {
369  av_log(ctx, AV_LOG_DEBUG, " %d", fs->framesig[i] / pot3[0] );
370  for (j = 1; j < 5; j++)
371  av_log(ctx, AV_LOG_DEBUG, ",%d", fs->framesig[i] % pot3[j-1] / pot3[j] );
372  }
373  av_log(ctx, AV_LOG_DEBUG, "\n");
374  }
375 
376  if (FF_INLINK_IDX(inlink) == 0)
377  return ff_filter_frame(inlink->dst->outputs[0], picref);
378  return 1;
379 }
380 
381 static int xml_export(AVFilterContext *ctx, StreamContext *sc, const char* filename)
382 {
383  FineSignature* fs;
384  CoarseSignature* cs;
385  int i, j;
386  FILE* f;
387  unsigned int pot3[5] = { 3*3*3*3, 3*3*3, 3*3, 3, 1 };
388 
389  f = fopen(filename, "w");
390  if (!f) {
391  int err = AVERROR(EINVAL);
392  char buf[128];
393  av_strerror(err, buf, sizeof(buf));
394  av_log(ctx, AV_LOG_ERROR, "cannot open xml file %s: %s\n", filename, buf);
395  return err;
396  }
397 
398  /* header */
399  fprintf(f, "<?xml version='1.0' encoding='ASCII' ?>\n");
400  fprintf(f, "<Mpeg7 xmlns=\"urn:mpeg:mpeg7:schema:2001\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:mpeg:mpeg7:schema:2001 schema/Mpeg7-2001.xsd\">\n");
401  fprintf(f, " <DescriptionUnit xsi:type=\"DescriptorCollectionType\">\n");
402  fprintf(f, " <Descriptor xsi:type=\"VideoSignatureType\">\n");
403  fprintf(f, " <VideoSignatureRegion>\n");
404  fprintf(f, " <VideoSignatureSpatialRegion>\n");
405  fprintf(f, " <Pixel>0 0 </Pixel>\n");
406  fprintf(f, " <Pixel>%d %d </Pixel>\n", sc->w - 1, sc->h - 1);
407  fprintf(f, " </VideoSignatureSpatialRegion>\n");
408  fprintf(f, " <StartFrameOfSpatialRegion>0</StartFrameOfSpatialRegion>\n");
409  /* hoping num is 1, other values are vague */
410  fprintf(f, " <MediaTimeUnit>%d</MediaTimeUnit>\n", sc->time_base.den / sc->time_base.num);
411  fprintf(f, " <MediaTimeOfSpatialRegion>\n");
412  fprintf(f, " <StartMediaTimeOfSpatialRegion>0</StartMediaTimeOfSpatialRegion>\n");
413  fprintf(f, " <EndMediaTimeOfSpatialRegion>%" PRIu64 "</EndMediaTimeOfSpatialRegion>\n", sc->coarseend->last->pts);
414  fprintf(f, " </MediaTimeOfSpatialRegion>\n");
415 
416  /* coarsesignatures */
417  for (cs = sc->coarsesiglist; cs; cs = cs->next) {
418  fprintf(f, " <VSVideoSegment>\n");
419  fprintf(f, " <StartFrameOfSegment>%" PRIu32 "</StartFrameOfSegment>\n", cs->first->index);
420  fprintf(f, " <EndFrameOfSegment>%" PRIu32 "</EndFrameOfSegment>\n", cs->last->index);
421  fprintf(f, " <MediaTimeOfSegment>\n");
422  fprintf(f, " <StartMediaTimeOfSegment>%" PRIu64 "</StartMediaTimeOfSegment>\n", cs->first->pts);
423  fprintf(f, " <EndMediaTimeOfSegment>%" PRIu64 "</EndMediaTimeOfSegment>\n", cs->last->pts);
424  fprintf(f, " </MediaTimeOfSegment>\n");
425  for (i = 0; i < 5; i++) {
426  fprintf(f, " <BagOfWords>");
427  for (j = 0; j < 31; j++) {
428  uint8_t n = cs->data[i][j];
429  if (j < 30) {
430  fprintf(f, "%d %d %d %d %d %d %d %d ", (n & 0x80) >> 7,
431  (n & 0x40) >> 6,
432  (n & 0x20) >> 5,
433  (n & 0x10) >> 4,
434  (n & 0x08) >> 3,
435  (n & 0x04) >> 2,
436  (n & 0x02) >> 1,
437  (n & 0x01));
438  } else {
439  /* print only 3 bit in last byte */
440  fprintf(f, "%d %d %d ", (n & 0x80) >> 7,
441  (n & 0x40) >> 6,
442  (n & 0x20) >> 5);
443  }
444  }
445  fprintf(f, "</BagOfWords>\n");
446  }
447  fprintf(f, " </VSVideoSegment>\n");
448  }
449 
450  /* finesignatures */
451  for (fs = sc->finesiglist; fs; fs = fs->next) {
452  fprintf(f, " <VideoFrame>\n");
453  fprintf(f, " <MediaTimeOfFrame>%" PRIu64 "</MediaTimeOfFrame>\n", fs->pts);
454  /* confidence */
455  fprintf(f, " <FrameConfidence>%d</FrameConfidence>\n", fs->confidence);
456  /* words */
457  fprintf(f, " <Word>");
458  for (i = 0; i < 5; i++) {
459  fprintf(f, "%d ", fs->words[i]);
460  if (i < 4) {
461  fprintf(f, " ");
462  }
463  }
464  fprintf(f, "</Word>\n");
465  /* framesignature */
466  fprintf(f, " <FrameSignature>");
467  for (i = 0; i< SIGELEM_SIZE/5; i++) {
468  if (i > 0) {
469  fprintf(f, " ");
470  }
471  fprintf(f, "%d ", fs->framesig[i] / pot3[0]);
472  for (j = 1; j < 5; j++)
473  fprintf(f, " %d ", fs->framesig[i] % pot3[j-1] / pot3[j] );
474  }
475  fprintf(f, "</FrameSignature>\n");
476  fprintf(f, " </VideoFrame>\n");
477  }
478  fprintf(f, " </VideoSignatureRegion>\n");
479  fprintf(f, " </Descriptor>\n");
480  fprintf(f, " </DescriptionUnit>\n");
481  fprintf(f, "</Mpeg7>\n");
482 
483  fclose(f);
484  return 0;
485 }
486 
487 static int binary_export(AVFilterContext *ctx, StreamContext *sc, const char* filename)
488 {
489  FILE* f;
490  FineSignature* fs;
491  CoarseSignature* cs;
492  uint32_t numofsegments = (sc->lastindex + 44)/45;
493  int i, j;
494  PutBitContext buf;
495  /* buffer + header + coarsesignatures + finesignature */
496  int len = (512 + 6 * 32 + 3*16 + 2 +
497  numofsegments * (4*32 + 1 + 5*243) +
498  sc->lastindex * (2 + 32 + 6*8 + 608)) / 8;
499  uint8_t* buffer = av_malloc_array(len, sizeof(uint8_t));
500  if (!buffer)
501  return AVERROR(ENOMEM);
502 
503  f = fopen(filename, "wb");
504  if (!f) {
505  int err = AVERROR(EINVAL);
506  char buf[128];
507  av_strerror(err, buf, sizeof(buf));
508  av_log(ctx, AV_LOG_ERROR, "cannot open file %s: %s\n", filename, buf);
509  av_freep(&buffer);
510  return err;
511  }
512  init_put_bits(&buf, buffer, len);
513 
514  put_bits32(&buf, 1); /* NumOfSpatial Regions, only 1 supported */
515  put_bits(&buf, 1, 1); /* SpatialLocationFlag, always the whole image */
516  put_bits32(&buf, 0); /* PixelX,1 PixelY,1, 0,0 */
517  put_bits(&buf, 16, sc->w-1 & 0xFFFF); /* PixelX,2 */
518  put_bits(&buf, 16, sc->h-1 & 0xFFFF); /* PixelY,2 */
519  put_bits32(&buf, 0); /* StartFrameOfSpatialRegion */
520  put_bits32(&buf, sc->lastindex); /* NumOfFrames */
521  /* hoping num is 1, other values are vague */
522  /* den/num might be greater than 16 bit, so cutting it */
523  put_bits(&buf, 16, 0xFFFF & (sc->time_base.den / sc->time_base.num)); /* MediaTimeUnit */
524  put_bits(&buf, 1, 1); /* MediaTimeFlagOfSpatialRegion */
525  put_bits32(&buf, 0); /* StartMediaTimeOfSpatialRegion */
526  put_bits32(&buf, 0xFFFFFFFF & sc->coarseend->last->pts); /* EndMediaTimeOfSpatialRegion */
527  put_bits32(&buf, numofsegments); /* NumOfSegments */
528  /* coarsesignatures */
529  for (cs = sc->coarsesiglist; cs; cs = cs->next) {
530  put_bits32(&buf, cs->first->index); /* StartFrameOfSegment */
531  put_bits32(&buf, cs->last->index); /* EndFrameOfSegment */
532  put_bits(&buf, 1, 1); /* MediaTimeFlagOfSegment */
533  put_bits32(&buf, 0xFFFFFFFF & cs->first->pts); /* StartMediaTimeOfSegment */
534  put_bits32(&buf, 0xFFFFFFFF & cs->last->pts); /* EndMediaTimeOfSegment */
535  for (i = 0; i < 5; i++) {
536  /* put 243 bits ( = 7 * 32 + 19 = 8 * 28 + 19) into buffer */
537  for (j = 0; j < 30; j++) {
538  put_bits(&buf, 8, cs->data[i][j]);
539  }
540  put_bits(&buf, 3, cs->data[i][30] >> 5);
541  }
542  }
543  /* finesignatures */
544  put_bits(&buf, 1, 0); /* CompressionFlag, only 0 supported */
545  for (fs = sc->finesiglist; fs; fs = fs->next) {
546  put_bits(&buf, 1, 1); /* MediaTimeFlagOfFrame */
547  put_bits32(&buf, 0xFFFFFFFF & fs->pts); /* MediaTimeOfFrame */
548  put_bits(&buf, 8, fs->confidence); /* FrameConfidence */
549  for (i = 0; i < 5; i++) {
550  put_bits(&buf, 8, fs->words[i]); /* Words */
551  }
552  /* framesignature */
553  for (i = 0; i < SIGELEM_SIZE/5; i++) {
554  put_bits(&buf, 8, fs->framesig[i]);
555  }
556  }
557 
558  flush_put_bits(&buf);
559  fwrite(buffer, 1, put_bytes_output(&buf), f);
560  fclose(f);
561  av_freep(&buffer);
562  return 0;
563 }
564 
566 {
567  SignatureContext* sic = ctx->priv;
568  char filename[1024];
569 
570  if (sic->nb_inputs > 1) {
571  /* error already handled */
572  av_assert0(av_get_frame_filename(filename, sizeof(filename), sic->filename, input) == 0);
573  } else {
574  if (av_strlcpy(filename, sic->filename, sizeof(filename)) >= sizeof(filename))
575  return AVERROR(EINVAL);
576  }
577  if (sic->format == FORMAT_XML) {
578  return xml_export(ctx, sc, filename);
579  } else {
580  return binary_export(ctx, sc, filename);
581  }
582 }
583 
584 static int request_frame(AVFilterLink *outlink)
585 {
586  AVFilterContext *ctx = outlink->src;
587  SignatureContext *sic = ctx->priv;
588  StreamContext *sc, *sc2;
589  MatchingInfo match;
590  int i, j, ret;
591  int lookup = 1; /* indicates wheather EOF of all files is reached */
592 
593  /* process all inputs */
594  for (i = 0; i < sic->nb_inputs; i++){
595  sc = &(sic->streamcontexts[i]);
596 
597  ret = ff_request_frame(ctx->inputs[i]);
598 
599  /* return if unexpected error occurs in input stream */
600  if (ret < 0 && ret != AVERROR_EOF)
601  return ret;
602 
603  /* export signature at EOF */
604  if (ret == AVERROR_EOF && !sc->exported) {
605  /* export if wanted */
606  if (strlen(sic->filename) > 0) {
607  if (export(ctx, sc, i) < 0)
608  return ret;
609  }
610  sc->exported = 1;
611  }
612  lookup &= sc->exported;
613  }
614 
615  /* signature lookup */
616  if (lookup && sic->mode != MODE_OFF) {
617  /* iterate over every pair */
618  for (i = 0; i < sic->nb_inputs; i++) {
619  sc = &(sic->streamcontexts[i]);
620  for (j = i+1; j < sic->nb_inputs; j++) {
621  sc2 = &(sic->streamcontexts[j]);
622  match = lookup_signatures(ctx, sic, sc, sc2, sic->mode);
623  if (match.score != 0) {
624  av_log(ctx, AV_LOG_INFO, "matching of video %d at %f and %d at %f, %d frames matching\n",
625  i, ((double) match.first->pts * sc->time_base.num) / sc->time_base.den,
626  j, ((double) match.second->pts * sc2->time_base.num) / sc2->time_base.den,
627  match.matchframes);
628  if (match.whole)
629  av_log(ctx, AV_LOG_INFO, "whole video matching\n");
630  } else {
631  av_log(ctx, AV_LOG_INFO, "no matching of video %d and %d\n", i, j);
632  }
633  }
634  }
635  }
636 
637  return ret;
638 }
639 
641 {
642 
643  SignatureContext *sic = ctx->priv;
644  StreamContext *sc;
645  int i, ret;
646  char tmp[1024];
647 
648  sic->streamcontexts = av_mallocz(sic->nb_inputs * sizeof(StreamContext));
649  if (!sic->streamcontexts)
650  return AVERROR(ENOMEM);
651 
652  for (i = 0; i < sic->nb_inputs; i++) {
653  AVFilterPad pad = {
655  .name = av_asprintf("in%d", i),
656  .config_props = config_input,
657  .filter_frame = filter_frame,
658  };
659 
660  if (!pad.name)
661  return AVERROR(ENOMEM);
662  if ((ret = ff_append_inpad_free_name(ctx, &pad)) < 0)
663  return ret;
664 
665  sc = &(sic->streamcontexts[i]);
666 
667  sc->lastindex = 0;
668  sc->finesiglist = av_mallocz(sizeof(FineSignature));
669  if (!sc->finesiglist)
670  return AVERROR(ENOMEM);
671  sc->curfinesig = NULL;
672 
674  if (!sc->coarsesiglist)
675  return AVERROR(ENOMEM);
676  sc->curcoarsesig1 = sc->coarsesiglist;
677  sc->coarseend = sc->coarsesiglist;
678  sc->coarsecount = 0;
679  sc->midcoarse = 0;
680  }
681 
682  /* check filename */
683  if (sic->nb_inputs > 1 && strlen(sic->filename) > 0 && av_get_frame_filename(tmp, sizeof(tmp), sic->filename, 0) == -1) {
684  av_log(ctx, AV_LOG_ERROR, "The filename must contain %%d or %%0nd, if you have more than one input.\n");
685  return AVERROR(EINVAL);
686  }
687 
688  return 0;
689 }
690 
691 
692 
694 {
695  SignatureContext *sic = ctx->priv;
696  StreamContext *sc;
697  void* tmp;
698  FineSignature* finsig;
699  CoarseSignature* cousig;
700  int i;
701 
702 
703  /* free the lists */
704  if (sic->streamcontexts != NULL) {
705  for (i = 0; i < sic->nb_inputs; i++) {
706  sc = &(sic->streamcontexts[i]);
707  finsig = sc->finesiglist;
708  cousig = sc->coarsesiglist;
709 
710  while (finsig) {
711  tmp = finsig;
712  finsig = finsig->next;
713  av_freep(&tmp);
714  }
715  sc->finesiglist = NULL;
716 
717  while (cousig) {
718  tmp = cousig;
719  cousig = cousig->next;
720  av_freep(&tmp);
721  }
722  sc->coarsesiglist = NULL;
723  }
724  av_freep(&sic->streamcontexts);
725  }
726 }
727 
728 static int config_output(AVFilterLink *outlink)
729 {
730  AVFilterContext *ctx = outlink->src;
731  AVFilterLink *inlink = ctx->inputs[0];
732 
733  outlink->time_base = inlink->time_base;
734  outlink->frame_rate = inlink->frame_rate;
735  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
736  outlink->w = inlink->w;
737  outlink->h = inlink->h;
738 
739  return 0;
740 }
741 
742 static const AVFilterPad signature_outputs[] = {
743  {
744  .name = "default",
745  .type = AVMEDIA_TYPE_VIDEO,
746  .request_frame = request_frame,
747  .config_props = config_output,
748  },
749 };
750 
752  .name = "signature",
753  .description = NULL_IF_CONFIG_SMALL("Calculate the MPEG-7 video signature"),
754  .priv_size = sizeof(SignatureContext),
755  .priv_class = &signature_class,
756  .init = init,
757  .uninit = uninit,
759  .inputs = NULL,
762 };
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
put_bits32
static void av_unused put_bits32(PutBitContext *s, uint32_t value)
Write exactly 32 bits into a bitstream.
Definition: put_bits.h:290
StreamContext::coarsesiglist
CoarseSignature * coarsesiglist
Definition: signature.h:114
elements
static const ElemCat * elements[ELEMENT_COUNT]
Definition: signature.h:566
put_bytes_output
static int put_bytes_output(const PutBitContext *s)
Definition: put_bits.h:88
OFFSET
#define OFFSET(x)
Definition: vf_signature.c:39
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
signature_outputs
static const AVFilterPad signature_outputs[]
Definition: vf_signature.c:742
FineSignature::next
struct FineSignature * next
Definition: signature.h:73
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:171
set_bit
static void set_bit(uint8_t *data, size_t pos)
sets the bit at position pos to 1 in data
Definition: vf_signature.c:139
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
init_put_bits
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:61
FORMAT_BINARY
@ FORMAT_BINARY
Definition: signature.h:49
ElemCat::left_count
short left_count
Definition: signature.h:66
MatchingInfo
Definition: signature.h:90
StreamContext::curcoarsesig2
CoarseSignature * curcoarsesig2
Definition: signature.h:118
ElemCat::av_elem
int av_elem
Definition: signature.h:65
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:220
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:424
w
uint8_t w
Definition: llviddspenc.c:38
MatchingInfo::whole
int whole
Definition: signature.h:96
AVOption
AVOption.
Definition: opt.h:247
b
#define b
Definition: input.c:40
StreamContext::divide
int divide
Definition: signature.h:109
data
const char data[16]
Definition: mxf.c:143
MatchingInfo::score
int score
Definition: signature.h:93
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:420
float.h
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:169
av_get_frame_filename
int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
Definition: utils.c:1045
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:338
FineSignature::pts
uint64_t pts
Definition: signature.h:75
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
Definition: vf_signature.c:145
FineSignature::index
uint32_t index
Definition: signature.h:76
signature_options
static const AVOption signature_options[]
Definition: vf_signature.c:43
StreamContext::exported
int exported
Definition: signature.h:124
av_strerror
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
Definition: error.c:105
lookup_signatures
static MatchingInfo lookup_signatures(AVFilterContext *ctx, SignatureContext *sc, StreamContext *first, StreamContext *second, int mode)
Definition: signature_lookup.c:533
SignatureContext::mode
int mode
Definition: signature.h:130
AVFILTER_FLAG_DYNAMIC_INPUTS
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:110
AVRational::num
int num
Numerator.
Definition: rational.h:59
CoarseSignature::last
struct FineSignature * last
Definition: signature.h:85
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
signature
static const char signature[]
Definition: ipmovie.c:592
AV_PIX_FMT_YUVJ411P
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:248
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
get_block_sum
static uint64_t get_block_sum(StreamContext *sc, uint64_t intpic[32][32], const Block *b)
Definition: vf_signature.c:107
av_cold
#define av_cold
Definition: attributes.h:90
ElemCat::blocks
const Block * blocks
Definition: signature.h:69
ElemCat
Definition: signature.h:64
mask
static const uint16_t mask[17]
Definition: lzw.c:38
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
MODE_FAST
@ MODE_FAST
Definition: signature.h:44
CoarseSignature::first
struct FineSignature * first
Definition: signature.h:84
intreadwrite.h
SIGELEM_SIZE
#define SIGELEM_SIZE
Definition: signature.h:37
g
const char * g
Definition: vf_curves.c:117
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:226
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
SignatureContext::nb_inputs
int nb_inputs
Definition: signature.h:131
ctx
AVFormatContext * ctx
Definition: movenc.c:48
export
static int export(AVFilterContext *ctx, StreamContext *sc, int input)
Definition: vf_signature.c:565
ElemCat::block_count
short block_count
Definition: signature.h:67
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
NB_LOOKUP_MODE
@ NB_LOOKUP_MODE
Definition: signature.h:45
f
#define f(width, name)
Definition: cbs_vp9.c:255
PutBitContext
Definition: put_bits.h:49
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
BLOCK_LCM
#define BLOCK_LCM
Definition: vf_signature.c:41
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:65
ff_vf_signature
const AVFilter ff_vf_signature
Definition: vf_signature.c:751
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_signature.c:728
av_log_get_level
int av_log_get_level(void)
Get the current log level.
Definition: log.c:435
NULL
#define NULL
Definition: coverity.c:32
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:259
signature.h
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: vf_signature.c:584
ff_append_inpad_free_name
int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
Definition: avfilter.c:144
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_signature.c:693
cmp
static int cmp(const void *x, const void *y)
Definition: vf_signature.c:130
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
get_block_size
static int get_block_size(const Block *b)
Definition: vf_signature.c:102
MODE_FULL
@ MODE_FULL
Definition: signature.h:43
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(signature)
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
StreamContext
Definition: transcoding.c:51
Block
Definition: flashsv2enc.c:69
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_signature.c:85
signature_lookup.c
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_signature.c:73
format
ofilter format
Definition: ffmpeg_filter.c:172
StreamContext::midcoarse
int midcoarse
Definition: signature.h:121
StreamContext::curfinesig
FineSignature * curfinesig
Definition: signature.h:112
StreamContext::h
int h
Definition: signature.h:106
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
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
th
#define th
Definition: regdef.h:75
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
FineSignature
Definition: signature.h:72
internal.h
SignatureContext
Definition: signature.h:127
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
lookup
int lookup
Definition: vorbis_enc_data.h:428
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
StreamContext::coarsecount
int coarsecount
Definition: signature.h:120
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_YUVJ440P
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition: pixfmt.h:100
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:263
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_signature.c:640
AV_PIX_FMT_NV21
@ AV_PIX_FMT_NV21
as above, but U and V bytes are swapped
Definition: pixfmt.h:90
len
int len
Definition: vorbis_enc_data.h:426
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
xml_export
static int xml_export(AVFilterContext *ctx, StreamContext *sc, const char *filename)
Definition: vf_signature.c:381
MODE_OFF
@ MODE_OFF
Definition: signature.h:42
AVFilter
Filter definition.
Definition: avfilter.h:165
ret
ret
Definition: filter_design.txt:187
AVFilterPad::type
enum AVMediaType type
AVFilterPad type.
Definition: internal.h:61
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
pos
unsigned int pos
Definition: spdifenc.c:412
avformat.h
NB_FORMATS
@ NB_FORMATS
Definition: signature.h:51
CoarseSignature::data
uint8_t data[5][31]
Definition: signature.h:83
StreamContext::w
int w
Definition: signature.h:105
StreamContext::coarseend
CoarseSignature * coarseend
Definition: signature.h:115
CoarseSignature::next
struct CoarseSignature * next
Definition: signature.h:86
ElemCat::elem_count
short elem_count
Definition: signature.h:68
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
DIFFELEM_SIZE
#define DIFFELEM_SIZE
Definition: signature.h:38
AVRational::den
int den
Denominator.
Definition: rational.h:60
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
FF_INLINK_IDX
#define FF_INLINK_IDX(link)
Find the index of a link.
Definition: internal.h:334
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
avfilter.h
ELEMENT_COUNT
#define ELEMENT_COUNT
Definition: signature.h:36
binary_export
static int binary_export(AVFilterContext *ctx, StreamContext *sc, const char *filename)
Definition: vf_signature.c:487
MatchingInfo::second
struct FineSignature * second
Definition: signature.h:98
SignatureContext::filename
char * filename
Definition: signature.h:132
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
FLAGS
#define FLAGS
Definition: vf_signature.c:40
AVFilterContext
An instance of a filter.
Definition: avfilter.h:402
StreamContext::curcoarsesig1
CoarseSignature * curcoarsesig1
Definition: signature.h:117
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:142
FORMAT_XML
@ FORMAT_XML
Definition: signature.h:50
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:192
SignatureContext::format
int format
Definition: signature.h:133
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
MatchingInfo::first
struct FineSignature * first
Definition: signature.h:97
StreamContext::finesiglist
FineSignature * finesiglist
Definition: signature.h:111
int32_t
int32_t
Definition: audioconvert.c:56
timestamp.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:362
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
SignatureContext::streamcontexts
StreamContext * streamcontexts
Definition: signature.h:142
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
StreamContext::time_base
AVRational time_base
Definition: signature.h:103
int
int
Definition: ffmpeg_filter.c:153
put_bits.h
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
CoarseSignature
Definition: signature.h:82
MatchingInfo::matchframes
int matchframes
Definition: signature.h:95
StreamContext::lastindex
uint32_t lastindex
Definition: signature.h:122