mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/vf_stereo3d: support interleaved rows as input format
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
09812e1200
commit
4b2bafbd4c
|
@ -71,6 +71,7 @@ typedef struct StereoComponent {
|
||||||
int off_left, off_right;
|
int off_left, off_right;
|
||||||
int off_lstep, off_rstep;
|
int off_lstep, off_rstep;
|
||||||
int row_left, row_right;
|
int row_left, row_right;
|
||||||
|
int row_step;
|
||||||
} StereoComponent;
|
} StereoComponent;
|
||||||
|
|
||||||
static const int ana_coeff[][3][6] = {
|
static const int ana_coeff[][3][6] = {
|
||||||
|
@ -136,7 +137,6 @@ typedef struct Stereo3DContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
StereoComponent in, out;
|
StereoComponent in, out;
|
||||||
int width, height;
|
int width, height;
|
||||||
int row_step;
|
|
||||||
const int *ana_matrix[3];
|
const int *ana_matrix[3];
|
||||||
int nb_planes;
|
int nb_planes;
|
||||||
int linesize[4];
|
int linesize[4];
|
||||||
|
@ -152,18 +152,20 @@ typedef struct Stereo3DContext {
|
||||||
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
|
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
|
||||||
|
|
||||||
static const AVOption stereo3d_options[] = {
|
static const AVOption stereo3d_options[] = {
|
||||||
{ "in", "set input format", OFFSET(in.format), AV_OPT_TYPE_INT, {.i64=SIDE_BY_SIDE_LR}, SIDE_BY_SIDE_LR, STEREO_CODE_COUNT-1, FLAGS, "in"},
|
{ "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"},
|
||||||
{ "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "in" },
|
{ "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "in" },
|
||||||
{ "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "in" },
|
{ "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "in" },
|
||||||
{ "abl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "in" },
|
{ "abl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "in" },
|
||||||
{ "abr", "above below right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL}, 0, 0, FLAGS, "in" },
|
{ "abr", "above below right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL}, 0, 0, FLAGS, "in" },
|
||||||
{ "al", "alternating frames left first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR}, 0, 0, FLAGS, "in" },
|
{ "al", "alternating frames left first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR}, 0, 0, FLAGS, "in" },
|
||||||
{ "ar", "alternating frames right first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL}, 0, 0, FLAGS, "in" },
|
{ "ar", "alternating frames right first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL}, 0, 0, FLAGS, "in" },
|
||||||
{ "sbs2l", "side by side half width left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR}, 0, 0, FLAGS, "in" },
|
{ "sbs2l", "side by side half width left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR}, 0, 0, FLAGS, "in" },
|
||||||
{ "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL}, 0, 0, FLAGS, "in" },
|
{ "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL}, 0, 0, FLAGS, "in" },
|
||||||
{ "sbsl", "side by side left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR}, 0, 0, FLAGS, "in" },
|
{ "sbsl", "side by side left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR}, 0, 0, FLAGS, "in" },
|
||||||
{ "sbsr", "side by side right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL}, 0, 0, FLAGS, "in" },
|
{ "sbsr", "side by side right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL}, 0, 0, FLAGS, "in" },
|
||||||
{ "out", "set output format", OFFSET(out.format), AV_OPT_TYPE_INT, {.i64=ANAGLYPH_RC_DUBOIS}, 0, STEREO_CODE_COUNT-1, FLAGS, "out"},
|
{ "irl", "interleave rows left first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_LR}, 0, 0, FLAGS, "in" },
|
||||||
|
{ "irr", "interleave rows right first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_RL}, 0, 0, FLAGS, "in" },
|
||||||
|
{ "out", "set output format", OFFSET(out.format), AV_OPT_TYPE_INT, {.i64=ANAGLYPH_RC_DUBOIS}, 0, STEREO_CODE_COUNT-1, FLAGS, "out"},
|
||||||
{ "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "out" },
|
{ "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "out" },
|
||||||
{ "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "out" },
|
{ "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "out" },
|
||||||
{ "abl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "out" },
|
{ "abl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "out" },
|
||||||
|
@ -312,6 +314,8 @@ static int config_output(AVFilterLink *outlink)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case INTERLEAVE_ROWS_LR:
|
||||||
|
case INTERLEAVE_ROWS_RL:
|
||||||
case ABOVE_BELOW_2_LR:
|
case ABOVE_BELOW_2_LR:
|
||||||
case ABOVE_BELOW_LR:
|
case ABOVE_BELOW_LR:
|
||||||
case ABOVE_BELOW_2_RL:
|
case ABOVE_BELOW_2_RL:
|
||||||
|
@ -334,13 +338,13 @@ static int config_output(AVFilterLink *outlink)
|
||||||
s->width = inlink->w;
|
s->width = inlink->w;
|
||||||
s->in.height =
|
s->in.height =
|
||||||
s->height = inlink->h;
|
s->height = inlink->h;
|
||||||
s->row_step = 1;
|
|
||||||
s->in.off_lstep =
|
s->in.off_lstep =
|
||||||
s->in.off_rstep =
|
s->in.off_rstep =
|
||||||
s->in.off_left =
|
s->in.off_left =
|
||||||
s->in.off_right =
|
s->in.off_right =
|
||||||
s->in.row_left =
|
s->in.row_left =
|
||||||
s->in.row_right = 0;
|
s->in.row_right = 0;
|
||||||
|
s->in.row_step = 1;
|
||||||
|
|
||||||
switch (s->in.format) {
|
switch (s->in.format) {
|
||||||
case SIDE_BY_SIDE_2_LR:
|
case SIDE_BY_SIDE_2_LR:
|
||||||
|
@ -373,6 +377,19 @@ static int config_output(AVFilterLink *outlink)
|
||||||
fps.den *= 2;
|
fps.den *= 2;
|
||||||
tb.num *= 2;
|
tb.num *= 2;
|
||||||
break;
|
break;
|
||||||
|
case INTERLEAVE_ROWS_LR:
|
||||||
|
case INTERLEAVE_ROWS_RL:
|
||||||
|
s->in.row_step = 2;
|
||||||
|
if (s->in.format == INTERLEAVE_ROWS_RL)
|
||||||
|
s->in.off_lstep = 1;
|
||||||
|
else
|
||||||
|
s->in.off_rstep = 1;
|
||||||
|
if (s->out.format != INTERLEAVE_ROWS_LR &&
|
||||||
|
s->out.format != INTERLEAVE_ROWS_RL &&
|
||||||
|
s->out.format != CHECKERBOARD_LR &&
|
||||||
|
s->out.format != CHECKERBOARD_RL)
|
||||||
|
s->height = inlink->h / 2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
av_log(ctx, AV_LOG_ERROR, "input format %d is not supported\n", s->in.format);
|
av_log(ctx, AV_LOG_ERROR, "input format %d is not supported\n", s->in.format);
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
|
@ -386,6 +403,7 @@ static int config_output(AVFilterLink *outlink)
|
||||||
s->out.off_right =
|
s->out.off_right =
|
||||||
s->out.row_left =
|
s->out.row_left =
|
||||||
s->out.row_right = 0;
|
s->out.row_right = 0;
|
||||||
|
s->out.row_step = 1;
|
||||||
|
|
||||||
switch (s->out.format) {
|
switch (s->out.format) {
|
||||||
case ANAGLYPH_RB_GRAY:
|
case ANAGLYPH_RB_GRAY:
|
||||||
|
@ -435,21 +453,28 @@ static int config_output(AVFilterLink *outlink)
|
||||||
s->out.row_left = s->height;
|
s->out.row_left = s->height;
|
||||||
break;
|
break;
|
||||||
case INTERLEAVE_ROWS_LR:
|
case INTERLEAVE_ROWS_LR:
|
||||||
s->row_step = 2;
|
s->in.row_step = 2;
|
||||||
|
s->out.row_step = 2;
|
||||||
s->height = s->height / 2;
|
s->height = s->height / 2;
|
||||||
s->out.off_rstep =
|
s->out.off_rstep = 1;
|
||||||
s->in.off_rstep = 1;
|
s->in.off_rstep = s->in.format != INTERLEAVE_ROWS_RL;
|
||||||
break;
|
break;
|
||||||
case INTERLEAVE_ROWS_RL:
|
case INTERLEAVE_ROWS_RL:
|
||||||
s->row_step = 2;
|
s->in.row_step = 2;
|
||||||
|
s->out.row_step = 2;
|
||||||
s->height = s->height / 2;
|
s->height = s->height / 2;
|
||||||
s->out.off_lstep =
|
s->out.off_lstep = 1;
|
||||||
s->in.off_lstep = 1;
|
s->in.off_lstep = s->in.format != INTERLEAVE_ROWS_LR;
|
||||||
break;
|
break;
|
||||||
case MONO_R:
|
case MONO_R:
|
||||||
s->in.off_left = s->in.off_right;
|
s->in.off_left = s->in.off_right;
|
||||||
s->in.row_left = s->in.row_right;
|
s->in.row_left = s->in.row_right;
|
||||||
|
if (s->in.format == INTERLEAVE_ROWS_LR)
|
||||||
|
FFSWAP(int, s->in.off_lstep, s->in.off_rstep);
|
||||||
|
break;
|
||||||
case MONO_L:
|
case MONO_L:
|
||||||
|
if (s->in.format == INTERLEAVE_ROWS_RL)
|
||||||
|
FFSWAP(int, s->in.off_lstep, s->in.off_rstep);
|
||||||
break;
|
break;
|
||||||
case ALTERNATING_RL:
|
case ALTERNATING_RL:
|
||||||
case ALTERNATING_LR:
|
case ALTERNATING_LR:
|
||||||
|
@ -519,8 +544,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
|
||||||
|
|
||||||
for (y = start; y < end; y++) {
|
for (y = start; y < end; y++) {
|
||||||
o = out->linesize[0] * y;
|
o = out->linesize[0] * y;
|
||||||
il = s->in_off_left[0] + y * ileft->linesize[0];
|
il = s->in_off_left[0] + y * ileft->linesize[0] * s->in.row_step;
|
||||||
ir = s->in_off_right[0] + y * iright->linesize[0];
|
ir = s->in_off_right[0] + y * iright->linesize[0] * s->in.row_step;
|
||||||
for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) {
|
for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) {
|
||||||
dst[o ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir);
|
dst[o ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir);
|
||||||
dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir);
|
dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir);
|
||||||
|
@ -540,6 +565,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
|
||||||
int out_off_left[4], out_off_right[4];
|
int out_off_left[4], out_off_right[4];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (s->in.format == s->out.format)
|
||||||
|
return ff_filter_frame(outlink, inpicref);
|
||||||
|
|
||||||
switch (s->in.format) {
|
switch (s->in.format) {
|
||||||
case ALTERNATING_LR:
|
case ALTERNATING_LR:
|
||||||
case ALTERNATING_RL:
|
case ALTERNATING_RL:
|
||||||
|
@ -600,14 +628,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
|
||||||
case INTERLEAVE_ROWS_RL:
|
case INTERLEAVE_ROWS_RL:
|
||||||
for (i = 0; i < s->nb_planes; i++) {
|
for (i = 0; i < s->nb_planes; i++) {
|
||||||
av_image_copy_plane(oleft->data[i] + out_off_left[i],
|
av_image_copy_plane(oleft->data[i] + out_off_left[i],
|
||||||
oleft->linesize[i] * s->row_step,
|
oleft->linesize[i] * s->out.row_step,
|
||||||
ileft->data[i] + s->in_off_left[i],
|
ileft->data[i] + s->in_off_left[i],
|
||||||
ileft->linesize[i] * s->row_step,
|
ileft->linesize[i] * s->in.row_step,
|
||||||
s->linesize[i], s->pheight[i]);
|
s->linesize[i], s->pheight[i]);
|
||||||
av_image_copy_plane(oright->data[i] + out_off_right[i],
|
av_image_copy_plane(oright->data[i] + out_off_right[i],
|
||||||
oright->linesize[i] * s->row_step,
|
oright->linesize[i] * s->out.row_step,
|
||||||
iright->data[i] + s->in_off_right[i],
|
iright->data[i] + s->in_off_right[i],
|
||||||
iright->linesize[i] * s->row_step,
|
iright->linesize[i] * s->in.row_step,
|
||||||
s->linesize[i], s->pheight[i]);
|
s->linesize[i], s->pheight[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -617,7 +645,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
|
||||||
for (i = 0; i < s->nb_planes; i++) {
|
for (i = 0; i < s->nb_planes; i++) {
|
||||||
av_image_copy_plane(out->data[i], out->linesize[i],
|
av_image_copy_plane(out->data[i], out->linesize[i],
|
||||||
iright->data[i] + s->in_off_left[i],
|
iright->data[i] + s->in_off_left[i],
|
||||||
iright->linesize[i],
|
iright->linesize[i] * s->in.row_step,
|
||||||
s->linesize[i], s->pheight[i]);
|
s->linesize[i], s->pheight[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue