Re: [FFmpeg-devel] [PATCH v3 2/2] fftools/ffmpeg: add exif orientation support per frame's metadata

2019-05-28 Thread Jun Li
On Tue, May 28, 2019 at 1:50 PM Michael Niedermayer 
wrote:

> On Mon, May 27, 2019 at 11:18:26PM -0700, Jun Li wrote:
> > Fix #6945
> > Rotate or/and flip frame according to frame's metadata orientation
> > ---
> >  fftools/ffmpeg.c| 16 +++-
> >  fftools/ffmpeg.h|  3 ++-
> >  fftools/ffmpeg_filter.c | 28 +++-
> >  3 files changed, 40 insertions(+), 7 deletions(-)
> >
> > diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> > index 01f04103cf..2f4229a9d0 100644
> > --- a/fftools/ffmpeg.c
> > +++ b/fftools/ffmpeg.c
> > @@ -2126,6 +2126,19 @@ static int
> ifilter_has_all_input_formats(FilterGraph *fg)
> >  return 1;
> >  }
> >
> > +static int orientation_need_update(InputFilter *ifilter, AVFrame *frame)
> > +{
> > +int orientaion = get_frame_orientation(frame);
> > +int filterst = ifilter->orientation <= 1 ? 0 : // not set
> > +   ifilter->orientation <= 4 ? 1 : // auto flip
> > +   2; // auto transpose
> > +int framest = orientaion <= 1 ? 0 : // not set
> > +  orientaion <= 4 ? 1 : // auto flip
> > +  2; // auto transpose
> > +
> > +return filterst != framest;
> > +}
> > +
> >  static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
> >  {
> >  FilterGraph *fg = ifilter->graph;
> > @@ -2142,7 +2155,8 @@ static int ifilter_send_frame(InputFilter
> *ifilter, AVFrame *frame)
> >  break;
> >  case AVMEDIA_TYPE_VIDEO:
> >  need_reinit |= ifilter->width  != frame->width ||
> > -   ifilter->height != frame->height;
> > +   ifilter->height != frame->height ||
> > +   orientation_need_update(ifilter, frame);
> >  break;
> >  }
> >
> > diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
> > index eb1eaf6363..54532ef0eb 100644
> > --- a/fftools/ffmpeg.h
> > +++ b/fftools/ffmpeg.h
> > @@ -244,7 +244,7 @@ typedef struct InputFilter {
> >  // parameters configured for this input
> >  int format;
> >
> > -int width, height;
> > +int width, height, orientation;
> >  AVRational sample_aspect_ratio;
> >
> >  int sample_rate;
> > @@ -649,6 +649,7 @@ int init_complex_filtergraph(FilterGraph *fg);
> >  void sub2video_update(InputStream *ist, AVSubtitle *sub);
> >
> >  int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame
> *frame);
> > +int get_frame_orientation(const AVFrame* frame);
> >
> >  int ffmpeg_parse_options(int argc, char **argv);
> >
> > diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
> > index 72838de1e2..ff63540906 100644
> > --- a/fftools/ffmpeg_filter.c
> > +++ b/fftools/ffmpeg_filter.c
> > @@ -743,6 +743,18 @@ static int sub2video_prepare(InputStream *ist,
> InputFilter *ifilter)
> >  return 0;
> >  }
> >
> > +int get_frame_orientation(const AVFrame *frame)
> > +{
> > +AVDictionaryEntry *entry = NULL;
> > +int orientation = 0;
> > +
> > +// read exif orientation data
> > +entry = av_dict_get(frame->metadata, "Orientation", NULL, 0);
>
> > +if (entry)
> > +orientation = atoi(entry->value);
>
> this probably should be checking the validity of the string unless
> it has been checked already elsewhere


Thanks Michael for the catch. I updated to version 5:
https://patchwork.ffmpeg.org/patch/13321/
https://patchwork.ffmpeg.org/patch/13322/

Best Regards,
Jun


> thx
>
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> I have never wished to cater to the crowd; for what I know they do not
> approve, and what they approve I do not know. -- Epicurus
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v3 2/2] fftools/ffmpeg: add exif orientation support per frame's metadata

2019-05-28 Thread Michael Niedermayer
On Mon, May 27, 2019 at 11:18:26PM -0700, Jun Li wrote:
> Fix #6945
> Rotate or/and flip frame according to frame's metadata orientation
> ---
>  fftools/ffmpeg.c| 16 +++-
>  fftools/ffmpeg.h|  3 ++-
>  fftools/ffmpeg_filter.c | 28 +++-
>  3 files changed, 40 insertions(+), 7 deletions(-)
> 
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index 01f04103cf..2f4229a9d0 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -2126,6 +2126,19 @@ static int ifilter_has_all_input_formats(FilterGraph 
> *fg)
>  return 1;
>  }
>  
> +static int orientation_need_update(InputFilter *ifilter, AVFrame *frame)
> +{
> +int orientaion = get_frame_orientation(frame);
> +int filterst = ifilter->orientation <= 1 ? 0 : // not set
> +   ifilter->orientation <= 4 ? 1 : // auto flip
> +   2; // auto transpose
> +int framest = orientaion <= 1 ? 0 : // not set
> +  orientaion <= 4 ? 1 : // auto flip
> +  2; // auto transpose
> +
> +return filterst != framest;
> +}
> +
>  static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
>  {
>  FilterGraph *fg = ifilter->graph;
> @@ -2142,7 +2155,8 @@ static int ifilter_send_frame(InputFilter *ifilter, 
> AVFrame *frame)
>  break;
>  case AVMEDIA_TYPE_VIDEO:
>  need_reinit |= ifilter->width  != frame->width ||
> -   ifilter->height != frame->height;
> +   ifilter->height != frame->height ||
> +   orientation_need_update(ifilter, frame);
>  break;
>  }
>  
> diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
> index eb1eaf6363..54532ef0eb 100644
> --- a/fftools/ffmpeg.h
> +++ b/fftools/ffmpeg.h
> @@ -244,7 +244,7 @@ typedef struct InputFilter {
>  // parameters configured for this input
>  int format;
>  
> -int width, height;
> +int width, height, orientation;
>  AVRational sample_aspect_ratio;
>  
>  int sample_rate;
> @@ -649,6 +649,7 @@ int init_complex_filtergraph(FilterGraph *fg);
>  void sub2video_update(InputStream *ist, AVSubtitle *sub);
>  
>  int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame 
> *frame);
> +int get_frame_orientation(const AVFrame* frame);
>  
>  int ffmpeg_parse_options(int argc, char **argv);
>  
> diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
> index 72838de1e2..ff63540906 100644
> --- a/fftools/ffmpeg_filter.c
> +++ b/fftools/ffmpeg_filter.c
> @@ -743,6 +743,18 @@ static int sub2video_prepare(InputStream *ist, 
> InputFilter *ifilter)
>  return 0;
>  }
>  
> +int get_frame_orientation(const AVFrame *frame)
> +{
> +AVDictionaryEntry *entry = NULL;
> +int orientation = 0;
> +
> +// read exif orientation data
> +entry = av_dict_get(frame->metadata, "Orientation", NULL, 0);

> +if (entry)
> +orientation = atoi(entry->value);

this probably should be checking the validity of the string unless
it has been checked already elsewhere

thx

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I have never wished to cater to the crowd; for what I know they do not
approve, and what they approve I do not know. -- Epicurus


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v3 2/2] fftools/ffmpeg: add exif orientation support per frame's metadata

2019-05-28 Thread Paul B Mahol
On 5/28/19, Jun Li  wrote:
> Fix #6945
> Rotate or/and flip frame according to frame's metadata orientation
> ---
>  fftools/ffmpeg.c| 16 +++-
>  fftools/ffmpeg.h|  3 ++-
>  fftools/ffmpeg_filter.c | 28 +++-
>  3 files changed, 40 insertions(+), 7 deletions(-)
>
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index 01f04103cf..2f4229a9d0 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -2126,6 +2126,19 @@ static int ifilter_has_all_input_formats(FilterGraph
> *fg)
>  return 1;
>  }
>
> +static int orientation_need_update(InputFilter *ifilter, AVFrame *frame)
> +{
> +int orientaion = get_frame_orientation(frame);
> +int filterst = ifilter->orientation <= 1 ? 0 : // not set
> +   ifilter->orientation <= 4 ? 1 : // auto flip
> +   2; // auto transpose
> +int framest = orientaion <= 1 ? 0 : // not set
> +  orientaion <= 4 ? 1 : // auto flip
> +  2; // auto transpose
> +
> +return filterst != framest;
> +}
> +
>  static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
>  {
>  FilterGraph *fg = ifilter->graph;
> @@ -2142,7 +2155,8 @@ static int ifilter_send_frame(InputFilter *ifilter,
> AVFrame *frame)
>  break;
>  case AVMEDIA_TYPE_VIDEO:
>  need_reinit |= ifilter->width  != frame->width ||
> -   ifilter->height != frame->height;
> +   ifilter->height != frame->height ||
> +   orientation_need_update(ifilter, frame);
>  break;
>  }
>
> diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
> index eb1eaf6363..54532ef0eb 100644
> --- a/fftools/ffmpeg.h
> +++ b/fftools/ffmpeg.h
> @@ -244,7 +244,7 @@ typedef struct InputFilter {
>  // parameters configured for this input
>  int format;
>
> -int width, height;
> +int width, height, orientation;
>  AVRational sample_aspect_ratio;
>
>  int sample_rate;
> @@ -649,6 +649,7 @@ int init_complex_filtergraph(FilterGraph *fg);
>  void sub2video_update(InputStream *ist, AVSubtitle *sub);
>
>  int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame
> *frame);
> +int get_frame_orientation(const AVFrame* frame);
>
>  int ffmpeg_parse_options(int argc, char **argv);
>
> diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
> index 72838de1e2..ff63540906 100644
> --- a/fftools/ffmpeg_filter.c
> +++ b/fftools/ffmpeg_filter.c
> @@ -743,6 +743,18 @@ static int sub2video_prepare(InputStream *ist,
> InputFilter *ifilter)
>  return 0;
>  }
>
> +int get_frame_orientation(const AVFrame *frame)
> +{
> +AVDictionaryEntry *entry = NULL;
> +int orientation = 0;
> +
> +// read exif orientation data
> +entry = av_dict_get(frame->metadata, "Orientation", NULL, 0);
> +if (entry)
> +orientation = atoi(entry->value);
> +return orientation;
> +}
> +
>  static int configure_input_video_filter(FilterGraph *fg, InputFilter
> *ifilter,
>  AVFilterInOut *in)
>  {
> @@ -809,13 +821,18 @@ static int configure_input_video_filter(FilterGraph
> *fg, InputFilter *ifilter,
>  if (ist->autorotate) {
>  double theta = get_rotation(ist->st);
>
> -if (fabs(theta - 90) < 1.0) {
> +if (fabs(theta) < 1.0) { // no rotation info in stream meta
> +if (ifilter->orientation < 0 || ifilter->orientation > 8) {
> +av_log(NULL, AV_LOG_ERROR, "Invalid frame orientation:
> %i\n", ifilter->orientation);
> +} else if (ifilter->orientation > 1 && ifilter->orientation <=
> 4) { // skip 0 (not set) and 1 (orientaion 'Normal')
> +ret = insert_filter(_filter, _idx, "transpose",
> "orientation=-1");
> +} else if (ifilter->orientation > 4) {
> +ret = insert_filter(_filter, _idx, "transpose",
> "orientation=-2");

Usning non-named option values is bad and not user-friendly.

> +}
> +} else if (fabs(theta - 90) < 1.0) {
>  ret = insert_filter(_filter, _idx, "transpose",
> "clock");
>  } else if (fabs(theta - 180) < 1.0) {
> -ret = insert_filter(_filter, _idx, "hflip", NULL);
> -if (ret < 0)
> -return ret;
> -ret = insert_filter(_filter, _idx, "vflip", NULL);
> +ret = insert_filter(_filter, _idx, "transpose",
> "orientation=3");

ditto

>  } else if (fabs(theta - 270) < 1.0) {
>  ret = insert_filter(_filter, _idx, "transpose",
> "cclock");
>  } else if (fabs(theta) > 1.0) {
> @@ -1191,6 +1208,7 @@ int ifilter_parameters_from_frame(InputFilter
> *ifilter, const AVFrame *frame)
>  ifilter->width   = frame->width;
>  ifilter->height  = frame->height;
>  ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
> +ifilter->orientation = get_frame_orientation(frame);
>
>  

[FFmpeg-devel] [PATCH v3 2/2] fftools/ffmpeg: add exif orientation support per frame's metadata

2019-05-28 Thread Jun Li
Fix #6945
Rotate or/and flip frame according to frame's metadata orientation
---
 fftools/ffmpeg.c| 16 +++-
 fftools/ffmpeg.h|  3 ++-
 fftools/ffmpeg_filter.c | 28 +++-
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..2f4229a9d0 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2126,6 +2126,19 @@ static int ifilter_has_all_input_formats(FilterGraph *fg)
 return 1;
 }
 
+static int orientation_need_update(InputFilter *ifilter, AVFrame *frame)
+{
+int orientaion = get_frame_orientation(frame);
+int filterst = ifilter->orientation <= 1 ? 0 : // not set
+   ifilter->orientation <= 4 ? 1 : // auto flip
+   2; // auto transpose
+int framest = orientaion <= 1 ? 0 : // not set
+  orientaion <= 4 ? 1 : // auto flip
+  2; // auto transpose
+
+return filterst != framest;
+}
+
 static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame)
 {
 FilterGraph *fg = ifilter->graph;
@@ -2142,7 +2155,8 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
 break;
 case AVMEDIA_TYPE_VIDEO:
 need_reinit |= ifilter->width  != frame->width ||
-   ifilter->height != frame->height;
+   ifilter->height != frame->height ||
+   orientation_need_update(ifilter, frame);
 break;
 }
 
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index eb1eaf6363..54532ef0eb 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -244,7 +244,7 @@ typedef struct InputFilter {
 // parameters configured for this input
 int format;
 
-int width, height;
+int width, height, orientation;
 AVRational sample_aspect_ratio;
 
 int sample_rate;
@@ -649,6 +649,7 @@ int init_complex_filtergraph(FilterGraph *fg);
 void sub2video_update(InputStream *ist, AVSubtitle *sub);
 
 int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
+int get_frame_orientation(const AVFrame* frame);
 
 int ffmpeg_parse_options(int argc, char **argv);
 
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de1e2..ff63540906 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -743,6 +743,18 @@ static int sub2video_prepare(InputStream *ist, InputFilter 
*ifilter)
 return 0;
 }
 
+int get_frame_orientation(const AVFrame *frame)
+{
+AVDictionaryEntry *entry = NULL;
+int orientation = 0;
+
+// read exif orientation data
+entry = av_dict_get(frame->metadata, "Orientation", NULL, 0);
+if (entry)
+orientation = atoi(entry->value);
+return orientation;
+}
+
 static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
 AVFilterInOut *in)
 {
@@ -809,13 +821,18 @@ static int configure_input_video_filter(FilterGraph *fg, 
InputFilter *ifilter,
 if (ist->autorotate) {
 double theta = get_rotation(ist->st);
 
-if (fabs(theta - 90) < 1.0) {
+if (fabs(theta) < 1.0) { // no rotation info in stream meta
+if (ifilter->orientation < 0 || ifilter->orientation > 8) {
+av_log(NULL, AV_LOG_ERROR, "Invalid frame orientation: %i\n", 
ifilter->orientation);
+} else if (ifilter->orientation > 1 && ifilter->orientation <= 4) 
{ // skip 0 (not set) and 1 (orientaion 'Normal') 
+ret = insert_filter(_filter, _idx, "transpose", 
"orientation=-1");
+} else if (ifilter->orientation > 4) {
+ret = insert_filter(_filter, _idx, "transpose", 
"orientation=-2");
+}
+} else if (fabs(theta - 90) < 1.0) {
 ret = insert_filter(_filter, _idx, "transpose", "clock");
 } else if (fabs(theta - 180) < 1.0) {
-ret = insert_filter(_filter, _idx, "hflip", NULL);
-if (ret < 0)
-return ret;
-ret = insert_filter(_filter, _idx, "vflip", NULL);
+ret = insert_filter(_filter, _idx, "transpose", 
"orientation=3");
 } else if (fabs(theta - 270) < 1.0) {
 ret = insert_filter(_filter, _idx, "transpose", "cclock");
 } else if (fabs(theta) > 1.0) {
@@ -1191,6 +1208,7 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, 
const AVFrame *frame)
 ifilter->width   = frame->width;
 ifilter->height  = frame->height;
 ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
+ifilter->orientation = get_frame_orientation(frame);
 
 ifilter->sample_rate = frame->sample_rate;
 ifilter->channels= frame->channels;
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email