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