Re: [FFmpeg-devel] [PATCH v6 1/2] lavf/vf_transpose: add exif orientation support

2019-06-04 Thread Jun Li
On Tue, Jun 4, 2019 at 12:50 AM Paul B Mahol  wrote:

> On 5/31/19, Jun Li  wrote:
> > Add exif orientation support and expose an option.
> > ---
> >  libavfilter/hflip.h|   2 +
> >  libavfilter/transpose.h|  14 
> >  libavfilter/vf_hflip.c |  40 ++---
> >  libavfilter/vf_transpose.c | 161 -
> >  4 files changed, 185 insertions(+), 32 deletions(-)
> >
> > diff --git a/libavfilter/hflip.h b/libavfilter/hflip.h
> > index 204090dbb4..4e89bae3fc 100644
> > --- a/libavfilter/hflip.h
> > +++ b/libavfilter/hflip.h
> > @@ -35,5 +35,7 @@ typedef struct FlipContext {
> >
> >  int ff_hflip_init(FlipContext *s, int step[4], int nb_planes);
> >  void ff_hflip_init_x86(FlipContext *s, int step[4], int nb_planes);
> > +int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink);
> > +int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int
> > job, int nb_jobs, int vlifp);
> >
> >  #endif /* AVFILTER_HFLIP_H */
> > diff --git a/libavfilter/transpose.h b/libavfilter/transpose.h
> > index aa262b9487..5da08bddc0 100644
> > --- a/libavfilter/transpose.h
> > +++ b/libavfilter/transpose.h
> > @@ -34,4 +34,18 @@ enum TransposeDir {
> >  TRANSPOSE_VFLIP,
> >  };
> >
> > +enum OrientationType {
> > +ORIENTATION_AUTO_TRANSPOSE = -2,
> > +ORIENTATION_AUTO_FLIP = -1,
> > +ORIENTATION_NONE = 0,
> > +ORIENTATION_NORMAL,
> > +ORIENTATION_HFLIP,
> > +ORIENTATION_ROTATE180,
> > +ORIENTATION_VFLIP,
> > +ORIENTATION_HFLIP_ROTATE270CW,
> > +ORIENTATION_ROTATE90CW,
> > +ORIENTATION_HFLIP_ROTATE90CW,
> > +ORIENTATION_ROTATE270CW
> > +};
> > +
> >  #endif
> > diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
> > index b77afc77fc..d24ca5c2e7 100644
> > --- a/libavfilter/vf_hflip.c
> > +++ b/libavfilter/vf_hflip.c
> > @@ -125,9 +125,8 @@ static void hflip_qword_c(const uint8_t *ssrc,
> uint8_t
> > *ddst, int w)
> >  dst[j] = src[-j];
> >  }
> >
> > -static int config_props(AVFilterLink *inlink)
> > +int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink)
> >  {
> > -FlipContext *s = inlink->dst->priv;
> >  const AVPixFmtDescriptor *pix_desc =
> > av_pix_fmt_desc_get(inlink->format);
> >  const int hsub = pix_desc->log2_chroma_w;
> >  const int vsub = pix_desc->log2_chroma_h;
> > @@ -144,6 +143,12 @@ static int config_props(AVFilterLink *inlink)
> >  return ff_hflip_init(s, s->max_step, nb_planes);
> >  }
> >
> > +static int config_props(AVFilterLink *inlink)
> > +{
> > +FlipContext *s = inlink->dst->priv;
> > +return ff_hflip_config_props(s, inlink);
> > +}
> > +
> >  int ff_hflip_init(FlipContext *s, int step[4], int nb_planes)
> >  {
> >  int i;
> > @@ -170,14 +175,10 @@ typedef struct ThreadData {
> >  AVFrame *in, *out;
> >  } ThreadData;
> >
> > -static int filter_slice(AVFilterContext *ctx, void *arg, int job, int
> > nb_jobs)
> > +int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int
> > job, int nb_jobs, int vflip)
> >  {
> > -FlipContext *s = ctx->priv;
> > -ThreadData *td = arg;
> > -AVFrame *in = td->in;
> > -AVFrame *out = td->out;
> >  uint8_t *inrow, *outrow;
> > -int i, plane, step;
> > +int i, plane, step, outlinesize;
> >
> >  for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane];
> > plane++) {
> >  const int width  = s->planewidth[plane];
> > @@ -187,19 +188,36 @@ static int filter_slice(AVFilterContext *ctx, void
> > *arg, int job, int nb_jobs)
> >
> >  step = s->max_step[plane];
> >
> > -outrow = out->data[plane] + start * out->linesize[plane];
> > -inrow  = in ->data[plane] + start * in->linesize[plane] +
> (width -
> > 1) * step;
> > +if (vflip) {
> > +outrow = out->data[plane] + (height - start - 1)*
> > out->linesize[plane];
> > +outlinesize = -out->linesize[plane];
> > +} else {
> > +outrow = out->data[plane] + start * out->linesize[plane];
> > +outlinesize = out->linesize[plane];
> > +}
> > +
> > +inrow = in->data[plane] + start * in->linesize[plane] +  (width
> -
> > 1) * step;
> > +
> >  for (i = start; i < end; i++) {
> >  s->flip_line[plane](inrow, outrow, width);
> >
> >  inrow  += in ->linesize[plane];
> > -outrow += out->linesize[plane];
> > +outrow += outlinesize;
> >  }
> >  }
> >
> >  return 0;
> >  }
> >
> > +static int filter_slice(AVFilterContext *ctx, void *arg, int job, int
> > nb_jobs)
> > +{
> > +FlipContext *s = ctx->priv;
> > +ThreadData *td = arg;
> > +AVFrame *in = td->in;
> > +AVFrame *out = td->out;
> > +return ff_hflip_filter_slice(s, in, out, job, nb_jobs, 0);
> > +}
> > +
> >  static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> >  {
> >  AVFilterContext *ctx  = inlink->dst;
> > diff --git a/libavfilter/vf_transpose.c 

Re: [FFmpeg-devel] [PATCH v6 1/2] lavf/vf_transpose: add exif orientation support

2019-06-04 Thread Paul B Mahol
On 5/31/19, Jun Li  wrote:
> Add exif orientation support and expose an option.
> ---
>  libavfilter/hflip.h|   2 +
>  libavfilter/transpose.h|  14 
>  libavfilter/vf_hflip.c |  40 ++---
>  libavfilter/vf_transpose.c | 161 -
>  4 files changed, 185 insertions(+), 32 deletions(-)
>
> diff --git a/libavfilter/hflip.h b/libavfilter/hflip.h
> index 204090dbb4..4e89bae3fc 100644
> --- a/libavfilter/hflip.h
> +++ b/libavfilter/hflip.h
> @@ -35,5 +35,7 @@ typedef struct FlipContext {
>
>  int ff_hflip_init(FlipContext *s, int step[4], int nb_planes);
>  void ff_hflip_init_x86(FlipContext *s, int step[4], int nb_planes);
> +int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink);
> +int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int
> job, int nb_jobs, int vlifp);
>
>  #endif /* AVFILTER_HFLIP_H */
> diff --git a/libavfilter/transpose.h b/libavfilter/transpose.h
> index aa262b9487..5da08bddc0 100644
> --- a/libavfilter/transpose.h
> +++ b/libavfilter/transpose.h
> @@ -34,4 +34,18 @@ enum TransposeDir {
>  TRANSPOSE_VFLIP,
>  };
>
> +enum OrientationType {
> +ORIENTATION_AUTO_TRANSPOSE = -2,
> +ORIENTATION_AUTO_FLIP = -1,
> +ORIENTATION_NONE = 0,
> +ORIENTATION_NORMAL,
> +ORIENTATION_HFLIP,
> +ORIENTATION_ROTATE180,
> +ORIENTATION_VFLIP,
> +ORIENTATION_HFLIP_ROTATE270CW,
> +ORIENTATION_ROTATE90CW,
> +ORIENTATION_HFLIP_ROTATE90CW,
> +ORIENTATION_ROTATE270CW
> +};
> +
>  #endif
> diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
> index b77afc77fc..d24ca5c2e7 100644
> --- a/libavfilter/vf_hflip.c
> +++ b/libavfilter/vf_hflip.c
> @@ -125,9 +125,8 @@ static void hflip_qword_c(const uint8_t *ssrc, uint8_t
> *ddst, int w)
>  dst[j] = src[-j];
>  }
>
> -static int config_props(AVFilterLink *inlink)
> +int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink)
>  {
> -FlipContext *s = inlink->dst->priv;
>  const AVPixFmtDescriptor *pix_desc =
> av_pix_fmt_desc_get(inlink->format);
>  const int hsub = pix_desc->log2_chroma_w;
>  const int vsub = pix_desc->log2_chroma_h;
> @@ -144,6 +143,12 @@ static int config_props(AVFilterLink *inlink)
>  return ff_hflip_init(s, s->max_step, nb_planes);
>  }
>
> +static int config_props(AVFilterLink *inlink)
> +{
> +FlipContext *s = inlink->dst->priv;
> +return ff_hflip_config_props(s, inlink);
> +}
> +
>  int ff_hflip_init(FlipContext *s, int step[4], int nb_planes)
>  {
>  int i;
> @@ -170,14 +175,10 @@ typedef struct ThreadData {
>  AVFrame *in, *out;
>  } ThreadData;
>
> -static int filter_slice(AVFilterContext *ctx, void *arg, int job, int
> nb_jobs)
> +int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int
> job, int nb_jobs, int vflip)
>  {
> -FlipContext *s = ctx->priv;
> -ThreadData *td = arg;
> -AVFrame *in = td->in;
> -AVFrame *out = td->out;
>  uint8_t *inrow, *outrow;
> -int i, plane, step;
> +int i, plane, step, outlinesize;
>
>  for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane];
> plane++) {
>  const int width  = s->planewidth[plane];
> @@ -187,19 +188,36 @@ static int filter_slice(AVFilterContext *ctx, void
> *arg, int job, int nb_jobs)
>
>  step = s->max_step[plane];
>
> -outrow = out->data[plane] + start * out->linesize[plane];
> -inrow  = in ->data[plane] + start * in->linesize[plane] + (width -
> 1) * step;
> +if (vflip) {
> +outrow = out->data[plane] + (height - start - 1)*
> out->linesize[plane];
> +outlinesize = -out->linesize[plane];
> +} else {
> +outrow = out->data[plane] + start * out->linesize[plane];
> +outlinesize = out->linesize[plane];
> +}
> +
> +inrow = in->data[plane] + start * in->linesize[plane] +  (width -
> 1) * step;
> +
>  for (i = start; i < end; i++) {
>  s->flip_line[plane](inrow, outrow, width);
>
>  inrow  += in ->linesize[plane];
> -outrow += out->linesize[plane];
> +outrow += outlinesize;
>  }
>  }
>
>  return 0;
>  }
>
> +static int filter_slice(AVFilterContext *ctx, void *arg, int job, int
> nb_jobs)
> +{
> +FlipContext *s = ctx->priv;
> +ThreadData *td = arg;
> +AVFrame *in = td->in;
> +AVFrame *out = td->out;
> +return ff_hflip_filter_slice(s, in, out, job, nb_jobs, 0);
> +}
> +
>  static int filter_frame(AVFilterLink *inlink, AVFrame *in)
>  {
>  AVFilterContext *ctx  = inlink->dst;
> diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
> index dd54947bd9..8b5c8d3f50 100644
> --- a/libavfilter/vf_transpose.c
> +++ b/libavfilter/vf_transpose.c
> @@ -39,6 +39,7 @@
>  #include "internal.h"
>  #include "video.h"
>  #include "transpose.h"
> +#include "hflip.h"
>
>  typedef struct TransVtable {
>  void (*transpose_8x8)(uint8_t *src, ptrdiff_t src_linesize,

Re: [FFmpeg-devel] [PATCH v6 1/2] lavf/vf_transpose: add exif orientation support

2019-06-03 Thread Jun Li
On Fri, May 31, 2019 at 6:15 PM Jun Li  wrote:

>
> On Thu, May 30, 2019 at 5:29 PM Jun Li  wrote:
>
>> Add exif orientation support and expose an option.
>> ---
>>  libavfilter/hflip.h|   2 +
>>  libavfilter/transpose.h|  14 
>>  libavfilter/vf_hflip.c |  40 ++---
>>  libavfilter/vf_transpose.c | 161 -
>>  4 files changed, 185 insertions(+), 32 deletions(-)
>>
>> diff --git a/libavfilter/hflip.h b/libavfilter/hflip.h
>> index 204090dbb4..4e89bae3fc 100644
>> --- a/libavfilter/hflip.h
>> +++ b/libavfilter/hflip.h
>> @@ -35,5 +35,7 @@ typedef struct FlipContext {
>>
>>  int ff_hflip_init(FlipContext *s, int step[4], int nb_planes);
>>  void ff_hflip_init_x86(FlipContext *s, int step[4], int nb_planes);
>> +int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink);
>> +int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int
>> job, int nb_jobs, int vlifp);
>>
>>  #endif /* AVFILTER_HFLIP_H */
>> diff --git a/libavfilter/transpose.h b/libavfilter/transpose.h
>> index aa262b9487..5da08bddc0 100644
>> --- a/libavfilter/transpose.h
>> +++ b/libavfilter/transpose.h
>> @@ -34,4 +34,18 @@ enum TransposeDir {
>>  TRANSPOSE_VFLIP,
>>  };
>>
>> +enum OrientationType {
>> +ORIENTATION_AUTO_TRANSPOSE = -2,
>> +ORIENTATION_AUTO_FLIP = -1,
>> +ORIENTATION_NONE = 0,
>> +ORIENTATION_NORMAL,
>> +ORIENTATION_HFLIP,
>> +ORIENTATION_ROTATE180,
>> +ORIENTATION_VFLIP,
>> +ORIENTATION_HFLIP_ROTATE270CW,
>> +ORIENTATION_ROTATE90CW,
>> +ORIENTATION_HFLIP_ROTATE90CW,
>> +ORIENTATION_ROTATE270CW
>> +};
>> +
>>  #endif
>> diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
>> index b77afc77fc..d24ca5c2e7 100644
>> --- a/libavfilter/vf_hflip.c
>> +++ b/libavfilter/vf_hflip.c
>> @@ -125,9 +125,8 @@ static void hflip_qword_c(const uint8_t *ssrc,
>> uint8_t *ddst, int w)
>>  dst[j] = src[-j];
>>  }
>>
>> -static int config_props(AVFilterLink *inlink)
>> +int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink)
>>  {
>> -FlipContext *s = inlink->dst->priv;
>>  const AVPixFmtDescriptor *pix_desc =
>> av_pix_fmt_desc_get(inlink->format);
>>  const int hsub = pix_desc->log2_chroma_w;
>>  const int vsub = pix_desc->log2_chroma_h;
>> @@ -144,6 +143,12 @@ static int config_props(AVFilterLink *inlink)
>>  return ff_hflip_init(s, s->max_step, nb_planes);
>>  }
>>
>> +static int config_props(AVFilterLink *inlink)
>> +{
>> +FlipContext *s = inlink->dst->priv;
>> +return ff_hflip_config_props(s, inlink);
>> +}
>> +
>>  int ff_hflip_init(FlipContext *s, int step[4], int nb_planes)
>>  {
>>  int i;
>> @@ -170,14 +175,10 @@ typedef struct ThreadData {
>>  AVFrame *in, *out;
>>  } ThreadData;
>>
>> -static int filter_slice(AVFilterContext *ctx, void *arg, int job, int
>> nb_jobs)
>> +int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int
>> job, int nb_jobs, int vflip)
>>  {
>> -FlipContext *s = ctx->priv;
>> -ThreadData *td = arg;
>> -AVFrame *in = td->in;
>> -AVFrame *out = td->out;
>>  uint8_t *inrow, *outrow;
>> -int i, plane, step;
>> +int i, plane, step, outlinesize;
>>
>>  for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane];
>> plane++) {
>>  const int width  = s->planewidth[plane];
>> @@ -187,19 +188,36 @@ static int filter_slice(AVFilterContext *ctx, void
>> *arg, int job, int nb_jobs)
>>
>>  step = s->max_step[plane];
>>
>> -outrow = out->data[plane] + start * out->linesize[plane];
>> -inrow  = in ->data[plane] + start * in->linesize[plane] + (width
>> - 1) * step;
>> +if (vflip) {
>> +outrow = out->data[plane] + (height - start - 1)*
>> out->linesize[plane];
>> +outlinesize = -out->linesize[plane];
>> +} else {
>> +outrow = out->data[plane] + start * out->linesize[plane];
>> +outlinesize = out->linesize[plane];
>> +}
>> +
>> +inrow = in->data[plane] + start * in->linesize[plane] +  (width
>> - 1) * step;
>> +
>>  for (i = start; i < end; i++) {
>>  s->flip_line[plane](inrow, outrow, width);
>>
>>  inrow  += in ->linesize[plane];
>> -outrow += out->linesize[plane];
>> +outrow += outlinesize;
>>  }
>>  }
>>
>>  return 0;
>>  }
>>
>> +static int filter_slice(AVFilterContext *ctx, void *arg, int job, int
>> nb_jobs)
>> +{
>> +FlipContext *s = ctx->priv;
>> +ThreadData *td = arg;
>> +AVFrame *in = td->in;
>> +AVFrame *out = td->out;
>> +return ff_hflip_filter_slice(s, in, out, job, nb_jobs, 0);
>> +}
>> +
>>  static int filter_frame(AVFilterLink *inlink, AVFrame *in)
>>  {
>>  AVFilterContext *ctx  = inlink->dst;
>> diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
>> index dd54947bd9..8b5c8d3f50 100644
>> --- a/libavfilter/vf_transpose.c
>> +++ b/libavfilter/vf_transpose.c

Re: [FFmpeg-devel] [PATCH v6 1/2] lavf/vf_transpose: add exif orientation support

2019-05-31 Thread Jun Li
On Thu, May 30, 2019 at 5:29 PM Jun Li  wrote:

> Add exif orientation support and expose an option.
> ---
>  libavfilter/hflip.h|   2 +
>  libavfilter/transpose.h|  14 
>  libavfilter/vf_hflip.c |  40 ++---
>  libavfilter/vf_transpose.c | 161 -
>  4 files changed, 185 insertions(+), 32 deletions(-)
>
> diff --git a/libavfilter/hflip.h b/libavfilter/hflip.h
> index 204090dbb4..4e89bae3fc 100644
> --- a/libavfilter/hflip.h
> +++ b/libavfilter/hflip.h
> @@ -35,5 +35,7 @@ typedef struct FlipContext {
>
>  int ff_hflip_init(FlipContext *s, int step[4], int nb_planes);
>  void ff_hflip_init_x86(FlipContext *s, int step[4], int nb_planes);
> +int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink);
> +int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int
> job, int nb_jobs, int vlifp);
>
>  #endif /* AVFILTER_HFLIP_H */
> diff --git a/libavfilter/transpose.h b/libavfilter/transpose.h
> index aa262b9487..5da08bddc0 100644
> --- a/libavfilter/transpose.h
> +++ b/libavfilter/transpose.h
> @@ -34,4 +34,18 @@ enum TransposeDir {
>  TRANSPOSE_VFLIP,
>  };
>
> +enum OrientationType {
> +ORIENTATION_AUTO_TRANSPOSE = -2,
> +ORIENTATION_AUTO_FLIP = -1,
> +ORIENTATION_NONE = 0,
> +ORIENTATION_NORMAL,
> +ORIENTATION_HFLIP,
> +ORIENTATION_ROTATE180,
> +ORIENTATION_VFLIP,
> +ORIENTATION_HFLIP_ROTATE270CW,
> +ORIENTATION_ROTATE90CW,
> +ORIENTATION_HFLIP_ROTATE90CW,
> +ORIENTATION_ROTATE270CW
> +};
> +
>  #endif
> diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
> index b77afc77fc..d24ca5c2e7 100644
> --- a/libavfilter/vf_hflip.c
> +++ b/libavfilter/vf_hflip.c
> @@ -125,9 +125,8 @@ static void hflip_qword_c(const uint8_t *ssrc, uint8_t
> *ddst, int w)
>  dst[j] = src[-j];
>  }
>
> -static int config_props(AVFilterLink *inlink)
> +int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink)
>  {
> -FlipContext *s = inlink->dst->priv;
>  const AVPixFmtDescriptor *pix_desc =
> av_pix_fmt_desc_get(inlink->format);
>  const int hsub = pix_desc->log2_chroma_w;
>  const int vsub = pix_desc->log2_chroma_h;
> @@ -144,6 +143,12 @@ static int config_props(AVFilterLink *inlink)
>  return ff_hflip_init(s, s->max_step, nb_planes);
>  }
>
> +static int config_props(AVFilterLink *inlink)
> +{
> +FlipContext *s = inlink->dst->priv;
> +return ff_hflip_config_props(s, inlink);
> +}
> +
>  int ff_hflip_init(FlipContext *s, int step[4], int nb_planes)
>  {
>  int i;
> @@ -170,14 +175,10 @@ typedef struct ThreadData {
>  AVFrame *in, *out;
>  } ThreadData;
>
> -static int filter_slice(AVFilterContext *ctx, void *arg, int job, int
> nb_jobs)
> +int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int
> job, int nb_jobs, int vflip)
>  {
> -FlipContext *s = ctx->priv;
> -ThreadData *td = arg;
> -AVFrame *in = td->in;
> -AVFrame *out = td->out;
>  uint8_t *inrow, *outrow;
> -int i, plane, step;
> +int i, plane, step, outlinesize;
>
>  for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane];
> plane++) {
>  const int width  = s->planewidth[plane];
> @@ -187,19 +188,36 @@ static int filter_slice(AVFilterContext *ctx, void
> *arg, int job, int nb_jobs)
>
>  step = s->max_step[plane];
>
> -outrow = out->data[plane] + start * out->linesize[plane];
> -inrow  = in ->data[plane] + start * in->linesize[plane] + (width
> - 1) * step;
> +if (vflip) {
> +outrow = out->data[plane] + (height - start - 1)*
> out->linesize[plane];
> +outlinesize = -out->linesize[plane];
> +} else {
> +outrow = out->data[plane] + start * out->linesize[plane];
> +outlinesize = out->linesize[plane];
> +}
> +
> +inrow = in->data[plane] + start * in->linesize[plane] +  (width -
> 1) * step;
> +
>  for (i = start; i < end; i++) {
>  s->flip_line[plane](inrow, outrow, width);
>
>  inrow  += in ->linesize[plane];
> -outrow += out->linesize[plane];
> +outrow += outlinesize;
>  }
>  }
>
>  return 0;
>  }
>
> +static int filter_slice(AVFilterContext *ctx, void *arg, int job, int
> nb_jobs)
> +{
> +FlipContext *s = ctx->priv;
> +ThreadData *td = arg;
> +AVFrame *in = td->in;
> +AVFrame *out = td->out;
> +return ff_hflip_filter_slice(s, in, out, job, nb_jobs, 0);
> +}
> +
>  static int filter_frame(AVFilterLink *inlink, AVFrame *in)
>  {
>  AVFilterContext *ctx  = inlink->dst;
> diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
> index dd54947bd9..8b5c8d3f50 100644
> --- a/libavfilter/vf_transpose.c
> +++ b/libavfilter/vf_transpose.c
> @@ -39,6 +39,7 @@
>  #include "internal.h"
>  #include "video.h"
>  #include "transpose.h"
> +#include "hflip.h"
>
>  typedef struct TransVtable {
>  void (*transpose_8x8)(uint8_t *src, 

[FFmpeg-devel] [PATCH v6 1/2] lavf/vf_transpose: add exif orientation support

2019-05-30 Thread Jun Li
Add exif orientation support and expose an option.
---
 libavfilter/hflip.h|   2 +
 libavfilter/transpose.h|  14 
 libavfilter/vf_hflip.c |  40 ++---
 libavfilter/vf_transpose.c | 161 -
 4 files changed, 185 insertions(+), 32 deletions(-)

diff --git a/libavfilter/hflip.h b/libavfilter/hflip.h
index 204090dbb4..4e89bae3fc 100644
--- a/libavfilter/hflip.h
+++ b/libavfilter/hflip.h
@@ -35,5 +35,7 @@ typedef struct FlipContext {
 
 int ff_hflip_init(FlipContext *s, int step[4], int nb_planes);
 void ff_hflip_init_x86(FlipContext *s, int step[4], int nb_planes);
+int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink);
+int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int job, 
int nb_jobs, int vlifp);
 
 #endif /* AVFILTER_HFLIP_H */
diff --git a/libavfilter/transpose.h b/libavfilter/transpose.h
index aa262b9487..5da08bddc0 100644
--- a/libavfilter/transpose.h
+++ b/libavfilter/transpose.h
@@ -34,4 +34,18 @@ enum TransposeDir {
 TRANSPOSE_VFLIP,
 };
 
+enum OrientationType {
+ORIENTATION_AUTO_TRANSPOSE = -2,
+ORIENTATION_AUTO_FLIP = -1,
+ORIENTATION_NONE = 0,
+ORIENTATION_NORMAL,
+ORIENTATION_HFLIP,
+ORIENTATION_ROTATE180,
+ORIENTATION_VFLIP,
+ORIENTATION_HFLIP_ROTATE270CW,
+ORIENTATION_ROTATE90CW,
+ORIENTATION_HFLIP_ROTATE90CW,
+ORIENTATION_ROTATE270CW
+};
+
 #endif
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index b77afc77fc..d24ca5c2e7 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -125,9 +125,8 @@ static void hflip_qword_c(const uint8_t *ssrc, uint8_t 
*ddst, int w)
 dst[j] = src[-j];
 }
 
-static int config_props(AVFilterLink *inlink)
+int ff_hflip_config_props(FlipContext* s, AVFilterLink *inlink)
 {
-FlipContext *s = inlink->dst->priv;
 const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
 const int hsub = pix_desc->log2_chroma_w;
 const int vsub = pix_desc->log2_chroma_h;
@@ -144,6 +143,12 @@ static int config_props(AVFilterLink *inlink)
 return ff_hflip_init(s, s->max_step, nb_planes);
 }
 
+static int config_props(AVFilterLink *inlink)
+{
+FlipContext *s = inlink->dst->priv;
+return ff_hflip_config_props(s, inlink);
+}
+
 int ff_hflip_init(FlipContext *s, int step[4], int nb_planes)
 {
 int i;
@@ -170,14 +175,10 @@ typedef struct ThreadData {
 AVFrame *in, *out;
 } ThreadData;
 
-static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
+int ff_hflip_filter_slice(FlipContext *s, AVFrame *in, AVFrame *out, int job, 
int nb_jobs, int vflip)
 {
-FlipContext *s = ctx->priv;
-ThreadData *td = arg;
-AVFrame *in = td->in;
-AVFrame *out = td->out;
 uint8_t *inrow, *outrow;
-int i, plane, step;
+int i, plane, step, outlinesize;
 
 for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; 
plane++) {
 const int width  = s->planewidth[plane];
@@ -187,19 +188,36 @@ static int filter_slice(AVFilterContext *ctx, void *arg, 
int job, int nb_jobs)
 
 step = s->max_step[plane];
 
-outrow = out->data[plane] + start * out->linesize[plane];
-inrow  = in ->data[plane] + start * in->linesize[plane] + (width - 1) 
* step;
+if (vflip) {
+outrow = out->data[plane] + (height - start - 1)* 
out->linesize[plane];
+outlinesize = -out->linesize[plane];
+} else {
+outrow = out->data[plane] + start * out->linesize[plane];
+outlinesize = out->linesize[plane];
+}
+
+inrow = in->data[plane] + start * in->linesize[plane] +  (width - 1) * 
step;
+
 for (i = start; i < end; i++) {
 s->flip_line[plane](inrow, outrow, width);
 
 inrow  += in ->linesize[plane];
-outrow += out->linesize[plane];
+outrow += outlinesize;
 }
 }
 
 return 0;
 }
 
+static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
+{
+FlipContext *s = ctx->priv;
+ThreadData *td = arg;
+AVFrame *in = td->in;
+AVFrame *out = td->out;
+return ff_hflip_filter_slice(s, in, out, job, nb_jobs, 0);
+}
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
 AVFilterContext *ctx  = inlink->dst;
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index dd54947bd9..8b5c8d3f50 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -39,6 +39,7 @@
 #include "internal.h"
 #include "video.h"
 #include "transpose.h"
+#include "hflip.h"
 
 typedef struct TransVtable {
 void (*transpose_8x8)(uint8_t *src, ptrdiff_t src_linesize,
@@ -48,16 +49,24 @@ typedef struct TransVtable {
 int w, int h);
 } TransVtable;
 
-typedef struct TransContext {
-const AVClass *class;
+typedef struct TransContextData {
 int hsub, vsub;
 int planes;
 int pixsteps[4];
+TransVtable vtables[4];