Message ID | 20190515053645.21432-1-junli1026@gmail.com |
---|---|
State | Superseded |
Headers | show |
On Tue, May 14, 2019 at 10:36:44PM -0700, Jun Li wrote: > Add av_display_rotation_hflip_get to get information whether the > matrix indicates horizontal flip. > --- > doc/APIchanges | 3 +++ > libavutil/display.c | 14 ++++++++++++++ > libavutil/display.h | 14 ++++++++++++++ > libavutil/tests/display.c | 8 ++++++++ > libavutil/version.h | 2 +- > tests/ref/fate/display | 4 ++++ > 6 files changed, 44 insertions(+), 1 deletion(-) > > diff --git a/doc/APIchanges b/doc/APIchanges > index e75c4044ce..73c6809563 100644 > --- a/doc/APIchanges > +++ b/doc/APIchanges > @@ -15,6 +15,9 @@ libavutil: 2017-10-21 > > API changes, most recent first: > > +2019-05-13 - XXXXXXXXXX - lavu 56.28.100 - display.h > + Add av_display_rotation_hflip_get > + > 2019-04-20 - 3153a6502a - lavc 58.52.100 - avcodec.h > Add AV_CODEC_FLAG_DROPCHANGED to allow avcodec_receive_frame to drop > frames whose parameters differ from first decoded frame in stream. > diff --git a/libavutil/display.c b/libavutil/display.c > index a0076e067b..f5a6a4a08d 100644 > --- a/libavutil/display.c > +++ b/libavutil/display.c > @@ -71,3 +71,17 @@ void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip) > for (i = 0; i < 9; i++) > matrix[i] *= flip[i % 3]; > } > + > +double av_display_rotation_hflip_get(const int32_t matrix[9], int *hflip) > +{ > + int32_t m[9]; > + *hflip = 0; > + memcpy(m, matrix, sizeof(m)); > + > + if (m[0] > 0 && m[4] < 0 || m[0] < 0 && m[4] > 0 || > + m[1] > 0 && m[3] > 0 || m[1] < 0 && m[3] < 0) { > + *hflip = 1; > + av_display_matrix_flip(m, 1, 0); > + } This is not correct consider the identity transform matrix 1 0 0 1 now if the 0 elements are only so slightly off 0 this could set hflip, this does not make the matrix flip anything, its still basically a identity matrix. What you want to detect here, i _think_, is the direction in which the matrix rotates the vector. Not sure what the technical term is but the "z" sign of the cross product of the 2 basis vectors should be that if iam not mistaken. I think that results in something like m[0]*m[4] < m[1]*m[3] but ive not checked this so please check before using it thx [...]
On Wed, May 15, 2019 at 3:22 PM Michael Niedermayer <michael@niedermayer.cc> wrote: > On Tue, May 14, 2019 at 10:36:44PM -0700, Jun Li wrote: > > Add av_display_rotation_hflip_get to get information whether the > > matrix indicates horizontal flip. > > --- > > doc/APIchanges | 3 +++ > > libavutil/display.c | 14 ++++++++++++++ > > libavutil/display.h | 14 ++++++++++++++ > > libavutil/tests/display.c | 8 ++++++++ > > libavutil/version.h | 2 +- > > tests/ref/fate/display | 4 ++++ > > 6 files changed, 44 insertions(+), 1 deletion(-) > > > > diff --git a/doc/APIchanges b/doc/APIchanges > > index e75c4044ce..73c6809563 100644 > > --- a/doc/APIchanges > > +++ b/doc/APIchanges > > @@ -15,6 +15,9 @@ libavutil: 2017-10-21 > > > > API changes, most recent first: > > > > +2019-05-13 - XXXXXXXXXX - lavu 56.28.100 - display.h > > + Add av_display_rotation_hflip_get > > + > > 2019-04-20 - 3153a6502a - lavc 58.52.100 - avcodec.h > > Add AV_CODEC_FLAG_DROPCHANGED to allow avcodec_receive_frame to drop > > frames whose parameters differ from first decoded frame in stream. > > diff --git a/libavutil/display.c b/libavutil/display.c > > index a0076e067b..f5a6a4a08d 100644 > > --- a/libavutil/display.c > > +++ b/libavutil/display.c > > @@ -71,3 +71,17 @@ void av_display_matrix_flip(int32_t matrix[9], int > hflip, int vflip) > > for (i = 0; i < 9; i++) > > matrix[i] *= flip[i % 3]; > > } > > + > > +double av_display_rotation_hflip_get(const int32_t matrix[9], int > *hflip) > > +{ > > + int32_t m[9]; > > + *hflip = 0; > > + memcpy(m, matrix, sizeof(m)); > > + > > > + if (m[0] > 0 && m[4] < 0 || m[0] < 0 && m[4] > 0 || > > + m[1] > 0 && m[3] > 0 || m[1] < 0 && m[3] < 0) { > > + *hflip = 1; > > + av_display_matrix_flip(m, 1, 0); > > + } > > This is not correct > consider the identity transform matrix > 1 0 > 0 1 > > now if the 0 elements are only so slightly off 0 this could set hflip, this > does not make the matrix flip anything, its still basically a identity > matrix. > > What you want to detect here, i _think_, is the direction in which the > matrix > rotates the vector. Not sure what the technical term is but the "z" sign of > the cross product of the 2 basis vectors should be that if iam not > mistaken. > > I think that results in something like m[0]*m[4] < m[1]*m[3] but ive not > checked this so please check before using it > Thanks Michael for review, it is very helpful. Yes, using cross product should be the right way. Negative value of m[0]*m[4] - m[1]*m[3] indicates flipped (the vector points into the screen). I tested on the content you shared, "47j9R7PXBep.mov" and "bug.jpg", also on some exif jpg images from the link in the tickets. All works well. Let me know if you have any more content need me to test. I have the updated version: https://patchwork.ffmpeg.org/patch/13130/ https://patchwork.ffmpeg.org/patch/13131/ Thanks! Best Regards, Jun > thx > > [...] > > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Those who would give up essential Liberty, to purchase a little > temporary Safety, deserve neither Liberty nor Safety -- Benjamin Franklin > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff --git a/doc/APIchanges b/doc/APIchanges index e75c4044ce..73c6809563 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2017-10-21 API changes, most recent first: +2019-05-13 - XXXXXXXXXX - lavu 56.28.100 - display.h + Add av_display_rotation_hflip_get + 2019-04-20 - 3153a6502a - lavc 58.52.100 - avcodec.h Add AV_CODEC_FLAG_DROPCHANGED to allow avcodec_receive_frame to drop frames whose parameters differ from first decoded frame in stream. diff --git a/libavutil/display.c b/libavutil/display.c index a0076e067b..f5a6a4a08d 100644 --- a/libavutil/display.c +++ b/libavutil/display.c @@ -71,3 +71,17 @@ void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip) for (i = 0; i < 9; i++) matrix[i] *= flip[i % 3]; } + +double av_display_rotation_hflip_get(const int32_t matrix[9], int *hflip) +{ + int32_t m[9]; + *hflip = 0; + memcpy(m, matrix, sizeof(m)); + + if (m[0] > 0 && m[4] < 0 || m[0] < 0 && m[4] > 0 || + m[1] > 0 && m[3] > 0 || m[1] < 0 && m[3] < 0) { + *hflip = 1; + av_display_matrix_flip(m, 1, 0); + } + return av_display_rotation_get(m); +} diff --git a/libavutil/display.h b/libavutil/display.h index 515adad795..c37d10c741 100644 --- a/libavutil/display.h +++ b/libavutil/display.h @@ -106,6 +106,20 @@ void av_display_rotation_set(int32_t matrix[9], double angle); */ void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip); +/** + * Extract the rotation component and hflip status of the transformation matrix. + * + * @param matrix the transformation matrix + * @param hflip will be set to 1 if the matrix indicates horizontal flip + * @return the angle (in degrees) by which the transformation rotates the frame + * counterclockwise. The angle will be in range [-180.0, 180.0], + * or NaN if the matrix is singular. + * + * @note floating point numbers are inherently inexact, so callers are + * recommended to round the return value to nearest integer before use. + */ +double av_display_rotation_hflip_get(const int32_t matrix[9], int* hflip); + /** * @} * @} diff --git a/libavutil/tests/display.c b/libavutil/tests/display.c index 893ebb5543..65a0971e7b 100644 --- a/libavutil/tests/display.c +++ b/libavutil/tests/display.c @@ -35,6 +35,8 @@ static void print_matrix(int32_t matrix[9]) int main(void) { int32_t matrix[9]; + int hflip = 0; + double degree; // Set the matrix to 90 degrees av_display_rotation_set(matrix, 90); @@ -56,6 +58,12 @@ int main(void) print_matrix(matrix); printf("degrees: %f\n", av_display_rotation_get(matrix)); + // flip vertical + av_display_matrix_flip(matrix, 0, 1); + print_matrix(matrix); + degree = av_display_rotation_hflip_get(matrix, &hflip); + printf("degrees: %f, hflip: %i\n", degree, hflip); + return 0; } diff --git a/libavutil/version.h b/libavutil/version.h index 12b4f9fc3a..91ab71604b 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 27 +#define LIBAVUTIL_VERSION_MINOR 28 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/tests/ref/fate/display b/tests/ref/fate/display index 251e7e0cdf..14b4c7db7c 100644 --- a/tests/ref/fate/display +++ b/tests/ref/fate/display @@ -14,3 +14,7 @@ degrees: 135.000000 -46340 -46340 0 0 0 1073741824 degrees: -135.000000 +-46340 -46340 0 +-46340 46340 0 +0 0 1073741824 +degrees: 45.000000, hflip: 1