History

avformat/mov: get heif image rotation from irot box

Based on a patch by Hacene Bouaroua. Fixes ticket #11171.

James Almer committed 2 years ago

Commit 76eb3e51 parent 50d1b892 files · +68 −0Browse files

Unified · Split

2 files
  1. libavformat/isom.h +1 −0
  2. libavformat/mov.c +67 −0
libavformat/isom.h+1−0
@@ -283,6 +283,7 @@ typedef struct HEIFItem { · 282 unmodified lines
283 int64_t extent_offset;283 int64_t extent_offset;
284 int width;284 int width;
285 int height;285 int height;
286 int rotation;
286 int type;287 int type;
287 int is_idat_relative;288 int is_idat_relative;
288} HEIFItem;289} HEIFItem;
libavformat/mov.c+67−0
@@ -40,6 +40,7 @@ · 39 unmodified lines
40#include "libavutil/avassert.h"40#include "libavutil/avassert.h"
41#include "libavutil/avstring.h"41#include "libavutil/avstring.h"
42#include "libavutil/dict.h"42#include "libavutil/dict.h"
43#include "libavutil/display.h"
43#include "libavutil/mem.h"44#include "libavutil/mem.h"
44#include "libavutil/opt.h"45#include "libavutil/opt.h"
45#include "libavutil/aes.h"46#include "libavutil/aes.h"
@@ -8933,6 +8934,27 @@ static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom) · 8887 unmodified lines
8933 return 0;8934 return 0;
8934}8935}
8935 8936
8937static int mov_read_irot(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8938{
8939 int angle;
8940
8941 angle = avio_r8(pb) & 0x3;
8942
8943 av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
8944 c->cur_item_id, angle);
8945
8946 for (int i = 0; i < c->nb_heif_item; i++) {
8947 if (c->heif_item[i].item_id == c->cur_item_id) {
8948 // angle * 90 specifies the angle (in anti-clockwise direction)
8949 // in units of degrees.
8950 c->heif_item[i].rotation = angle * 90;
8951 break;
8952 }
8953 }
8954
8955 return 0;
8956}
8957
8936static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)8958static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
8937{8959{
8938 typedef struct MOVAtoms {8960 typedef struct MOVAtoms {
@@ -9159,6 +9181,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { · 220 unmodified lines
9159{ MKTAG('i','d','a','t'), mov_read_idat },9181{ MKTAG('i','d','a','t'), mov_read_idat },
9160{ MKTAG('i','r','e','f'), mov_read_iref },9182{ MKTAG('i','r','e','f'), mov_read_iref },
9161{ MKTAG('i','s','p','e'), mov_read_ispe },9183{ MKTAG('i','s','p','e'), mov_read_ispe },
9184{ MKTAG('i','r','o','t'), mov_read_irot },
9162{ MKTAG('i','p','r','p'), mov_read_iprp },9185{ MKTAG('i','p','r','p'), mov_read_iprp },
9163{ MKTAG('i','i','n','f'), mov_read_iinf },9186{ MKTAG('i','i','n','f'), mov_read_iinf },
9164{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */9187{ MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */
@@ -9828,6 +9851,26 @@ fail: · 663 unmodified lines
9828 return ret;9851 return ret;
9829}9852}
9830 9853
9854static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data,
9855 const HEIFItem *item)
9856{
9857 int32_t *matrix;
9858 AVPacketSideData *sd = av_packet_side_data_new(coded_side_data,
9859 nb_coded_side_data,
9860 AV_PKT_DATA_DISPLAYMATRIX,
9861 9 * sizeof(*matrix), 0);
9862 if (!sd)
9863 return AVERROR(ENOMEM);
9864
9865 matrix = (int32_t*)sd->data;
9866 /* rotation is in the counter-clockwise direction whereas
9867 * av_display_rotation_set() expects its argument to be
9868 * oriented clockwise, so we need to negate it. */
9869 av_display_rotation_set(matrix, -item->rotation);
9870
9871 return 0;
9872}
9873
9831static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,9874static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
9832 AVStreamGroupTileGrid *tile_grid)9875 AVStreamGroupTileGrid *tile_grid)
9833{9876{
@@ -9861,6 +9904,14 @@ static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, · 27 unmodified lines
9861 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);9904 tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9862 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);9905 tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9863 9906
9907 /* rotation */
9908 if (item->rotation) {
9909 int ret = set_display_matrix_from_item(&tile_grid->coded_side_data,
9910 &tile_grid->nb_coded_side_data, item);
9911 if (ret < 0)
9912 return ret;
9913 }
9914
9864 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",9915 av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n",
9865 tile_rows, tile_cols, tile_grid->width, tile_grid->height);9916 tile_rows, tile_cols, tile_grid->width, tile_grid->height);
9866 9917
@@ -9951,6 +10002,15 @@ static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, · 84 unmodified lines
9951 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);10002 tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
9952 tile_grid->height =10003 tile_grid->height =
9953 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);10004 tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
10005
10006 /* rotation */
10007 if (item->rotation) {
10008 int ret = set_display_matrix_from_item(&tile_grid->coded_side_data,
10009 &tile_grid->nb_coded_side_data, item);
10010 if (ret < 0)
10011 return ret;
10012 }
10013
9954 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",10014 av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n",
9955 tile_grid->width, tile_grid->height);10015 tile_grid->width, tile_grid->height);
9956 10016
@@ -10153,6 +10213,13 @@ static int mov_read_header(AVFormatContext *s) · 196 unmodified lines
10153 if (item->item_id == mov->primary_item_id)10213 if (item->item_id == mov->primary_item_id)
10154 st->disposition |= AV_DISPOSITION_DEFAULT;10214 st->disposition |= AV_DISPOSITION_DEFAULT;
10155 10215
10216 if (item->rotation) {
10217 int ret = set_display_matrix_from_item(&st->codecpar->coded_side_data,
10218 &st->codecpar->nb_coded_side_data, item);
10219 if (ret < 0)
10220 return ret;
10221 }
10222
10156 mov_build_index(mov, st);10223 mov_build_index(mov, st);
10157 }10224 }
10158 10225

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t