From e93c9986027d17917c3b4f533b28ee4a2ce7cd4c Mon Sep 17 00:00:00 2001 From: James Almer Date: Wed, 8 Sep 2021 15:34:27 -0300 Subject: [PATCH] avcodec/mjpegdec: export display matrix frame side data when available Finishes fixing ticket #6945. Signed-off-by: James Almer --- libavcodec/mjpegdec.c | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 2a5868fe1d..7bec5ce221 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -30,6 +30,7 @@ * MJPEG decoder. */ +#include "libavutil/display.h" #include "libavutil/imgutils.h" #include "libavutil/avassert.h" #include "libavutil/opt.h" @@ -2406,6 +2407,7 @@ int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame) int i, index; int ret = 0; int is16bit; + AVDictionaryEntry *e = NULL; s->force_pal8 = 0; @@ -2864,6 +2866,57 @@ the_end: } } + if (e = av_dict_get(s->exif_metadata, "Orientation", e, AV_DICT_IGNORE_SUFFIX)) { + char *value = e->value + strspn(e->value, " \n\t\r"), *endptr; + int orientation = strtol(value, &endptr, 0); + + if (!*endptr) { + AVFrameSideData *sd = NULL; + + if (orientation >= 2 && orientation <= 8) { + int32_t *matrix; + + sd = av_frame_new_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX, sizeof(int32_t) * 9); + if (!sd) { + av_log(s->avctx, AV_LOG_ERROR, "Could not allocate frame side data\n"); + return AVERROR(ENOMEM); + } + + matrix = (int32_t *)sd->data; + + switch (orientation) { + case 2: + av_display_rotation_set(matrix, 0.0); + av_display_matrix_flip(matrix, 1, 0); + break; + case 3: + av_display_rotation_set(matrix, 180.0); + break; + case 4: + av_display_rotation_set(matrix, 180.0); + av_display_matrix_flip(matrix, 1, 0); + break; + case 5: + av_display_rotation_set(matrix, 90.0); + av_display_matrix_flip(matrix, 0, 1); + break; + case 6: + av_display_rotation_set(matrix, 90.0); + break; + case 7: + av_display_rotation_set(matrix, -90.0); + av_display_matrix_flip(matrix, 0, 1); + break; + case 8: + av_display_rotation_set(matrix, -90.0); + break; + default: + av_assert0(0); + } + } + } + } + av_dict_copy(&frame->metadata, s->exif_metadata, 0); av_dict_free(&s->exif_metadata);