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/mem.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/pixdesc.h"
33 
34 #include "avfilter.h"
35 #include "internal.h"
36 #include "video.h"
37 
38 #define LAG 25
39 #define CLOCK_BITSIZE_MIN 0.2f
40 #define CLOCK_BITSIZE_MAX 1.5f
41 #define SYNC_BITSIZE_MIN 12.f
42 #define SYNC_BITSIZE_MAX 15.f
43 
44 typedef struct LineItem {
45  int input;
46  int output;
47 
48  float unfiltered;
49  float filtered;
50  float average;
51  float deviation;
52 } LineItem;
53 
54 typedef struct CodeItem {
55  uint8_t bit;
56  int size;
57 } CodeItem;
58 
59 typedef struct ScanItem {
60  int nb_line;
61  int found;
62  int white;
63  int black;
64  uint64_t *histogram;
65  uint8_t byte[2];
66 
69 } ScanItem;
70 
71 typedef struct ReadEIA608Context {
72  const AVClass *class;
73 
74  int start, end;
75  float spw;
76  int chp;
77  int lp;
78 
79  int depth;
80  int max;
83 
84  void (*read_line[2])(AVFrame *in, int nb_line,
85  LineItem *line, int lp, int w);
87 
88 #define OFFSET(x) offsetof(ReadEIA608Context, x)
89 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
90 
91 static const AVOption readeia608_options[] = {
92  { "scan_min", "set from which line to scan for codes", OFFSET(start), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
93  { "scan_max", "set to which line to scan for codes", OFFSET(end), AV_OPT_TYPE_INT, {.i64=29}, 0, INT_MAX, FLAGS },
94  { "spw", "set ratio of width reserved for sync code detection", OFFSET(spw), AV_OPT_TYPE_FLOAT, {.dbl=.27}, 0.1, 0.7, FLAGS },
95  { "chp", "check and apply parity bit", OFFSET(chp), AV_OPT_TYPE_BOOL, {.i64= 0}, 0, 1, FLAGS },
96  { "lp", "lowpass line prior to processing", OFFSET(lp), AV_OPT_TYPE_BOOL, {.i64= 1}, 0, 1, FLAGS },
97  { NULL }
98 };
99 
100 AVFILTER_DEFINE_CLASS(readeia608);
101 
102 static const enum AVPixelFormat pixel_fmts[] = {
124 };
125 
126 static int config_filter(AVFilterContext *ctx, int start, int end)
127 {
128  ReadEIA608Context *s = ctx->priv;
129  AVFilterLink *inlink = ctx->inputs[0];
130  int size = inlink->w + LAG;
131 
132  if (end >= inlink->h) {
133  av_log(ctx, AV_LOG_WARNING, "Last line to scan too large, clipping.\n");
134  end = inlink->h - 1;
135  }
136 
137  if (start > end) {
138  av_log(ctx, AV_LOG_ERROR, "Invalid range.\n");
139  return AVERROR(EINVAL);
140  }
141 
142  if (s->nb_allocated < end - start + 1) {
143  const int diff = end - start + 1 - s->nb_allocated;
144 
145  s->scan = av_realloc_f(s->scan, end - start + 1, sizeof(*s->scan));
146  if (!s->scan)
147  return AVERROR(ENOMEM);
148  memset(&s->scan[s->nb_allocated], 0, diff * sizeof(*s->scan));
149  s->nb_allocated = end - start + 1;
150  }
151 
152  for (int i = 0; i < s->nb_allocated; i++) {
153  ScanItem *scan = &s->scan[i];
154 
155  if (!scan->histogram)
156  scan->histogram = av_calloc(s->max + 1, sizeof(*scan->histogram));
157  if (!scan->line)
158  scan->line = av_calloc(size, sizeof(*scan->line));
159  if (!scan->code)
160  scan->code = av_calloc(size, sizeof(*scan->code));
161  if (!scan->line || !scan->code || !scan->histogram)
162  return AVERROR(ENOMEM);
163  }
164 
165  s->start = start;
166  s->end = end;
167 
168  return 0;
169 }
170 
171 static void build_histogram(ReadEIA608Context *s, ScanItem *scan, const LineItem *line, int len)
172 {
173  memset(scan->histogram, 0, (s->max + 1) * sizeof(*scan->histogram));
174 
175  for (int i = LAG; i < len + LAG; i++)
176  scan->histogram[line[i].input]++;
177 }
178 
180 {
181  const int max = s->max;
182  int start = 0, end = 0, middle;
183  int black = 0, white = 0;
184  int cnt;
185 
186  for (int i = 0; i <= max; i++) {
187  if (scan->histogram[i]) {
188  start = i;
189  break;
190  }
191  }
192 
193  for (int i = max; i >= 0; i--) {
194  if (scan->histogram[i]) {
195  end = i;
196  break;
197  }
198  }
199 
200  middle = start + (end - start) / 2;
201 
202  cnt = 0;
203  for (int i = start; i <= middle; i++) {
204  if (scan->histogram[i] > cnt) {
205  cnt = scan->histogram[i];
206  black = i;
207  }
208  }
209 
210  cnt = 0;
211  for (int i = end; i >= middle; i--) {
212  if (scan->histogram[i] > cnt) {
213  cnt = scan->histogram[i];
214  white = i;
215  }
216  }
217 
218  scan->black = black;
219  scan->white = white;
220 }
221 
222 static float meanf(const LineItem *line, int len)
223 {
224  float sum = 0.0, mean = 0.0;
225 
226  for (int i = 0; i < len; i++)
227  sum += line[i].filtered;
228 
229  mean = sum / len;
230 
231  return mean;
232 }
233 
234 static float stddevf(const LineItem *line, int len)
235 {
236  float m = meanf(line, len);
237  float standard_deviation = 0.f;
238 
239  for (int i = 0; i < len; i++)
240  standard_deviation += (line[i].filtered - m) * (line[i].filtered - m);
241 
242  return sqrtf(standard_deviation / (len - 1));
243 }
244 
246  int lag, float threshold, float influence, int len)
247 {
248  for (int i = lag; i < len + lag; i++) {
249  line[i].unfiltered = line[i].input / 255.f;
250  line[i].filtered = line[i].unfiltered;
251  }
252 
253  for (int i = 0; i < lag; i++) {
254  line[i].unfiltered = meanf(line, len * s->spw);
255  line[i].filtered = line[i].unfiltered;
256  }
257 
258  line[lag - 1].average = meanf(line, lag);
259  line[lag - 1].deviation = stddevf(line, lag);
260 
261  for (int i = lag; i < len + lag; i++) {
262  if (fabsf(line[i].unfiltered - line[i-1].average) > threshold * line[i-1].deviation) {
263  if (line[i].unfiltered > line[i-1].average) {
264  line[i].output = 255;
265  } else {
266  line[i].output = 0;
267  }
268 
269  line[i].filtered = influence * line[i].unfiltered + (1.f - influence) * line[i-1].filtered;
270  } else {
271  int distance_from_black, distance_from_white;
272 
273  distance_from_black = FFABS(line[i].input - scan->black);
274  distance_from_white = FFABS(line[i].input - scan->white);
275 
276  line[i].output = distance_from_black <= distance_from_white ? 0 : 255;
277  }
278 
279  line[i].average = meanf(line + i - lag, lag);
280  line[i].deviation = stddevf(line + i - lag, lag);
281  }
282 }
283 
284 static int periods(const LineItem *line, CodeItem *code, int len)
285 {
286  int hold = line[LAG].output, cnt = 0;
287  int last = LAG;
288 
289  memset(code, 0, len * sizeof(*code));
290 
291  for (int i = LAG + 1; i < len + LAG; i++) {
292  if (line[i].output != hold) {
293  code[cnt].size = i - last;
294  code[cnt].bit = hold;
295  hold = line[i].output;
296  last = i;
297  cnt++;
298  }
299  }
300 
301  code[cnt].size = LAG + len - last;
302  code[cnt].bit = hold;
303 
304  return cnt + 1;
305 }
306 
307 static void dump_code(AVFilterContext *ctx, ScanItem *scan, int len, int item)
308 {
309  av_log(ctx, AV_LOG_DEBUG, "%d:", item);
310  for (int i = 0; i < len; i++) {
311  av_log(ctx, AV_LOG_DEBUG, " %03d", scan->code[i].size);
312  }
313  av_log(ctx, AV_LOG_DEBUG, "\n");
314 }
315 
316 #define READ_LINE(type, name) \
317 static void read_##name(AVFrame *in, int nb_line, LineItem *line, int lp, int w) \
318 { \
319  const type *src = (const type *)(&in->data[0][nb_line * in->linesize[0]]);\
320  \
321  if (lp) { \
322  for (int i = 0; i < w; i++) { \
323  int a = FFMAX(i - 3, 0); \
324  int b = FFMAX(i - 2, 0); \
325  int c = FFMAX(i - 1, 0); \
326  int d = FFMIN(i + 3, w-1); \
327  int e = FFMIN(i + 2, w-1); \
328  int f = FFMIN(i + 1, w-1); \
329  \
330  line[LAG + i].input = (src[a] + src[b] + src[c] + src[i] + \
331  src[d] + src[e] + src[f] + 6) / 7; \
332  } \
333  } else { \
334  for (int i = 0; i < w; i++) { \
335  line[LAG + i].input = src[i]; \
336  } \
337  } \
338 }
339 
340 READ_LINE(uint8_t, byte)
341 READ_LINE(uint16_t, word)
342 
344 {
345  AVFilterContext *ctx = inlink->dst;
346  ReadEIA608Context *s = ctx->priv;
348 
349  if (!desc)
350  return AVERROR_BUG;
351  s->depth = desc->comp[0].depth;
352  s->max = (1 << desc->comp[0].depth) - 1;
353  s->read_line[0] = read_byte;
354  s->read_line[1] = read_word;
355 
356  return config_filter(ctx, s->start, s->end);
357 }
358 
359 static void extract_line(AVFilterContext *ctx, AVFrame *in, ScanItem *scan, int w, int nb_line)
360 {
361  ReadEIA608Context *s = ctx->priv;
362  LineItem *line = scan->line;
363  int i, j, ch, len;
364  uint8_t codes[19] = { 0 };
365  float bit_size = 0.f;
366  int parity;
367 
368  memset(line, 0, (w + LAG) * sizeof(*line));
369  scan->byte[0] = scan->byte[1] = 0;
370  scan->found = 0;
371 
372  s->read_line[s->depth > 8](in, nb_line, line, s->lp, w);
373 
374  build_histogram(s, scan, line, w);
375  find_black_and_white(s, scan);
376  if (scan->white - scan->black < 5)
377  return;
378 
379  thresholding(s, scan, line, LAG, 1, 0, w);
380  len = periods(line, scan->code, w);
381  dump_code(ctx, scan, len, nb_line);
382  if (len < 15 ||
383  scan->code[14].bit != 0 ||
384  w / (float)scan->code[14].size < SYNC_BITSIZE_MIN ||
385  w / (float)scan->code[14].size > SYNC_BITSIZE_MAX) {
386  return;
387  }
388 
389  for (i = 14; i < len; i++) {
390  bit_size += scan->code[i].size;
391  }
392 
393  bit_size /= 19.f;
394  for (i = 1; i < 14; i++) {
395  if (scan->code[i].size / bit_size > CLOCK_BITSIZE_MAX ||
396  scan->code[i].size / bit_size < CLOCK_BITSIZE_MIN) {
397  return;
398  }
399  }
400 
401  if (scan->code[15].size / bit_size < 0.45f) {
402  return;
403  }
404 
405  for (j = 0, i = 14; i < len; i++) {
406  int run, bit;
407 
408  run = lrintf(scan->code[i].size / bit_size);
409  bit = scan->code[i].bit;
410 
411  for (int k = 0; j < 19 && k < run; k++) {
412  codes[j++] = bit;
413  }
414 
415  if (j >= 19)
416  break;
417  }
418 
419  for (ch = 0; ch < 2; ch++) {
420  for (parity = 0, i = 0; i < 8; i++) {
421  int b = codes[3 + ch * 8 + i];
422 
423  if (b == 255) {
424  parity++;
425  b = 1;
426  } else {
427  b = 0;
428  }
429  scan->byte[ch] |= b << i;
430  }
431 
432  if (s->chp) {
433  if (!(parity & 1)) {
434  scan->byte[ch] = 0x7F;
435  }
436  }
437  }
438 
439  scan->nb_line = nb_line;
440  scan->found = 1;
441 }
442 
444  int job, int nb_jobs)
445 {
446  ReadEIA608Context *s = ctx->priv;
447  AVFilterLink *inlink = ctx->inputs[0];
448  const int h = s->end - s->start + 1;
449  const int start = (h * job) / nb_jobs;
450  const int end = (h * (job+1)) / nb_jobs;
451  AVFrame *in = arg;
452 
453  for (int i = start; i < end; i++) {
454  ScanItem *scan = &s->scan[i];
455 
456  extract_line(ctx, in, scan, inlink->w, s->start + i);
457  }
458 
459  return 0;
460 }
461 
463 {
464  AVFilterContext *ctx = inlink->dst;
465  AVFilterLink *outlink = ctx->outputs[0];
466  ReadEIA608Context *s = ctx->priv;
467  int nb_found;
468 
470  FFMIN(FFMAX(s->end - s->start + 1, 1), ff_filter_get_nb_threads(ctx)));
471 
472  nb_found = 0;
473  for (int i = 0; i < s->end - s->start + 1; i++) {
474  ScanItem *scan = &s->scan[i];
475  uint8_t key[128], value[128];
476 
477  if (!scan->found)
478  continue;
479 
480  //snprintf(key, sizeof(key), "lavfi.readeia608.%d.bits", nb_found);
481  //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);
482  //av_dict_set(&in->metadata, key, value, 0);
483 
484  snprintf(key, sizeof(key), "lavfi.readeia608.%d.cc", nb_found);
485  snprintf(value, sizeof(value), "0x%02X%02X", scan->byte[0], scan->byte[1]);
486  av_dict_set(&in->metadata, key, value, 0);
487 
488  snprintf(key, sizeof(key), "lavfi.readeia608.%d.line", nb_found);
489  av_dict_set_int(&in->metadata, key, scan->nb_line, 0);
490 
491  nb_found++;
492  }
493 
494  return ff_filter_frame(outlink, in);
495 }
496 
498 {
499  ReadEIA608Context *s = ctx->priv;
500 
501  for (int i = 0; i < s->nb_allocated; i++) {
502  ScanItem *scan = &s->scan[i];
503 
504  av_freep(&scan->histogram);
505  av_freep(&scan->code);
506  av_freep(&scan->line);
507  }
508 
509  s->nb_allocated = 0;
510  av_freep(&s->scan);
511 }
512 
513 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
514  char *res, int res_len, int flags)
515 {
516  ReadEIA608Context *s = ctx->priv;
517  int ret, start = s->start, end = s->end;
518 
519  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
520  if (ret < 0)
521  return ret;
522 
523  ret = config_filter(ctx, s->start, s->end);
524  if (ret < 0) {
525  s->start = start;
526  s->end = end;
527  }
528 
529  return 0;
530 }
531 
532 static const AVFilterPad readeia608_inputs[] = {
533  {
534  .name = "default",
535  .type = AVMEDIA_TYPE_VIDEO,
536  .filter_frame = filter_frame,
537  .config_props = config_input,
538  },
539 };
540 
542  .name = "readeia608",
543  .description = NULL_IF_CONFIG_SMALL("Read EIA-608 Closed Caption codes from input video and write them to frame metadata."),
544  .priv_size = sizeof(ReadEIA608Context),
545  .priv_class = &readeia608_class,
549  .uninit = uninit,
553  .process_command = process_command,
554 };
CodeItem::size
int size
Definition: vf_readeia608.c:56
LineItem::average
float average
Definition: vf_readeia608.c:50
AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:522
ReadEIA608Context::spw
float spw
Definition: vf_readeia608.c:75
LineItem::filtered
float filtered
Definition: vf_readeia608.c:49
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:55
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ScanItem::white
int white
Definition: vf_readeia608.c:62
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:513
ReadEIA608Context::end
int end
Definition: vf_readeia608.c:74
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2965
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:162
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:74
AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:514
readeia608_options
static const AVOption readeia608_options[]
Definition: vf_readeia608.c:91
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
pixdesc.h
AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:521
w
uint8_t w
Definition: llviddspenc.c:38
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:516
AVOption
AVOption.
Definition: opt.h:346
b
#define b
Definition: input.c:41
ff_vf_readeia608
const AVFilter ff_vf_readeia608
Definition: vf_readeia608.c:541
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:478
LineItem::output
int output
Definition: vf_readeia608.c:46
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
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:170
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_readeia608.c:462
video.h
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:517
AV_PIX_FMT_GRAY9
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:458
bit
#define bit(string, value)
Definition: cbs_mpeg2.c:56
ScanItem::histogram
uint64_t * histogram
Definition: vf_readeia608.c:64
AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:513
meanf
static float meanf(const LineItem *line, int len)
Definition: vf_readeia608.c:222
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:523
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:476
ScanItem::found
int found
Definition: vf_readeia608.c:61
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:462
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
ScanItem::nb_line
int nb_line
Definition: vf_readeia608.c:60
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:481
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
extract_lines
static int extract_lines(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
Definition: vf_readeia608.c:443
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:490
ff_video_default_filterpad
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition: video.c:37
ReadEIA608Context
Definition: vf_readeia608.c:71
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
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:108
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:491
ReadEIA608Context::max
int max
Definition: vf_readeia608.c:80
AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:520
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:475
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:489
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:461
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
pixel_fmts
static enum AVPixelFormat pixel_fmts[]
Definition: vf_readeia608.c:102
key
const char * key
Definition: hwcontext_opencl.c:189
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
periods
static int periods(const LineItem *line, CodeItem *code, int len)
Definition: vf_readeia608.c:284
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
ReadEIA608Context::read_line
void(* read_line[2])(AVFrame *in, int nb_line, LineItem *line, int lp, int w)
Definition: vf_readeia608.c:84
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:73
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:459
ScanItem::byte
uint8_t byte[2]
Definition: vf_readeia608.c:65
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:89
ScanItem
Definition: vf_readeia608.c:59
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:204
LineItem::unfiltered
float unfiltered
Definition: vf_readeia608.c:48
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
ReadEIA608Context::depth
int depth
Definition: vf_readeia608.c:79
AV_PIX_FMT_YUV440P10
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:480
find_black_and_white
static void find_black_and_white(ReadEIA608Context *s, ScanItem *scan)
Definition: vf_readeia608.c:179
sqrtf
static __device__ float sqrtf(float a)
Definition: cuda_runtime.h:184
ReadEIA608Context::scan
ScanItem * scan
Definition: vf_readeia608.c:82
readeia608_inputs
static const AVFilterPad readeia608_inputs[]
Definition: vf_readeia608.c:532
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:479
ReadEIA608Context::nb_allocated
int nb_allocated
Definition: vf_readeia608.c:81
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
READ_LINE
#define READ_LINE(type, name)
Definition: vf_readeia608.c:316
ReadEIA608Context::lp
int lp
Definition: vf_readeia608.c:77
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_readeia608.c:497
thresholding
static void thresholding(ReadEIA608Context *s, ScanItem *scan, LineItem *line, int lag, float threshold, float influence, int len)
Definition: vf_readeia608.c:245
LineItem::input
int input
Definition: vf_readeia608.c:45
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
dump_code
static void dump_code(AVFilterContext *ctx, ScanItem *scan, int len, int item)
Definition: vf_readeia608.c:307
stddevf
static float stddevf(const LineItem *line, int len)
Definition: vf_readeia608.c:234
OFFSET
#define OFFSET(x)
Definition: vf_readeia608.c:88
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:483
size
int size
Definition: twinvq_data.h:10344
CodeItem
Definition: vf_readeia608.c:54
parity
mcdeint parity
Definition: vf_mcdeint.c:281
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:485
ScanItem::black
int black
Definition: vf_readeia608.c:63
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:887
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:165
SYNC_BITSIZE_MAX
#define SYNC_BITSIZE_MAX
Definition: vf_readeia608.c:42
build_histogram
static void build_histogram(ReadEIA608Context *s, ScanItem *scan, const LineItem *line, int len)
Definition: vf_readeia608.c:171
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:174
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:518
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:147
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:238
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_readeia608.c:343
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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:359
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:827
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:107
len
int len
Definition: vorbis_enc_data.h:426
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:477
AVFilter
Filter definition.
Definition: avfilter.h:166
CLOCK_BITSIZE_MAX
#define CLOCK_BITSIZE_MAX
Definition: vf_readeia608.c:40
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:515
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:482
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:487
LineItem::deviation
float deviation
Definition: vf_readeia608.c:51
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:519
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
avfilter.h
AVFrame::metadata
AVDictionary * metadata
metadata.
Definition: frame.h:692
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:133
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:863
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
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
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:167
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:117
desc
const char * desc
Definition: libsvtav1.c:75
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
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
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:88
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
ScanItem::code
CodeItem * code
Definition: vf_readeia608.c:67
ScanItem::line
LineItem * line
Definition: vf_readeia608.c:68
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
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:79
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:484
h
h
Definition: vp9dsp_template.c:2038
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:488
ReadEIA608Context::chp
int chp
Definition: vf_readeia608.c:76
LAG
#define LAG
Definition: vf_readeia608.c:38
SYNC_BITSIZE_MIN
#define SYNC_BITSIZE_MIN
Definition: vf_readeia608.c:41
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:460
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:134
snprintf
#define snprintf
Definition: snprintf.h:34
LineItem
Definition: vf_readeia608.c:44
config_filter
static int config_filter(AVFilterContext *ctx, int start, int end)
Definition: vf_readeia608.c:126
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:173
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:486
CLOCK_BITSIZE_MIN
#define CLOCK_BITSIZE_MIN
Definition: vf_readeia608.c:39