FFmpeg
vf_stereo3d.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Gordon Schmidt <gordon.schmidt <at> s2000.tu-chemnitz.de>
3  * Copyright (c) 2013-2015 Paul B Mahol
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/avassert.h"
23 #include "libavutil/imgutils.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/parseutils.h"
27 #include "libavutil/pixdesc.h"
28 #include "avfilter.h"
29 #include "drawutils.h"
30 #include "formats.h"
31 #include "internal.h"
32 #include "video.h"
33 #include "stereo3d.h"
34 
35 enum StereoCode {
36  ANAGLYPH_RC_GRAY, // anaglyph red/cyan gray
37  ANAGLYPH_RC_HALF, // anaglyph red/cyan half colored
38  ANAGLYPH_RC_COLOR, // anaglyph red/cyan colored
39  ANAGLYPH_RC_DUBOIS, // anaglyph red/cyan dubois
40  ANAGLYPH_GM_GRAY, // anaglyph green/magenta gray
41  ANAGLYPH_GM_HALF, // anaglyph green/magenta half colored
42  ANAGLYPH_GM_COLOR, // anaglyph green/magenta colored
43  ANAGLYPH_GM_DUBOIS, // anaglyph green/magenta dubois
44  ANAGLYPH_YB_GRAY, // anaglyph yellow/blue gray
45  ANAGLYPH_YB_HALF, // anaglyph yellow/blue half colored
46  ANAGLYPH_YB_COLOR, // anaglyph yellow/blue colored
47  ANAGLYPH_YB_DUBOIS, // anaglyph yellow/blue dubois
48  ANAGLYPH_RB_GRAY, // anaglyph red/blue gray
49  ANAGLYPH_RG_GRAY, // anaglyph red/green gray
50  MONO_L, // mono output for debugging (left eye only)
51  MONO_R, // mono output for debugging (right eye only)
52  INTERLEAVE_ROWS_LR, // row-interleave (left eye has top row)
53  INTERLEAVE_ROWS_RL, // row-interleave (right eye has top row)
54  SIDE_BY_SIDE_LR, // side by side parallel (left eye left, right eye right)
55  SIDE_BY_SIDE_RL, // side by side crosseye (right eye left, left eye right)
56  SIDE_BY_SIDE_2_LR, // side by side parallel with half width resolution
57  SIDE_BY_SIDE_2_RL, // side by side crosseye with half width resolution
58  ABOVE_BELOW_LR, // above-below (left eye above, right eye below)
59  ABOVE_BELOW_RL, // above-below (right eye above, left eye below)
60  ABOVE_BELOW_2_LR, // above-below with half height resolution
61  ABOVE_BELOW_2_RL, // above-below with half height resolution
62  ALTERNATING_LR, // alternating frames (left eye first, right eye second)
63  ALTERNATING_RL, // alternating frames (right eye first, left eye second)
64  CHECKERBOARD_LR, // checkerboard pattern (left eye first, right eye second)
65  CHECKERBOARD_RL, // checkerboard pattern (right eye first, left eye second)
66  INTERLEAVE_COLS_LR, // column-interleave (left eye first, right eye second)
67  INTERLEAVE_COLS_RL, // column-interleave (right eye first, left eye second)
68  HDMI, // HDMI frame pack (left eye first, right eye second)
69  STEREO_CODE_COUNT // TODO: needs autodetection
70 };
71 
72 typedef struct StereoComponent {
73  int format; ///< StereoCode
74  int width, height;
78  int row_step;
80 
81 static const int ana_coeff[][3][6] = {
83  {{19595, 38470, 7471, 0, 0, 0},
84  { 0, 0, 0, 0, 0, 0},
85  { 0, 0, 0, 19595, 38470, 7471}},
87  {{19595, 38470, 7471, 0, 0, 0},
88  { 0, 0, 0, 19595, 38470, 7471},
89  { 0, 0, 0, 0, 0, 0}},
91  {{19595, 38470, 7471, 0, 0, 0},
92  { 0, 0, 0, 19595, 38470, 7471},
93  { 0, 0, 0, 19595, 38470, 7471}},
95  {{19595, 38470, 7471, 0, 0, 0},
96  { 0, 0, 0, 0, 65536, 0},
97  { 0, 0, 0, 0, 0, 65536}},
99  {{65536, 0, 0, 0, 0, 0},
100  { 0, 0, 0, 0, 65536, 0},
101  { 0, 0, 0, 0, 0, 65536}},
103  {{29884, 32768, 11534, -2818, -5767, -131},
104  {-2621, -2490, -1049, 24773, 48103, -1180},
105  { -983, -1376, -328, -4719, -7406, 80347}},
106  [ANAGLYPH_GM_GRAY] =
107  {{ 0, 0, 0, 19595, 38470, 7471},
108  {19595, 38470, 7471, 0, 0, 0},
109  { 0, 0, 0, 19595, 38470, 7471}},
110  [ANAGLYPH_GM_HALF] =
111  {{ 0, 0, 0, 65536, 0, 0},
112  {19595, 38470, 7471, 0, 0, 0},
113  { 0, 0, 0, 0, 0, 65536}},
115  {{ 0, 0, 0, 65536, 0, 0},
116  { 0, 65536, 0, 0, 0, 0},
117  { 0, 0, 0, 0, 0, 65536}},
119  {{-4063,-10354, -2556, 34669, 46203, 1573},
120  {18612, 43778, 9372, -1049, -983, -4260},
121  { -983, -1769, 1376, 590, 4915, 61407}},
122  [ANAGLYPH_YB_GRAY] =
123  {{ 0, 0, 0, 19595, 38470, 7471},
124  { 0, 0, 0, 19595, 38470, 7471},
125  {19595, 38470, 7471, 0, 0, 0}},
126  [ANAGLYPH_YB_HALF] =
127  {{ 0, 0, 0, 65536, 0, 0},
128  { 0, 0, 0, 0, 65536, 0},
129  {19595, 38470, 7471, 0, 0, 0}},
131  {{ 0, 0, 0, 65536, 0, 0},
132  { 0, 0, 0, 0, 65536, 0},
133  { 0, 0, 65536, 0, 0, 0}},
135  {{69599,-13435,19595, -1048, -8061, -1114},
136  {-1704, 59507, 4456, 393, 4063, -1114},
137  {-2490,-11338, 1442, 6160, 12124, 59703}},
138 };
139 
140 typedef struct Stereo3DContext {
141  const AVClass *class;
143  int width, height;
144  const int *ana_matrix[3];
146  int linesize[4];
147  int pheight[4];
148  int hsub, vsub;
149  int pixstep[4];
151  int blanks;
152  int in_off_left[4], in_off_right[4];
156 
157 #define OFFSET(x) offsetof(Stereo3DContext, x)
158 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
159 
160 static const AVOption stereo3d_options[] = {
161  { "in", "set input format", OFFSET(in.format), AV_OPT_TYPE_INT, {.i64=SIDE_BY_SIDE_LR}, INTERLEAVE_ROWS_LR, STEREO_CODE_COUNT-1, FLAGS, "in"},
162  { "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "in" },
163  { "tb2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "in" },
164  { "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "in" },
165  { "tb2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "in" },
166  { "abl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "in" },
167  { "tbl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "in" },
168  { "abr", "above below right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL}, 0, 0, FLAGS, "in" },
169  { "tbr", "above below right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL}, 0, 0, FLAGS, "in" },
170  { "al", "alternating frames left first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR}, 0, 0, FLAGS, "in" },
171  { "ar", "alternating frames right first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL}, 0, 0, FLAGS, "in" },
172  { "sbs2l", "side by side half width left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR}, 0, 0, FLAGS, "in" },
173  { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL}, 0, 0, FLAGS, "in" },
174  { "sbsl", "side by side left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR}, 0, 0, FLAGS, "in" },
175  { "sbsr", "side by side right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL}, 0, 0, FLAGS, "in" },
176  { "irl", "interleave rows left first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_LR}, 0, 0, FLAGS, "in" },
177  { "irr", "interleave rows right first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_RL}, 0, 0, FLAGS, "in" },
178  { "icl", "interleave columns left first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_COLS_LR}, 0, 0, FLAGS, "in" },
179  { "icr", "interleave columns right first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_COLS_RL}, 0, 0, FLAGS, "in" },
180  { "out", "set output format", OFFSET(out.format), AV_OPT_TYPE_INT, {.i64=ANAGLYPH_RC_DUBOIS}, 0, STEREO_CODE_COUNT-1, FLAGS, "out"},
181  { "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "out" },
182  { "tb2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "out" },
183  { "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "out" },
184  { "tb2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "out" },
185  { "abl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "out" },
186  { "tbl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "out" },
187  { "abr", "above below right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL}, 0, 0, FLAGS, "out" },
188  { "tbr", "above below right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL}, 0, 0, FLAGS, "out" },
189  { "agmc", "anaglyph green magenta color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_COLOR}, 0, 0, FLAGS, "out" },
190  { "agmd", "anaglyph green magenta dubois", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_DUBOIS}, 0, 0, FLAGS, "out" },
191  { "agmg", "anaglyph green magenta gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_GRAY}, 0, 0, FLAGS, "out" },
192  { "agmh", "anaglyph green magenta half color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_HALF}, 0, 0, FLAGS, "out" },
193  { "al", "alternating frames left first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR}, 0, 0, FLAGS, "out" },
194  { "ar", "alternating frames right first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL}, 0, 0, FLAGS, "out" },
195  { "arbg", "anaglyph red blue gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RB_GRAY}, 0, 0, FLAGS, "out" },
196  { "arcc", "anaglyph red cyan color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_COLOR}, 0, 0, FLAGS, "out" },
197  { "arcd", "anaglyph red cyan dubois", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_DUBOIS}, 0, 0, FLAGS, "out" },
198  { "arcg", "anaglyph red cyan gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_GRAY}, 0, 0, FLAGS, "out" },
199  { "arch", "anaglyph red cyan half color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_HALF}, 0, 0, FLAGS, "out" },
200  { "argg", "anaglyph red green gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RG_GRAY}, 0, 0, FLAGS, "out" },
201  { "aybc", "anaglyph yellow blue color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_YB_COLOR}, 0, 0, FLAGS, "out" },
202  { "aybd", "anaglyph yellow blue dubois", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_YB_DUBOIS}, 0, 0, FLAGS, "out" },
203  { "aybg", "anaglyph yellow blue gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_YB_GRAY}, 0, 0, FLAGS, "out" },
204  { "aybh", "anaglyph yellow blue half color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_YB_HALF}, 0, 0, FLAGS, "out" },
205  { "irl", "interleave rows left first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_LR}, 0, 0, FLAGS, "out" },
206  { "irr", "interleave rows right first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_RL}, 0, 0, FLAGS, "out" },
207  { "ml", "mono left", 0, AV_OPT_TYPE_CONST, {.i64=MONO_L}, 0, 0, FLAGS, "out" },
208  { "mr", "mono right", 0, AV_OPT_TYPE_CONST, {.i64=MONO_R}, 0, 0, FLAGS, "out" },
209  { "sbs2l", "side by side half width left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR}, 0, 0, FLAGS, "out" },
210  { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL}, 0, 0, FLAGS, "out" },
211  { "sbsl", "side by side left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR}, 0, 0, FLAGS, "out" },
212  { "sbsr", "side by side right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL}, 0, 0, FLAGS, "out" },
213  { "chl", "checkerboard left first", 0, AV_OPT_TYPE_CONST, {.i64=CHECKERBOARD_LR}, 0, 0, FLAGS, "out" },
214  { "chr", "checkerboard right first", 0, AV_OPT_TYPE_CONST, {.i64=CHECKERBOARD_RL}, 0, 0, FLAGS, "out" },
215  { "icl", "interleave columns left first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_COLS_LR}, 0, 0, FLAGS, "out" },
216  { "icr", "interleave columns right first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_COLS_RL}, 0, 0, FLAGS, "out" },
217  { "hdmi", "HDMI frame pack", 0, AV_OPT_TYPE_CONST, {.i64=HDMI}, 0, 0, FLAGS, "out" },
218  { NULL }
219 };
220 
221 AVFILTER_DEFINE_CLASS(stereo3d);
222 
223 static const enum AVPixelFormat anaglyph_pix_fmts[] = {
226 };
227 
228 static const enum AVPixelFormat other_pix_fmts[] = {
280 };
281 
283 {
284  Stereo3DContext *s = ctx->priv;
285  const enum AVPixelFormat *pix_fmts;
286  AVFilterFormats *fmts_list;
287 
288  switch (s->out.format) {
289  case ANAGLYPH_GM_COLOR:
290  case ANAGLYPH_GM_DUBOIS:
291  case ANAGLYPH_GM_GRAY:
292  case ANAGLYPH_GM_HALF:
293  case ANAGLYPH_RB_GRAY:
294  case ANAGLYPH_RC_COLOR:
295  case ANAGLYPH_RC_DUBOIS:
296  case ANAGLYPH_RC_GRAY:
297  case ANAGLYPH_RC_HALF:
298  case ANAGLYPH_RG_GRAY:
299  case ANAGLYPH_YB_COLOR:
300  case ANAGLYPH_YB_DUBOIS:
301  case ANAGLYPH_YB_GRAY:
302  case ANAGLYPH_YB_HALF:
303  pix_fmts = anaglyph_pix_fmts;
304  break;
305  default:
306  pix_fmts = other_pix_fmts;
307  }
308 
309  fmts_list = ff_make_format_list(pix_fmts);
310  if (!fmts_list)
311  return AVERROR(ENOMEM);
312  return ff_set_common_formats(ctx, fmts_list);
313 }
314 
315 static inline uint8_t ana_convert(const int *coeff, const uint8_t *left, const uint8_t *right)
316 {
317  int sum;
318 
319  sum = coeff[0] * left[0] + coeff[3] * right[0]; //red in
320  sum += coeff[1] * left[1] + coeff[4] * right[1]; //green in
321  sum += coeff[2] * left[2] + coeff[5] * right[2]; //blue in
322 
323  return av_clip_uint8(sum >> 16);
324 }
325 
326 static void anaglyph_ic(uint8_t *dst, uint8_t *lsrc, uint8_t *rsrc,
327  ptrdiff_t dst_linesize, ptrdiff_t l_linesize, ptrdiff_t r_linesize,
328  int width, int height,
329  const int *ana_matrix_r, const int *ana_matrix_g, const int *ana_matrix_b)
330 {
331  int x, y, o;
332 
333  for (y = 0; y < height; y++) {
334  for (o = 0, x = 0; x < width; x++, o+= 3) {
335  dst[o ] = ana_convert(ana_matrix_r, lsrc + o * 2, rsrc + o * 2);
336  dst[o + 1] = ana_convert(ana_matrix_g, lsrc + o * 2, rsrc + o * 2);
337  dst[o + 2] = ana_convert(ana_matrix_b, lsrc + o * 2, rsrc + o * 2);
338  }
339 
340  dst += dst_linesize;
341  lsrc += l_linesize;
342  rsrc += r_linesize;
343  }
344 }
345 
346 static void anaglyph(uint8_t *dst, uint8_t *lsrc, uint8_t *rsrc,
347  ptrdiff_t dst_linesize, ptrdiff_t l_linesize, ptrdiff_t r_linesize,
348  int width, int height,
349  const int *ana_matrix_r, const int *ana_matrix_g, const int *ana_matrix_b)
350 {
351  int x, y, o;
352 
353  for (y = 0; y < height; y++) {
354  for (o = 0, x = 0; x < width; x++, o+= 3) {
355  dst[o ] = ana_convert(ana_matrix_r, lsrc + o, rsrc + o);
356  dst[o + 1] = ana_convert(ana_matrix_g, lsrc + o, rsrc + o);
357  dst[o + 2] = ana_convert(ana_matrix_b, lsrc + o, rsrc + o);
358  }
359 
360  dst += dst_linesize;
361  lsrc += l_linesize;
362  rsrc += r_linesize;
363  }
364 }
365 
366 static int config_output(AVFilterLink *outlink)
367 {
368  AVFilterContext *ctx = outlink->src;
369  AVFilterLink *inlink = ctx->inputs[0];
370  Stereo3DContext *s = ctx->priv;
371  AVRational fps = inlink->frame_rate;
372  AVRational tb = inlink->time_base;
374  int ret;
375  s->aspect = inlink->sample_aspect_ratio;
376 
377  switch (s->in.format) {
378  case INTERLEAVE_COLS_LR:
379  case INTERLEAVE_COLS_RL:
380  case SIDE_BY_SIDE_2_LR:
381  case SIDE_BY_SIDE_LR:
382  case SIDE_BY_SIDE_2_RL:
383  case SIDE_BY_SIDE_RL:
384  if (inlink->w & 1) {
385  av_log(ctx, AV_LOG_ERROR, "width must be even\n");
386  return AVERROR_INVALIDDATA;
387  }
388  break;
389  case INTERLEAVE_ROWS_LR:
390  case INTERLEAVE_ROWS_RL:
391  case ABOVE_BELOW_2_LR:
392  case ABOVE_BELOW_LR:
393  case ABOVE_BELOW_2_RL:
394  case ABOVE_BELOW_RL:
395  if (inlink->h & 1) {
396  av_log(ctx, AV_LOG_ERROR, "height must be even\n");
397  return AVERROR_INVALIDDATA;
398  }
399  break;
400  }
401 
402  s->in.width =
403  s->width = inlink->w;
404  s->in.height =
405  s->height = inlink->h;
406  s->in.off_lstep =
407  s->in.off_rstep =
408  s->in.off_left =
409  s->in.off_right =
410  s->in.row_left =
411  s->in.row_right = 0;
412  s->in.row_step = 1;
413 
414  switch (s->in.format) {
415  case SIDE_BY_SIDE_2_LR:
416  s->aspect.num *= 2;
417  case SIDE_BY_SIDE_LR:
418  s->width = inlink->w / 2;
419  s->in.off_right = s->width;
420  break;
421  case SIDE_BY_SIDE_2_RL:
422  s->aspect.num *= 2;
423  case SIDE_BY_SIDE_RL:
424  s->width = inlink->w / 2;
425  s->in.off_left = s->width;
426  break;
427  case ABOVE_BELOW_2_LR:
428  s->aspect.den *= 2;
429  case ABOVE_BELOW_LR:
430  s->in.row_right =
431  s->height = inlink->h / 2;
432  break;
433  case ABOVE_BELOW_2_RL:
434  s->aspect.den *= 2;
435  case ABOVE_BELOW_RL:
436  s->in.row_left =
437  s->height = inlink->h / 2;
438  break;
439  case ALTERNATING_RL:
440  case ALTERNATING_LR:
441  fps.den *= 2;
442  tb.num *= 2;
443  break;
444  case INTERLEAVE_COLS_RL:
445  case INTERLEAVE_COLS_LR:
446  s->width = inlink->w / 2;
447  break;
448  case INTERLEAVE_ROWS_LR:
449  case INTERLEAVE_ROWS_RL:
450  s->in.row_step = 2;
451  if (s->in.format == INTERLEAVE_ROWS_RL)
452  s->in.off_lstep = 1;
453  else
454  s->in.off_rstep = 1;
455  if (s->out.format != CHECKERBOARD_LR &&
456  s->out.format != CHECKERBOARD_RL)
457  s->height = inlink->h / 2;
458  break;
459  default:
460  av_log(ctx, AV_LOG_ERROR, "input format %d is not supported\n", s->in.format);
461  return AVERROR(EINVAL);
462  }
463 
464  s->out.width = s->width;
465  s->out.height = s->height;
466  s->out.off_lstep =
467  s->out.off_rstep =
468  s->out.off_left =
469  s->out.off_right =
470  s->out.row_left =
471  s->out.row_right = 0;
472  s->out.row_step = 1;
473 
474  switch (s->out.format) {
475  case ANAGLYPH_RB_GRAY:
476  case ANAGLYPH_RG_GRAY:
477  case ANAGLYPH_RC_GRAY:
478  case ANAGLYPH_RC_HALF:
479  case ANAGLYPH_RC_COLOR:
480  case ANAGLYPH_RC_DUBOIS:
481  case ANAGLYPH_GM_GRAY:
482  case ANAGLYPH_GM_HALF:
483  case ANAGLYPH_GM_COLOR:
484  case ANAGLYPH_GM_DUBOIS:
485  case ANAGLYPH_YB_GRAY:
486  case ANAGLYPH_YB_HALF:
487  case ANAGLYPH_YB_COLOR:
488  case ANAGLYPH_YB_DUBOIS: {
489  uint8_t rgba_map[4];
490 
491  ff_fill_rgba_map(rgba_map, outlink->format);
492  s->ana_matrix[rgba_map[0]] = &ana_coeff[s->out.format][0][0];
493  s->ana_matrix[rgba_map[1]] = &ana_coeff[s->out.format][1][0];
494  s->ana_matrix[rgba_map[2]] = &ana_coeff[s->out.format][2][0];
495  break;
496  }
497  case SIDE_BY_SIDE_2_LR:
498  s->aspect.den *= 2;
499  case SIDE_BY_SIDE_LR:
500  s->out.width = s->width * 2;
501  s->out.off_right = s->width;
502  break;
503  case SIDE_BY_SIDE_2_RL:
504  s->aspect.den *= 2;
505  case SIDE_BY_SIDE_RL:
506  s->out.width = s->width * 2;
507  s->out.off_left = s->width;
508  break;
509  case ABOVE_BELOW_2_LR:
510  s->aspect.num *= 2;
511  case ABOVE_BELOW_LR:
512  s->out.height = s->height * 2;
513  s->out.row_right = s->height;
514  break;
515  case HDMI:
516  if (s->height != 720 && s->height != 1080) {
517  av_log(ctx, AV_LOG_ERROR, "Only 720 and 1080 height supported\n");
518  return AVERROR(EINVAL);
519  }
520 
521  s->blanks = s->height / 24;
522  s->out.height = s->height * 2 + s->blanks;
523  s->out.row_right = s->height + s->blanks;
524  break;
525  case ABOVE_BELOW_2_RL:
526  s->aspect.num *= 2;
527  case ABOVE_BELOW_RL:
528  s->out.height = s->height * 2;
529  s->out.row_left = s->height;
530  break;
531  case INTERLEAVE_ROWS_LR:
532  s->in.row_step = 1 + (s->in.format == INTERLEAVE_ROWS_RL);
533  s->out.row_step = 2;
534  s->out.height = s->height * 2;
535  s->out.off_rstep = 1;
536  break;
537  case INTERLEAVE_ROWS_RL:
538  s->in.row_step = 1 + (s->in.format == INTERLEAVE_ROWS_LR);
539  s->out.row_step = 2;
540  s->out.height = s->height * 2;
541  s->out.off_lstep = 1;
542  break;
543  case MONO_R:
544  if (s->in.format != INTERLEAVE_COLS_LR) {
545  s->in.off_left = s->in.off_right;
546  s->in.row_left = s->in.row_right;
547  }
548  if (s->in.format == INTERLEAVE_ROWS_LR)
549  FFSWAP(int, s->in.off_lstep, s->in.off_rstep);
550  break;
551  case MONO_L:
552  if (s->in.format == INTERLEAVE_ROWS_RL)
553  FFSWAP(int, s->in.off_lstep, s->in.off_rstep);
554  break;
555  case ALTERNATING_RL:
556  case ALTERNATING_LR:
557  fps.num *= 2;
558  tb.den *= 2;
559  break;
560  case CHECKERBOARD_LR:
561  case CHECKERBOARD_RL:
562  case INTERLEAVE_COLS_LR:
563  case INTERLEAVE_COLS_RL:
564  s->out.width = s->width * 2;
565  break;
566  default:
567  av_log(ctx, AV_LOG_ERROR, "output format %d is not supported\n", s->out.format);
568  return AVERROR(EINVAL);
569  }
570 
572  if ((s->in.format & 1) != (s->out.format & 1)) {
573  FFSWAP(int, s->in.row_left, s->in.row_right);
574  FFSWAP(int, s->in.off_lstep, s->in.off_rstep);
575  FFSWAP(int, s->in.off_left, s->in.off_right);
576  FFSWAP(int, s->out.row_left, s->out.row_right);
577  FFSWAP(int, s->out.off_lstep, s->out.off_rstep);
578  FFSWAP(int, s->out.off_left, s->out.off_right);
579  }
580  }
581 
582  outlink->w = s->out.width;
583  outlink->h = s->out.height;
584  outlink->frame_rate = fps;
585  outlink->time_base = tb;
586  outlink->sample_aspect_ratio = s->aspect;
587 
588  if ((ret = av_image_fill_linesizes(s->linesize, outlink->format, s->width)) < 0)
589  return ret;
592  s->pheight[1] = s->pheight[2] = AV_CEIL_RSHIFT(s->height, desc->log2_chroma_h);
593  s->pheight[0] = s->pheight[3] = s->height;
594  s->hsub = desc->log2_chroma_w;
595  s->vsub = desc->log2_chroma_h;
596 
597  s->dsp.anaglyph = anaglyph;
598  if (ARCH_X86)
600 
601  return 0;
602 }
603 
604 typedef struct ThreadData {
605  AVFrame *ileft, *iright;
606  AVFrame *out;
607 } ThreadData;
608 
609 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
610 {
611  Stereo3DContext *s = ctx->priv;
612  ThreadData *td = arg;
613  AVFrame *ileft = td->ileft;
614  AVFrame *iright = td->iright;
615  AVFrame *out = td->out;
616  int height = s->out.height;
617  int start = (height * jobnr ) / nb_jobs;
618  int end = (height * (jobnr+1)) / nb_jobs;
619  const int **ana_matrix = s->ana_matrix;
620 
621  s->dsp.anaglyph(out->data[0] + out->linesize[0] * start,
622  ileft ->data[0] + s->in_off_left [0] + ileft->linesize[0] * start * s->in.row_step,
623  iright->data[0] + s->in_off_right[0] + iright->linesize[0] * start * s->in.row_step,
624  out->linesize[0],
625  ileft->linesize[0] * s->in.row_step,
626  iright->linesize[0] * s->in.row_step,
627  s->out.width, end - start,
628  ana_matrix[0], ana_matrix[1], ana_matrix[2]);
629 
630  return 0;
631 }
632 
633 static void interleave_cols_to_any(Stereo3DContext *s, int *out_off, int p, AVFrame *in, AVFrame *out, int d)
634 {
635  int y, x;
636 
637  for (y = 0; y < s->pheight[p]; y++) {
638  const uint8_t *src = (const uint8_t*)in->data[p] + y * in->linesize[p] + d * s->pixstep[p];
639  uint8_t *dst = out->data[p] + out_off[p] + y * out->linesize[p] * s->out.row_step;
640 
641  switch (s->pixstep[p]) {
642  case 1:
643  for (x = 0; x < s->linesize[p]; x++)
644  dst[x] = src[x * 2];
645  break;
646  case 2:
647  for (x = 0; x < s->linesize[p]; x+=2)
648  AV_WN16(&dst[x], AV_RN16(&src[x * 2]));
649  break;
650  case 3:
651  for (x = 0; x < s->linesize[p]; x+=3)
652  AV_WB24(&dst[x], AV_RB24(&src[x * 2]));
653  break;
654  case 4:
655  for (x = 0; x < s->linesize[p]; x+=4)
656  AV_WN32(&dst[x], AV_RN32(&src[x * 2]));
657  break;
658  case 6:
659  for (x = 0; x < s->linesize[p]; x+=6)
660  AV_WB48(&dst[x], AV_RB48(&src[x * 2]));
661  break;
662  case 8:
663  for (x = 0; x < s->linesize[p]; x+=8)
664  AV_WN64(&dst[x], AV_RN64(&src[x * 2]));
665  break;
666  }
667  }
668 }
669 
670 static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
671 {
672  AVFilterContext *ctx = inlink->dst;
673  Stereo3DContext *s = ctx->priv;
674  AVFilterLink *outlink = ctx->outputs[0];
675  AVFrame *out = NULL, *oleft, *oright, *ileft, *iright;
676  int out_off_left[4], out_off_right[4];
677  int i, ret;
678 
679  if (s->in.format == s->out.format)
680  return ff_filter_frame(outlink, inpicref);
681 
682  switch (s->out.format) {
683  case ALTERNATING_LR:
684  case ALTERNATING_RL:
685  if (!s->prev) {
686  s->prev = inpicref;
687  return 0;
688  }
689  break;
690  };
691 
692  switch (s->in.format) {
693  case ALTERNATING_LR:
694  case ALTERNATING_RL:
695  if (!s->prev) {
696  s->prev = inpicref;
697  return 0;
698  }
699  ileft = s->prev;
700  iright = inpicref;
701  if (s->in.format == ALTERNATING_RL)
702  FFSWAP(AVFrame *, ileft, iright);
703  break;
704  default:
705  ileft = iright = inpicref;
706  };
707 
708  if ((s->out.format == ALTERNATING_LR ||
709  s->out.format == ALTERNATING_RL) &&
710  (s->in.format == SIDE_BY_SIDE_LR ||
711  s->in.format == SIDE_BY_SIDE_RL ||
712  s->in.format == SIDE_BY_SIDE_2_LR ||
713  s->in.format == SIDE_BY_SIDE_2_RL ||
714  s->in.format == ABOVE_BELOW_LR ||
715  s->in.format == ABOVE_BELOW_RL ||
716  s->in.format == ABOVE_BELOW_2_LR ||
717  s->in.format == ABOVE_BELOW_2_RL ||
718  s->in.format == INTERLEAVE_ROWS_LR ||
719  s->in.format == INTERLEAVE_ROWS_RL)) {
720  oright = av_frame_clone(s->prev);
721  oleft = av_frame_clone(s->prev);
722  if (!oright || !oleft) {
723  av_frame_free(&oright);
724  av_frame_free(&oleft);
725  av_frame_free(&s->prev);
726  av_frame_free(&inpicref);
727  return AVERROR(ENOMEM);
728  }
729  } else if ((s->out.format == MONO_L ||
730  s->out.format == MONO_R) &&
731  (s->in.format == SIDE_BY_SIDE_LR ||
732  s->in.format == SIDE_BY_SIDE_RL ||
733  s->in.format == SIDE_BY_SIDE_2_LR ||
734  s->in.format == SIDE_BY_SIDE_2_RL ||
735  s->in.format == ABOVE_BELOW_LR ||
736  s->in.format == ABOVE_BELOW_RL ||
737  s->in.format == ABOVE_BELOW_2_LR ||
738  s->in.format == ABOVE_BELOW_2_RL ||
739  s->in.format == INTERLEAVE_ROWS_LR ||
740  s->in.format == INTERLEAVE_ROWS_RL)) {
741  out = oleft = oright = av_frame_clone(inpicref);
742  if (!out) {
743  av_frame_free(&s->prev);
744  av_frame_free(&inpicref);
745  return AVERROR(ENOMEM);
746  }
747  } else if ((s->out.format == MONO_L && s->in.format == ALTERNATING_LR) ||
748  (s->out.format == MONO_R && s->in.format == ALTERNATING_RL)) {
749  s->prev->pts /= 2;
750  ret = ff_filter_frame(outlink, s->prev);
751  av_frame_free(&inpicref);
752  s->prev = NULL;
753  return ret;
754  } else if ((s->out.format == MONO_L && s->in.format == ALTERNATING_RL) ||
755  (s->out.format == MONO_R && s->in.format == ALTERNATING_LR)) {
756  av_frame_free(&s->prev);
757  inpicref->pts /= 2;
758  return ff_filter_frame(outlink, inpicref);
759  } else if ((s->out.format == ALTERNATING_LR && s->in.format == ALTERNATING_RL) ||
760  (s->out.format == ALTERNATING_RL && s->in.format == ALTERNATING_LR)) {
761  FFSWAP(int64_t, s->prev->pts, inpicref->pts);
762  ff_filter_frame(outlink, inpicref);
763  ret = ff_filter_frame(outlink, s->prev);
764  s->prev = NULL;
765  return ret;
766  } else {
767  out = oleft = oright = ff_get_video_buffer(outlink, outlink->w, outlink->h);
768  if (!out) {
769  av_frame_free(&s->prev);
770  av_frame_free(&inpicref);
771  return AVERROR(ENOMEM);
772  }
773  av_frame_copy_props(out, inpicref);
774 
775  if (s->out.format == ALTERNATING_LR ||
776  s->out.format == ALTERNATING_RL) {
777  oright = ff_get_video_buffer(outlink, outlink->w, outlink->h);
778  if (!oright) {
779  av_frame_free(&oleft);
780  av_frame_free(&s->prev);
781  av_frame_free(&inpicref);
782  return AVERROR(ENOMEM);
783  }
784  av_frame_copy_props(oright, s->prev);
785  }
786  }
787 
788  for (i = 0; i < 4; i++) {
789  int hsub = i == 1 || i == 2 ? s->hsub : 0;
790  int vsub = i == 1 || i == 2 ? s->vsub : 0;
791  s->in_off_left[i] = (AV_CEIL_RSHIFT(s->in.row_left, vsub) + s->in.off_lstep) * ileft->linesize[i] + AV_CEIL_RSHIFT(s->in.off_left * s->pixstep[i], hsub);
792  s->in_off_right[i] = (AV_CEIL_RSHIFT(s->in.row_right, vsub) + s->in.off_rstep) * iright->linesize[i] + AV_CEIL_RSHIFT(s->in.off_right * s->pixstep[i], hsub);
793  out_off_left[i] = (AV_CEIL_RSHIFT(s->out.row_left, vsub) + s->out.off_lstep) * oleft->linesize[i] + AV_CEIL_RSHIFT(s->out.off_left * s->pixstep[i], hsub);
794  out_off_right[i] = (AV_CEIL_RSHIFT(s->out.row_right, vsub) + s->out.off_rstep) * oright->linesize[i] + AV_CEIL_RSHIFT(s->out.off_right * s->pixstep[i], hsub);
795  }
796 
797  switch (s->out.format) {
798  case ALTERNATING_LR:
799  case ALTERNATING_RL:
800  switch (s->in.format) {
801  case INTERLEAVE_ROWS_LR:
802  case INTERLEAVE_ROWS_RL:
803  for (i = 0; i < s->nb_planes; i++) {
804  oleft->linesize[i] *= 2;
805  oright->linesize[i] *= 2;
806  }
807  case ABOVE_BELOW_LR:
808  case ABOVE_BELOW_RL:
809  case ABOVE_BELOW_2_LR:
810  case ABOVE_BELOW_2_RL:
811  case SIDE_BY_SIDE_LR:
812  case SIDE_BY_SIDE_RL:
813  case SIDE_BY_SIDE_2_LR:
814  case SIDE_BY_SIDE_2_RL:
815  oleft->width = outlink->w;
816  oright->width = outlink->w;
817  oleft->height = outlink->h;
818  oright->height = outlink->h;
819 
820  for (i = 0; i < s->nb_planes; i++) {
821  oleft->data[i] += s->in_off_left[i];
822  oright->data[i] += s->in_off_right[i];
823  }
824  break;
825  default:
826  goto copy;
827  break;
828  }
829  break;
830  case HDMI:
831  for (i = 0; i < s->nb_planes; i++) {
832  int j, h = s->height >> ((i == 1 || i == 2) ? s->vsub : 0);
833  int b = (s->blanks) >> ((i == 1 || i == 2) ? s->vsub : 0);
834 
835  for (j = h; j < h + b; j++)
836  memset(oleft->data[i] + j * s->linesize[i], 0, s->linesize[i]);
837  }
838  case SIDE_BY_SIDE_LR:
839  case SIDE_BY_SIDE_RL:
840  case SIDE_BY_SIDE_2_LR:
841  case SIDE_BY_SIDE_2_RL:
842  case ABOVE_BELOW_LR:
843  case ABOVE_BELOW_RL:
844  case ABOVE_BELOW_2_LR:
845  case ABOVE_BELOW_2_RL:
846  case INTERLEAVE_ROWS_LR:
847  case INTERLEAVE_ROWS_RL:
848 copy:
849  if (s->in.format == INTERLEAVE_COLS_LR ||
850  s->in.format == INTERLEAVE_COLS_RL) {
851  for (i = 0; i < s->nb_planes; i++) {
852  int d = (s->in.format & 1) != (s->out.format & 1);
853 
854  interleave_cols_to_any(s, out_off_left, i, ileft, oleft, d);
855  interleave_cols_to_any(s, out_off_right, i, iright, oright, !d);
856  }
857  } else {
858  for (i = 0; i < s->nb_planes; i++) {
859  av_image_copy_plane(oleft->data[i] + out_off_left[i],
860  oleft->linesize[i] * s->out.row_step,
861  ileft->data[i] + s->in_off_left[i],
862  ileft->linesize[i] * s->in.row_step,
863  s->linesize[i], s->pheight[i]);
864  av_image_copy_plane(oright->data[i] + out_off_right[i],
865  oright->linesize[i] * s->out.row_step,
866  iright->data[i] + s->in_off_right[i],
867  iright->linesize[i] * s->in.row_step,
868  s->linesize[i], s->pheight[i]);
869  }
870  }
871  break;
872  case MONO_L:
873  iright = ileft;
874  case MONO_R:
875  switch (s->in.format) {
876  case INTERLEAVE_ROWS_LR:
877  case INTERLEAVE_ROWS_RL:
878  for (i = 0; i < s->nb_planes; i++) {
879  out->linesize[i] *= 2;
880  }
881  case ABOVE_BELOW_LR:
882  case ABOVE_BELOW_RL:
883  case ABOVE_BELOW_2_LR:
884  case ABOVE_BELOW_2_RL:
885  case SIDE_BY_SIDE_LR:
886  case SIDE_BY_SIDE_RL:
887  case SIDE_BY_SIDE_2_LR:
888  case SIDE_BY_SIDE_2_RL:
889  out->width = outlink->w;
890  out->height = outlink->h;
891 
892  for (i = 0; i < s->nb_planes; i++) {
893  out->data[i] += s->in_off_left[i];
894  }
895  break;
896  case INTERLEAVE_COLS_LR:
897  case INTERLEAVE_COLS_RL:
898  for (i = 0; i < s->nb_planes; i++) {
899  const int d = (s->in.format & 1) != (s->out.format & 1);
900 
901  interleave_cols_to_any(s, out_off_right, i, iright, out, d);
902  }
903  break;
904  default:
905  for (i = 0; i < s->nb_planes; i++) {
906  av_image_copy_plane(out->data[i], out->linesize[i],
907  iright->data[i] + s->in_off_left[i],
908  iright->linesize[i] * s->in.row_step,
909  s->linesize[i], s->pheight[i]);
910  }
911  break;
912  }
913  break;
914  case ANAGLYPH_RB_GRAY:
915  case ANAGLYPH_RG_GRAY:
916  case ANAGLYPH_RC_GRAY:
917  case ANAGLYPH_RC_HALF:
918  case ANAGLYPH_RC_COLOR:
919  case ANAGLYPH_RC_DUBOIS:
920  case ANAGLYPH_GM_GRAY:
921  case ANAGLYPH_GM_HALF:
922  case ANAGLYPH_GM_COLOR:
923  case ANAGLYPH_GM_DUBOIS:
924  case ANAGLYPH_YB_GRAY:
925  case ANAGLYPH_YB_HALF:
926  case ANAGLYPH_YB_COLOR:
927  case ANAGLYPH_YB_DUBOIS: {
928  if (s->in.format == INTERLEAVE_COLS_LR ||
929  s->in.format == INTERLEAVE_COLS_RL) {
930  const int d = (s->in.format & 1);
931 
932  anaglyph_ic(out->data[0],
933  ileft ->data[0] + s->in_off_left [0] + d * 3,
934  iright->data[0] + s->in_off_right[0] + (!d) * 3,
935  out->linesize[0],
936  ileft->linesize[0] * s->in.row_step,
937  iright->linesize[0] * s->in.row_step,
938  s->out.width, s->out.height,
939  s->ana_matrix[0], s->ana_matrix[1], s->ana_matrix[2]);
940  } else {
941  ThreadData td;
942 
943  td.ileft = ileft; td.iright = iright; td.out = out;
944  ctx->internal->execute(ctx, filter_slice, &td, NULL,
946  }
947  break;
948  }
949  case CHECKERBOARD_RL:
950  case CHECKERBOARD_LR:
951  for (i = 0; i < s->nb_planes; i++) {
952  int x, y;
953 
954  for (y = 0; y < s->pheight[i]; y++) {
955  uint8_t *dst = out->data[i] + out->linesize[i] * y;
956  const int d1 = (s->in.format == INTERLEAVE_COLS_LR || s->in.format == INTERLEAVE_COLS_RL) && (s->in.format & 1) != (s->out.format & 1);
957  const int d2 = (s->in.format == INTERLEAVE_COLS_LR || s->in.format == INTERLEAVE_COLS_RL) ? !d1 : 0;
958  const int m = 1 + (s->in.format == INTERLEAVE_COLS_LR || s->in.format == INTERLEAVE_COLS_RL);
959  uint8_t *left = ileft->data[i] + ileft->linesize[i] * y + s->in_off_left[i] + d1 * s->pixstep[i];
960  uint8_t *right = iright->data[i] + iright->linesize[i] * y + s->in_off_right[i] + d2 * s->pixstep[i];
961  int p, b;
962 
964  FFSWAP(uint8_t*, left, right);
965  switch (s->pixstep[i]) {
966  case 1:
967  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=2, p++, b+=2) {
968  dst[x ] = (b&1) == (y&1) ? left[p*m] : right[p*m];
969  dst[x+1] = (b&1) != (y&1) ? left[p*m] : right[p*m];
970  }
971  break;
972  case 2:
973  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=4, p+=2, b+=2) {
974  AV_WN16(&dst[x ], (b&1) == (y&1) ? AV_RN16(&left[p*m]) : AV_RN16(&right[p*m]));
975  AV_WN16(&dst[x+2], (b&1) != (y&1) ? AV_RN16(&left[p*m]) : AV_RN16(&right[p*m]));
976  }
977  break;
978  case 3:
979  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=6, p+=3, b+=2) {
980  AV_WB24(&dst[x ], (b&1) == (y&1) ? AV_RB24(&left[p*m]) : AV_RB24(&right[p*m]));
981  AV_WB24(&dst[x+3], (b&1) != (y&1) ? AV_RB24(&left[p*m]) : AV_RB24(&right[p*m]));
982  }
983  break;
984  case 4:
985  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=8, p+=4, b+=2) {
986  AV_WN32(&dst[x ], (b&1) == (y&1) ? AV_RN32(&left[p*m]) : AV_RN32(&right[p*m]));
987  AV_WN32(&dst[x+4], (b&1) != (y&1) ? AV_RN32(&left[p*m]) : AV_RN32(&right[p*m]));
988  }
989  break;
990  case 6:
991  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=12, p+=6, b+=2) {
992  AV_WB48(&dst[x ], (b&1) == (y&1) ? AV_RB48(&left[p*m]) : AV_RB48(&right[p*m]));
993  AV_WB48(&dst[x+6], (b&1) != (y&1) ? AV_RB48(&left[p*m]) : AV_RB48(&right[p*m]));
994  }
995  break;
996  case 8:
997  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=16, p+=8, b+=2) {
998  AV_WN64(&dst[x ], (b&1) == (y&1) ? AV_RN64(&left[p*m]) : AV_RN64(&right[p*m]));
999  AV_WN64(&dst[x+8], (b&1) != (y&1) ? AV_RN64(&left[p*m]) : AV_RN64(&right[p*m]));
1000  }
1001  break;
1002  }
1003  }
1004  }
1005  break;
1006  case INTERLEAVE_COLS_LR:
1007  case INTERLEAVE_COLS_RL:
1008  for (i = 0; i < s->nb_planes; i++) {
1009  const int d = (s->in.format == INTERLEAVE_COLS_LR || s->in.format == INTERLEAVE_COLS_RL);
1010  const int m = 1 + d;
1011  int x, y;
1012 
1013  for (y = 0; y < s->pheight[i]; y++) {
1014  uint8_t *dst = out->data[i] + out->linesize[i] * y;
1015  uint8_t *left = ileft->data[i] + ileft->linesize[i] * y * s->in.row_step + s->in_off_left[i] + d * s->pixstep[i];
1016  uint8_t *right = iright->data[i] + iright->linesize[i] * y * s->in.row_step + s->in_off_right[i];
1017  int p, b;
1018 
1019  if (s->out.format == INTERLEAVE_COLS_LR)
1020  FFSWAP(uint8_t*, left, right);
1021 
1022  switch (s->pixstep[i]) {
1023  case 1:
1024  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=2, p++, b+=2) {
1025  dst[x ] = b&1 ? left[p*m] : right[p*m];
1026  dst[x+1] = !(b&1) ? left[p*m] : right[p*m];
1027  }
1028  break;
1029  case 2:
1030  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=4, p+=2, b+=2) {
1031  AV_WN16(&dst[x ], b&1 ? AV_RN16(&left[p*m]) : AV_RN16(&right[p*m]));
1032  AV_WN16(&dst[x+2], !(b&1) ? AV_RN16(&left[p*m]) : AV_RN16(&right[p*m]));
1033  }
1034  break;
1035  case 3:
1036  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=6, p+=3, b+=2) {
1037  AV_WB24(&dst[x ], b&1 ? AV_RB24(&left[p*m]) : AV_RB24(&right[p*m]));
1038  AV_WB24(&dst[x+3], !(b&1) ? AV_RB24(&left[p*m]) : AV_RB24(&right[p*m]));
1039  }
1040  break;
1041  case 4:
1042  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=8, p+=4, b+=2) {
1043  AV_WN32(&dst[x ], b&1 ? AV_RN32(&left[p*m]) : AV_RN32(&right[p*m]));
1044  AV_WN32(&dst[x+4], !(b&1) ? AV_RN32(&left[p*m]) : AV_RN32(&right[p*m]));
1045  }
1046  break;
1047  case 6:
1048  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=12, p+=6, b+=2) {
1049  AV_WB48(&dst[x ], b&1 ? AV_RB48(&left[p*m]) : AV_RB48(&right[p*m]));
1050  AV_WB48(&dst[x+6], !(b&1) ? AV_RB48(&left[p*m]) : AV_RB48(&right[p*m]));
1051  }
1052  break;
1053  case 8:
1054  for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=16, p+=8, b+=2) {
1055  AV_WN64(&dst[x ], b&1 ? AV_RN64(&left[p*m]) : AV_RN64(&right[p*m]));
1056  AV_WN64(&dst[x+8], !(b&1) ? AV_RN64(&left[p*m]) : AV_RN64(&right[p*m]));
1057  }
1058  break;
1059  }
1060  }
1061  }
1062  break;
1063  default:
1064  av_assert0(0);
1065  }
1066 
1067  if (oright != oleft) {
1068  if (s->out.format == ALTERNATING_LR)
1069  FFSWAP(AVFrame *, oleft, oright);
1070  oright->pts = s->prev->pts * 2;
1071  ff_filter_frame(outlink, oright);
1072  out = oleft;
1073  oleft->pts = s->prev->pts + inpicref->pts;
1074  av_frame_free(&s->prev);
1075  s->prev = inpicref;
1076  } else if (s->in.format == ALTERNATING_LR ||
1077  s->in.format == ALTERNATING_RL) {
1078  out->pts = s->prev->pts / 2;
1079  av_frame_free(&s->prev);
1080  av_frame_free(&inpicref);
1081  } else {
1082  av_frame_free(&s->prev);
1083  av_frame_free(&inpicref);
1084  }
1085  av_assert0(out);
1086  out->sample_aspect_ratio = s->aspect;
1087  return ff_filter_frame(outlink, out);
1088 }
1089 
1091 {
1092  Stereo3DContext *s = ctx->priv;
1093 
1094  av_frame_free(&s->prev);
1095 }
1096 
1097 static const AVFilterPad stereo3d_inputs[] = {
1098  {
1099  .name = "default",
1100  .type = AVMEDIA_TYPE_VIDEO,
1101  .filter_frame = filter_frame,
1102  },
1103  { NULL }
1104 };
1105 
1106 static const AVFilterPad stereo3d_outputs[] = {
1107  {
1108  .name = "default",
1109  .type = AVMEDIA_TYPE_VIDEO,
1110  .config_props = config_output,
1111  },
1112  { NULL }
1113 };
1114 
1116  .name = "stereo3d",
1117  .description = NULL_IF_CONFIG_SMALL("Convert video stereoscopic 3D view."),
1118  .priv_size = sizeof(Stereo3DContext),
1119  .uninit = uninit,
1121  .inputs = stereo3d_inputs,
1122  .outputs = stereo3d_outputs,
1123  .priv_class = &stereo3d_class,
1125 };
#define NULL
Definition: coverity.c:32
planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
Definition: pixfmt.h:166
#define AV_RB48(x)
Definition: intreadwrite.h:472
planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
Definition: pixfmt.h:252
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
AVFrame * out
Definition: af_adeclick.c:488
planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:245
static void copy(const float *p1, float *p2, const int length)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
StereoComponent in
Definition: vf_stereo3d.c:142
AVOption.
Definition: opt.h:246
planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:249
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:159
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:208
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
static void anaglyph(uint8_t *dst, uint8_t *lsrc, uint8_t *rsrc, ptrdiff_t dst_linesize, ptrdiff_t l_linesize, ptrdiff_t r_linesize, int width, int height, const int *ana_matrix_r, const int *ana_matrix_g, const int *ana_matrix_b)
Definition: vf_stereo3d.c:346
misc image utilities
static void interleave_cols_to_any(Stereo3DContext *s, int *out_off, int p, AVFrame *in, AVFrame *out, int d)
Definition: vf_stereo3d.c:633
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2562
void(* anaglyph)(uint8_t *dst, uint8_t *lsrc, uint8_t *rsrc, ptrdiff_t dst_linesize, ptrdiff_t l_linesize, ptrdiff_t r_linesize, int width, int height, const int *ana_matrix_r, const int *ana_matrix_g, const int *ana_matrix_b)
Definition: stereo3d.h:28
Main libavfilter public API header.
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
int format
StereoCode.
Definition: vf_stereo3d.c:73
const char * desc
Definition: nvenc.c:68
planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
Definition: pixfmt.h:162
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
Definition: pixfmt.h:250
int in_off_right[4]
Definition: vf_stereo3d.c:152
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
int num
Numerator.
Definition: rational.h:59
packed RGBA 16:16:16:16, 64bpp, 16B, 16G, 16R, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:207
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:189
planar GBR 4:4:4 36bpp, little-endian
Definition: pixfmt.h:255
The following 12 formats have the disadvantage of needing 1 format for each bit depth.
Definition: pixfmt.h:156
AVFILTER_DEFINE_CLASS(stereo3d)
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:239
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
#define src
Definition: vp8dsp.c:254
planar GBR 4:4:4 36bpp, big-endian
Definition: pixfmt.h:254
planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:131
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
static uint8_t ana_convert(const int *coeff, const uint8_t *left, const uint8_t *right)
Definition: vf_stereo3d.c:315
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
AVFilter ff_vf_stereo3d
Definition: vf_stereo3d.c:1115
void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], const AVPixFmtDescriptor *pixdesc)
Compute the max pixel step for each plane of an image with a format described by pixdesc.
Definition: imgutils.c:35
const char * name
Pad name.
Definition: internal.h:60
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian ...
Definition: pixfmt.h:179
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
AVFrame * iright
Definition: vf_stereo3d.c:605
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian)
Definition: pixfmt.h:190
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1093
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
StereoComponent out
Definition: vf_stereo3d.c:142
uint8_t
#define av_cold
Definition: attributes.h:82
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:238
AVOptions.
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:103
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:205
#define AV_WB48(p, darg)
Definition: intreadwrite.h:481
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:251
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:191
static void anaglyph_ic(uint8_t *dst, uint8_t *lsrc, uint8_t *rsrc, ptrdiff_t dst_linesize, ptrdiff_t l_linesize, ptrdiff_t r_linesize, int width, int height, const int *ana_matrix_r, const int *ana_matrix_g, const int *ana_matrix_b)
Definition: vf_stereo3d.c:326
AVFrame * ileft
Definition: vf_stereo3d.c:605
static const AVFilterPad stereo3d_outputs[]
Definition: vf_stereo3d.c:1106
planar GBR 4:4:4 48bpp, big-endian
Definition: pixfmt.h:174
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:100
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
Definition: pixfmt.h:194
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:157
planar GBR 4:4:4 27bpp, big-endian
Definition: pixfmt.h:170
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:165
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_stereo3d.c:1090
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int width
Definition: frame.h:353
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:569
#define td
Definition: regdef.h:70
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
Definition: pixfmt.h:136
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), big-endian
Definition: pixfmt.h:182
const char * arg
Definition: jacosubdec.c:66
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:161
simple assert() macros that are a bit more flexible than ISO C assert().
planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
Definition: pixfmt.h:248
planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
Definition: pixfmt.h:134
AVFrame * prev
Definition: vf_stereo3d.c:150
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
Definition: pixfmt.h:183
#define FLAGS
Definition: vf_stereo3d.c:158
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:149
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, big-endian)
Definition: pixfmt.h:184
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
#define OFFSET(x)
Definition: vf_stereo3d.c:157
#define b
Definition: input.c:41
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
#define FFMIN(a, b)
Definition: common.h:96
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
static const AVFilterPad stereo3d_inputs[]
Definition: vf_stereo3d.c:1097
AVFormatContext * ctx
Definition: movenc.c:48
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
Definition: pixfmt.h:188
#define s(width, name)
Definition: cbs_vp9.c:257
planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), big-endian
Definition: pixfmt.h:180
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_stereo3d.c:609
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:243
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:158
planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:167
packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:148
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:540
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
static enum AVPixelFormat other_pix_fmts[]
Definition: vf_stereo3d.c:228
void ff_stereo3d_init_x86(Stereo3DDSPContext *dsp)
AVRational aspect
Definition: vf_stereo3d.c:153
static const AVOption stereo3d_options[]
Definition: vf_stereo3d.c:160
planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:132
misc drawing utilities
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:87
Used for passing data between threads.
Definition: dsddec.c:64
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
#define AV_RN16(p)
Definition: intreadwrite.h:360
planar GBR 4:4:4 30bpp, big-endian
Definition: pixfmt.h:172
planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian)
Definition: pixfmt.h:192
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:383
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2]...the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so...,+,-,+,-,+,+,-,+,-,+,...hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32-hcoeff[1]-hcoeff[2]-...a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2}an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||.........intra?||||:Block01:yes no||||:Block02:.................||||:Block03::y DC::ref index:||||:Block04::cb DC::motion x:||||.........:cr DC::motion y:||||.................|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------------------------------|||Y subbands||Cb subbands||Cr subbands||||------||------||------|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||------||------||------||||------||------||------|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||------||------||------||||------||------||------|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||------||------||------||||------||------||------|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------------------------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction------------|\Dequantization-------------------\||Reference frames|\IDWT|--------------|Motion\|||Frame 0||Frame 1||Compensation.OBMC v-------|--------------|--------------.\------> Frame n output Frame Frame<----------------------------------/|...|-------------------Range Coder:============Binary Range Coder:-------------------The implemented range coder is an adapted version based upon"Range encoding: an algorithm for removing redundancy from a digitised message."by G.N.N.Martin.The symbols encoded by the Snow range coder are bits(0|1).The associated probabilities are not fix but change depending on the symbol mix seen so far.bit seen|new state---------+-----------------------------------------------0|256-state_transition_table[256-old_state];1|state_transition_table[old_state];state_transition_table={0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:-------------------------FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1.the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:206
static enum AVPixelFormat anaglyph_pix_fmts[]
Definition: vf_stereo3d.c:223
planar GBR 4:4:4 42bpp, little-endian
Definition: pixfmt.h:257
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:193
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:89
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:195
Rational number (pair of numerator and denominator).
Definition: rational.h:58
planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:244
static int config_output(AVFilterLink *outlink)
Definition: vf_stereo3d.c:366
const int * ana_matrix[3]
Definition: vf_stereo3d.c:144
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:240
const char * name
Filter name.
Definition: avfilter.h:148
planar GBR 4:4:4 42bpp, big-endian
Definition: pixfmt.h:256
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), big-endian
Definition: pixfmt.h:178
#define AV_RN32(p)
Definition: intreadwrite.h:364
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
static int query_formats(AVFilterContext *ctx)
Definition: vf_stereo3d.c:282
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:187
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:163
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:135
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
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:247
#define AV_WN32(p, v)
Definition: intreadwrite.h:376
planar GBR 4:4:4 27bpp, little-endian
Definition: pixfmt.h:171
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:102
planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:133
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
int den
Denominator.
Definition: rational.h:60
avfilter_execute_func * execute
Definition: internal.h:155
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:185
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
Definition: vf_stereo3d.c:670
static const int ana_coeff[][3][6]
Definition: vf_stereo3d.c:81
planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:253
A list of supported formats for one end of a filter link.
Definition: formats.h:64
#define AV_RN64(p)
Definition: intreadwrite.h:368
static const double coeff[2][5]
Definition: vf_owdenoise.c:72
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:258
An instance of a filter.
Definition: avfilter.h:338
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, big-endian)
Definition: pixfmt.h:186
int in_off_left[4]
Definition: vf_stereo3d.c:152
int height
Definition: frame.h:353
FILE * out
Definition: movenc.c:54
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
void INT64 start
Definition: avisynth_c.h:766
#define AV_WN16(p, v)
Definition: intreadwrite.h:372
planar GBR 4:4:4 48bpp, little-endian
Definition: pixfmt.h:175
#define FFSWAP(type, a, b)
Definition: common.h:99
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:338
planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian
Definition: pixfmt.h:181
internal API functions
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
Stereo3DDSPContext dsp
Definition: vf_stereo3d.c:154
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:237
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
StereoCode
Definition: vf_stereo3d.c:35
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:74
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
Definition: pixfmt.h:242
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
Definition: pixfmt.h:164
planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
Definition: pixfmt.h:246
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
planar GBR 4:4:4 30bpp, little-endian
Definition: pixfmt.h:173
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:206
#define tb
Definition: regdef.h:68
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
#define AV_WN64(p, v)
Definition: intreadwrite.h:380
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
Definition: pixfmt.h:160