FFmpeg
vf_readeia608.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * Filter for reading closed captioning data (EIA-608).
24  * See also https://en.wikipedia.org/wiki/EIA-608
25  */
26 
27 #include <string.h>
28 
29 #include "libavutil/internal.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/pixdesc.h"
32 #include "libavutil/timestamp.h"
33 
34 #include "avfilter.h"
35 #include "formats.h"
36 #include "internal.h"
37 #include "video.h"
38 
39 #define LAG 25
40 #define CLOCK_BITSIZE_MIN 0.2f
41 #define CLOCK_BITSIZE_MAX 1.5f
42 #define SYNC_BITSIZE_MIN 12.f
43 #define SYNC_BITSIZE_MAX 15.f
44 
45 typedef struct LineItem {
46  int input;
47  int output;
48 
49  float unfiltered;
50  float filtered;
51  float average;
52  float deviation;
53 } LineItem;
54 
55 typedef struct CodeItem {
56  uint8_t bit;
57  int size;
58 } CodeItem;
59 
60 typedef struct ScanItem {
61  int nb_line;
62  int found;
63  int white;
64  int black;
65  uint64_t *histogram;
66  uint8_t byte[2];
67 
70 } ScanItem;
71 
72 typedef struct ReadEIA608Context {
73  const AVClass *class;
74 
75  int start, end;
76  float spw;
77  int chp;
78  int lp;
79 
80  int depth;
81  int max;
84 
85  void (*read_line[2])(AVFrame *in, int nb_line,
86  LineItem *line, int lp, int w);
88 
89 #define OFFSET(x) offsetof(ReadEIA608Context, x)
90 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
91 
92 static const AVOption readeia608_options[] = {
93  { "scan_min", "set from which line to scan for codes", OFFSET(start), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
94  { "scan_max", "set to which line to scan for codes", OFFSET(end), AV_OPT_TYPE_INT, {.i64=29}, 0, INT_MAX, FLAGS },
95  { "spw", "set ratio of width reserved for sync code detection", OFFSET(spw), AV_OPT_TYPE_FLOAT, {.dbl=.27}, 0.1, 0.7, FLAGS },
96  { "chp", "check and apply parity bit", OFFSET(chp), AV_OPT_TYPE_BOOL, {.i64= 0}, 0, 1, FLAGS },
97  { "lp", "lowpass line prior to processing", OFFSET(lp), AV_OPT_TYPE_BOOL, {.i64= 1}, 0, 1, FLAGS },
98  { NULL }
99 };
100 
101 AVFILTER_DEFINE_CLASS(readeia608);
102 
103 static const enum AVPixelFormat pixel_fmts[] = {
125 };
126 
127 static int config_filter(AVFilterContext *ctx, int start, int end)
128 {
129  ReadEIA608Context *s = ctx->priv;
130  AVFilterLink *inlink = ctx->inputs[0];
131  int size = inlink->w + LAG;
132 
133  if (end >= inlink->h) {
134  av_log(ctx, AV_LOG_WARNING, "Last line to scan too large, clipping.\n");
135  end = inlink->h - 1;
136  }
137 
138  if (start > end) {
139  av_log(ctx, AV_LOG_ERROR, "Invalid range.\n");
140  return AVERROR(EINVAL);
141  }
142 
143  if (s->nb_allocated < end - start + 1) {
144  const int diff = end - start + 1 - s->nb_allocated;
145 
146  s->scan = av_realloc_f(s->scan, end - start + 1, sizeof(*s->scan));
147  if (!s->scan)
148  return AVERROR(ENOMEM);
149  memset(&s->scan[s->nb_allocated], 0, diff * sizeof(*s->scan));
150  s->nb_allocated = end - start + 1;
151  }
152 
153  for (int i = 0; i < s->nb_allocated; i++) {
154  ScanItem *scan = &s->scan[i];
155 
156  if (!scan->histogram)
157  scan->histogram = av_calloc(s->max + 1, sizeof(*scan->histogram));
158  if (!scan->line)
159  scan->line = av_calloc(size, sizeof(*scan->line));
160  if (!scan->code)
161  scan->code = av_calloc(size, sizeof(*scan->code));
162  if (!scan->line || !scan->code || !scan->histogram)
163  return AVERROR(ENOMEM);
164  }
165 
166  s->start = start;
167  s->end = end;
168 
169  return 0;
170 }
171 
172 static void build_histogram(ReadEIA608Context *s, ScanItem *scan, const LineItem *line, int len)
173 {
174  memset(scan->histogram, 0, (s->max + 1) * sizeof(*scan->histogram));
175 
176  for (int i = LAG; i < len + LAG; i++)
177  scan->histogram[line[i].input]++;
178 }
179 
181 {
182  const int max = s->max;
183  int start = 0, end = 0, middle;
184  int black = 0, white = 0;
185  int cnt;
186 
187  for (int i = 0; i <= max; i++) {
188  if (scan->histogram[i]) {
189  start = i;
190  break;
191  }
192  }
193 
194  for (int i = max; i >= 0; i--) {
195  if (scan->histogram[i]) {
196  end = i;
197  break;
198  }
199  }
200 
201  middle = start + (end - start) / 2;
202 
203  cnt = 0;
204  for (int i = start; i <= middle; i++) {
205  if (scan->histogram[i] > cnt) {
206  cnt = scan->histogram[i];
207  black = i;
208  }
209  }
210 
211  cnt = 0;
212  for (int i = end; i >= middle; i--) {
213  if (scan->histogram[i] > cnt) {
214  cnt = scan->histogram[i];
215  white = i;
216  }
217  }
218 
219  scan->black = black;
220  scan->white = white;
221 }
222 
223 static float meanf(const LineItem *line, int len)
224 {
225  float sum = 0.0, mean = 0.0;
226 
227  for (int i = 0; i < len; i++)
228  sum += line[i].filtered;
229 
230  mean = sum / len;
231 
232  return mean;
233 }
234 
235 static float stddevf(const LineItem *line, int len)
236 {
237  float m = meanf(line, len);
238  float standard_deviation = 0.f;
239 
240  for (int i = 0; i < len; i++)
241  standard_deviation += (line[i].filtered - m) * (line[i].filtered - m);
242 
243  return sqrtf(standard_deviation / (len - 1));
244 }
245 
247  int lag, float threshold, float influence, int len)
248 {
249  for (int i = lag; i < len + lag; i++) {
250  line[i].unfiltered = line[i].input / 255.f;
251  line[i].filtered = line[i].unfiltered;
252  }
253 
254  for (int i = 0; i < lag; i++) {
255  line[i].unfiltered = meanf(line, len * s->spw);
256  line[i].filtered = line[i].unfiltered;
257  }
258 
259  line[lag - 1].average = meanf(line, lag);
260  line[lag - 1].deviation = stddevf(line, lag);
261 
262  for (int i = lag; i < len + lag; i++) {
263  if (fabsf(line[i].unfiltered - line[i-1].average) > threshold * line[i-1].deviation) {
264  if (line[i].unfiltered > line[i-1].average) {
265  line[i].output = 255;
266  } else {
267  line[i].output = 0;
268  }
269 
270  line[i].filtered = influence * line[i].unfiltered + (1.f - influence) * line[i-1].filtered;
271  } else {
272  int distance_from_black, distance_from_white;
273 
274  distance_from_black = FFABS(line[i].input - scan->black);
275  distance_from_white = FFABS(line[i].input - scan->white);
276 
277  line[i].output = distance_from_black <= distance_from_white ? 0 : 255;
278  }
279 
280  line[i].average = meanf(line + i - lag, lag);
281  line[i].deviation = stddevf(line + i - lag, lag);
282  }
283 }
284 
285 static int periods(const LineItem *line, CodeItem *code, int len)
286 {
287  int hold = line[LAG].output, cnt = 0;
288  int last = LAG;
289 
290  memset(code, 0, len * sizeof(*code));
291 
292  for (int i = LAG + 1; i < len + LAG; i++) {
293  if (line[i].output != hold) {
294  code[cnt].size = i - last;
295  code[cnt].bit = hold;
296  hold = line[i].output;
297  last = i;
298  cnt++;
299  }
300  }
301 
302  code[cnt].size = LAG + len - last;
303  code[cnt].bit = hold;
304 
305  return cnt + 1;
306 }
307 
308 static void dump_code(AVFilterContext *ctx, ScanItem *scan, int len, int item)
309 {
310  av_log(ctx, AV_LOG_DEBUG, "%d:", item);
311  for (int i = 0; i < len; i++) {
312  av_log(ctx, AV_LOG_DEBUG, " %03d", scan->code[i].size);
313  }
314  av_log(ctx, AV_LOG_DEBUG, "\n");
315 }
316 
317 #define READ_LINE(type, name) \
318 static void read_##name(AVFrame *in, int nb_line, LineItem *line, int lp, int w) \
319 { \
320  const type *src = (const type *)(&in->data[0][nb_line * in->linesize[0]]);\
321  \
322  if (lp) { \
323  for (int i = 0; i < w; i++) { \
324  int a = FFMAX(i - 3, 0); \
325  int b = FFMAX(i - 2, 0); \
326  int c = FFMAX(i - 1, 0); \
327  int d = FFMIN(i + 3, w-1); \
328  int e = FFMIN(i + 2, w-1); \
329  int f = FFMIN(i + 1, w-1); \
330  \
331  line[LAG + i].input = (src[a] + src[b] + src[c] + src[i] + \
332  src[d] + src[e] + src[f] + 6) / 7; \
333  } \
334  } else { \
335  for (int i = 0; i < w; i++) { \
336  line[LAG + i].input = src[i]; \
337  } \
338  } \
339 }
340 
341 READ_LINE(uint8_t, byte)
342 READ_LINE(uint16_t, word)
343 
345 {
346  AVFilterContext *ctx = inlink->dst;
347  ReadEIA608Context *s = ctx->priv;
349 
350  if (!desc)
351  return AVERROR_BUG;
352  s->depth = desc->comp[0].depth;
353  s->max = (1 << desc->comp[0].depth) - 1;
354  s->read_line[0] = read_byte;
355  s->read_line[1] = read_word;
356 
357  return config_filter(ctx, s->start, s->end);
358 }
359 
360 static void extract_line(AVFilterContext *ctx, AVFrame *in, ScanItem *scan, int w, int nb_line)
361 {
362  ReadEIA608Context *s = ctx->priv;
363  LineItem *line = scan->line;
364  int i, j, ch, len;
365  uint8_t codes[19] = { 0 };
366  float bit_size = 0.f;
367  int parity;
368 
369  memset(line, 0, (w + LAG) * sizeof(*line));
370  scan->byte[0] = scan->byte[1] = 0;
371  scan->found = 0;
372 
373  s->read_line[s->depth > 8](in, nb_line, line, s->lp, w);
374 
375  build_histogram(s, scan, line, w);
376  find_black_and_white(s, scan);
377  if (scan->white - scan->black < 5)
378  return;
379 
380  thresholding(s, scan, line, LAG, 1, 0, w);
381  len = periods(line, scan->code, w);
382  dump_code(ctx, scan, len, nb_line);
383  if (len < 15 ||
384  scan->code[14].bit != 0 ||
385  w / (float)scan->code[14].size < SYNC_BITSIZE_MIN ||
386  w / (float)scan->code[14].size > SYNC_BITSIZE_MAX) {
387  return;
388  }
389 
390  for (i = 14; i < len; i++) {
391  bit_size += scan->code[i].size;
392  }
393 
394  bit_size /= 19.f;
395  for (i = 1; i < 14; i++) {
396  if (scan->code[i].size / bit_size > CLOCK_BITSIZE_MAX ||
397  scan->code[i].size / bit_size < CLOCK_BITSIZE_MIN) {
398  return;
399  }
400  }
401 
402  if (scan->code[15].size / bit_size < 0.45f) {
403  return;
404  }
405 
406  for (j = 0, i = 14; i < len; i++) {
407  int run, bit;
408 
409  run = lrintf(scan->code[i].size / bit_size);
410  bit = scan->code[i].bit;
411 
412  for (int k = 0; j < 19 && k < run; k++) {
413  codes[j++] = bit;
414  }
415 
416  if (j >= 19)
417  break;
418  }
419 
420  for (ch = 0; ch < 2; ch++) {
421  for (parity = 0, i = 0; i < 8; i++) {
422  int b = codes[3 + ch * 8 + i];
423 
424  if (b == 255) {
425  parity++;
426  b = 1;
427  } else {
428  b = 0;
429  }
430  scan->byte[ch] |= b << i;
431  }
432 
433  if (s->chp) {
434  if (!(parity & 1)) {
435  scan->byte[ch] = 0x7F;
436  }
437  }
438  }
439 
440  scan->nb_line = nb_line;
441  scan->found = 1;
442 }
443 
445  int job, int nb_jobs)
446 {
447  ReadEIA608Context *s = ctx->priv;
448  AVFilterLink *inlink = ctx->inputs[0];
449  const int h = s->end - s->start + 1;
450  const int start = (h * job) / nb_jobs;
451  const int end = (h * (job+1)) / nb_jobs;
452  AVFrame *in = arg;
453 
454  for (int i = start; i < end; i++) {
455  ScanItem *scan = &s->scan[i];
456 
457  extract_line(ctx, in, scan, inlink->w, s->start + i);
458  }
459 
460  return 0;
461 }
462 
464 {
465  AVFilterContext *ctx = inlink->dst;
466  AVFilterLink *outlink = ctx->outputs[0];
467  ReadEIA608Context *s = ctx->priv;
468  int nb_found;
469 
471  FFMIN(FFMAX(s->end - s->start + 1, 1), ff_filter_get_nb_threads(ctx)));
472 
473  nb_found = 0;
474  for (int i = 0; i < s->end - s->start + 1; i++) {
475  ScanItem *scan = &s->scan[i];
476  uint8_t key[128], value[128];
477 
478  if (!scan->found)
479  continue;
480 
481  //snprintf(key, sizeof(key), "lavfi.readeia608.%d.bits", nb_found);
482  //snprintf(value, sizeof(value), "0b%d%d%d%d%d%d%d%d 0b%d%d%d%d%d%d%d%d", codes[3]==255,codes[4]==255,codes[5]==255,codes[6]==255,codes[7]==255,codes[8]==255,codes[9]==255,codes[10]==255,codes[11]==255,codes[12]==255,codes[13]==255,codes[14]==255,codes[15]==255,codes[16]==255,codes[17]==255,codes[18]==255);
483  //av_dict_set(&in->metadata, key, value, 0);
484 
485  snprintf(key, sizeof(key), "lavfi.readeia608.%d.cc", nb_found);
486  snprintf(value, sizeof(value), "0x%02X%02X", scan->byte[0], scan->byte[1]);
487  av_dict_set(&in->metadata, key, value, 0);
488 
489  snprintf(key, sizeof(key), "lavfi.readeia608.%d.line", nb_found);
490  av_dict_set_int(&in->metadata, key, scan->nb_line, 0);
491 
492  nb_found++;
493  }
494 
495  return ff_filter_frame(outlink, in);
496 }
497 
499 {
500  ReadEIA608Context *s = ctx->priv;
501 
502  for (int i = 0; i < s->nb_allocated; i++) {
503  ScanItem *scan = &s->scan[i];
504 
505  av_freep(&scan->histogram);
506  av_freep(&scan->code);
507  av_freep(&scan->line);
508  }
509 
510  s->nb_allocated = 0;
511  av_freep(&s->scan);
512 }
513 
514 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
515  char *res, int res_len, int flags)
516 {
517  ReadEIA608Context *s = ctx->priv;
518  int ret, start = s->start, end = s->end;
519 
520  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
521  if (ret < 0)
522  return ret;
523 
524  ret = config_filter(ctx, s->start, s->end);
525  if (ret < 0) {
526  s->start = start;
527  s->end = end;
528  }
529 
530  return 0;
531 }
532 
533 static const AVFilterPad readeia608_inputs[] = {
534  {
535  .name = "default",
536  .type = AVMEDIA_TYPE_VIDEO,
537  .filter_frame = filter_frame,
538  .config_props = config_input,
539  },
540 };
541 
542 static const AVFilterPad readeia608_outputs[] = {
543  {
544  .name = "default",
545  .type = AVMEDIA_TYPE_VIDEO,
546  },
547 };
548 
550  .name = "readeia608",
551  .description = NULL_IF_CONFIG_SMALL("Read EIA-608 Closed Caption codes from input video and write them to frame metadata."),
552  .priv_size = sizeof(ReadEIA608Context),
553  .priv_class = &readeia608_class,
557  .uninit = uninit,
561  .process_command = process_command,
562 };
CodeItem::size
int size
Definition: vf_readeia608.c:57
LineItem::average
float average
Definition: vf_readeia608.c:51
AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:449
ReadEIA608Context::spw
float spw
Definition: vf_readeia608.c:76
LineItem::filtered
float filtered
Definition: vf_readeia608.c:50
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
CodeItem::bit
uint8_t bit
Definition: vf_readeia608.c:56
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
ScanItem::white
int white
Definition: vf_readeia608.c:63
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
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_readeia608.c:514
ReadEIA608Context::end
int end
Definition: vf_readeia608.c:75
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:999
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2662
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:170
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
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
ReadEIA608Context::start
int start
Definition: vf_readeia608.c:75
AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:441
readeia608_options
static const AVOption readeia608_options[]
Definition: vf_readeia608.c:92
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
pixdesc.h
AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:448
w
uint8_t w
Definition: llviddspenc.c:38
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:443
AVOption
AVOption.
Definition: opt.h:251
b
#define b
Definition: input.c:34
ff_vf_readeia608
const AVFilter ff_vf_readeia608
Definition: vf_readeia608.c:549
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:406
LineItem::output
int output
Definition: vf_readeia608.c:47
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
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:175
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_readeia608.c:463
video.h
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:444
AV_PIX_FMT_GRAY9
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:386
formats.h
bit
#define bit(string, value)
Definition: cbs_mpeg2.c:58
ScanItem::histogram
uint64_t * histogram
Definition: vf_readeia608.c:65
AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:440
meanf
static float meanf(const LineItem *line, int len)
Definition: vf_readeia608.c:223
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:450
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:404
ScanItem::found
int found
Definition: vf_readeia608.c:62
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:390
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
ScanItem::nb_line
int nb_line
Definition: vf_readeia608.c:61
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:409
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
extract_lines
static int extract_lines(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
Definition: vf_readeia608.c:444
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:418
ReadEIA608Context
Definition: vf_readeia608.c:72
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
s
#define s(width, name)
Definition: cbs_vp9.c:256
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:419
ReadEIA608Context::max
int max
Definition: vf_readeia608.c:81
AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:447
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:403
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:417
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:389
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
pixel_fmts
static enum AVPixelFormat pixel_fmts[]
Definition: vf_readeia608.c:103
key
const char * key
Definition: hwcontext_opencl.c:174
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:190
periods
static int periods(const LineItem *line, CodeItem *code, int len)
Definition: vf_readeia608.c:285
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
ReadEIA608Context::read_line
void(* read_line[2])(AVFrame *in, int nb_line, LineItem *line, int lp, int w)
Definition: vf_readeia608.c:85
arg
const char * arg
Definition: jacosubdec.c:67
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:64
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:387
ScanItem::byte
uint8_t byte[2]
Definition: vf_readeia608.c:66
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(readeia608)
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:32
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
FLAGS
#define FLAGS
Definition: vf_readeia608.c:90
ScanItem
Definition: vf_readeia608.c:60
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:205
LineItem::unfiltered
float unfiltered
Definition: vf_readeia608.c:49
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
ReadEIA608Context::depth
int depth
Definition: vf_readeia608.c:80
AV_PIX_FMT_YUV440P10
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:408
find_black_and_white
static void find_black_and_white(ReadEIA608Context *s, ScanItem *scan)
Definition: vf_readeia608.c:180
sqrtf
static __device__ float sqrtf(float a)
Definition: cuda_runtime.h:184
ReadEIA608Context::scan
ScanItem * scan
Definition: vf_readeia608.c:83
readeia608_inputs
static const AVFilterPad readeia608_inputs[]
Definition: vf_readeia608.c:533
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:407
ReadEIA608Context::nb_allocated
int nb_allocated
Definition: vf_readeia608.c:82
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
READ_LINE
#define READ_LINE(type, name)
Definition: vf_readeia608.c:317
ReadEIA608Context::lp
int lp
Definition: vf_readeia608.c:78
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_readeia608.c:498
thresholding
static void thresholding(ReadEIA608Context *s, ScanItem *scan, LineItem *line, int lag, float threshold, float influence, int len)
Definition: vf_readeia608.c:246
LineItem::input
int input
Definition: vf_readeia608.c:46
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
dump_code
static void dump_code(AVFilterContext *ctx, ScanItem *scan, int len, int item)
Definition: vf_readeia608.c:308
stddevf
static float stddevf(const LineItem *line, int len)
Definition: vf_readeia608.c:235
OFFSET
#define OFFSET(x)
Definition: vf_readeia608.c:89
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:411
size
int size
Definition: twinvq_data.h:10344
readeia608_outputs
static const AVFilterPad readeia608_outputs[]
Definition: vf_readeia608.c:542
CodeItem
Definition: vf_readeia608.c:55
parity
mcdeint parity
Definition: vf_mcdeint.c:266
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:413
ScanItem::black
int black
Definition: vf_readeia608.c:64
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:863
SYNC_BITSIZE_MAX
#define SYNC_BITSIZE_MAX
Definition: vf_readeia608.c:43
build_histogram
static void build_histogram(ReadEIA608Context *s, ScanItem *scan, const LineItem *line, int len)
Definition: vf_readeia608.c:172
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:167
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:445
line
Definition: graph2dot.c:48
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
internal.h
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:152
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_readeia608.c:344
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
code
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 it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
extract_line
static void extract_line(AVFilterContext *ctx, AVFrame *in, ScanItem *scan, int w, int nb_line)
Definition: vf_readeia608.c:360
internal.h
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:783
value
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 default value
Definition: writing_filters.txt:86
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
len
int len
Definition: vorbis_enc_data.h:426
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:405
AVFilter
Filter definition.
Definition: avfilter.h:171
CLOCK_BITSIZE_MAX
#define CLOCK_BITSIZE_MAX
Definition: vf_readeia608.c:41
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:442
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:410
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:415
LineItem::deviation
float deviation
Definition: vf_readeia608.c:52
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:446
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
AVFrame::metadata
AVDictionary * metadata
metadata.
Definition: frame.h:620
AVFILTER_FLAG_METADATA_ONLY
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition: avfilter.h:143
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:857
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
AVFilterContext
An instance of a filter.
Definition: avfilter.h:408
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set that converts the value to a string and stores it.
Definition: dict.c:147
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:127
desc
const char * desc
Definition: libsvtav1.c:83
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
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
diff
static av_always_inline int diff(const uint32_t a, const uint32_t b)
Definition: vf_palettegen.c:139
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:191
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
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
ScanItem::code
CodeItem * code
Definition: vf_readeia608.c:68
ScanItem::line
LineItem * line
Definition: vf_readeia608.c:69
timestamp.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
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_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:412
h
h
Definition: vp9dsp_template.c:2038
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:416
ReadEIA608Context::chp
int chp
Definition: vf_readeia608.c:77
LAG
#define LAG
Definition: vf_readeia608.c:39
SYNC_BITSIZE_MIN
#define SYNC_BITSIZE_MIN
Definition: vf_readeia608.c:42
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:388
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:142
snprintf
#define snprintf
Definition: snprintf.h:34
LineItem
Definition: vf_readeia608.c:45
config_filter
static int config_filter(AVFilterContext *ctx, int start, int end)
Definition: vf_readeia608.c:127
line
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
Definition: swscale.txt:40
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:166
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:414
CLOCK_BITSIZE_MIN
#define CLOCK_BITSIZE_MIN
Definition: vf_readeia608.c:40