Message ID | 20240925001446.1905-1-jamrial@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel] avformat/mov: get heif image rotation from irot box | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
On 9/24/2024 9:14 PM, James Almer wrote: > Based on a patch by Hacene Bouaroua. > > Co-authored-by: Hacene Bouaroua <hbouaroua@freebox.fr> > Signed-off-by: James Almer <jamrial@gmail.com> > --- > libavformat/avformat.h | 6 +++++ > libavformat/isom.h | 1 + > libavformat/mov.c | 54 ++++++++++++++++++++++++++++++++++++++---- > 3 files changed, 57 insertions(+), 4 deletions(-) Will apply (with version bump and APIChanges entry) soon.
Quoting James Almer (2024-09-25 02:14:46) > Based on a patch by Hacene Bouaroua. > > Co-authored-by: Hacene Bouaroua <hbouaroua@freebox.fr> > Signed-off-by: James Almer <jamrial@gmail.com> > --- > libavformat/avformat.h | 6 +++++ > libavformat/isom.h | 1 + > libavformat/mov.c | 54 ++++++++++++++++++++++++++++++++++++++---- > 3 files changed, 57 insertions(+), 4 deletions(-) > > diff --git a/libavformat/avformat.h b/libavformat/avformat.h > index 56c1c80289..a54aac0f3a 100644 > --- a/libavformat/avformat.h > +++ b/libavformat/avformat.h > @@ -1082,6 +1082,12 @@ typedef struct AVStreamGroupTileGrid { > * final image before presentation. > */ > int height; > + > + /** > + * The angle in which the reconstructed image is rotated (in anti-clockwise > + * direction) before presentation, in units of degrees. > + */ > + AVRational rotation; Should it not be a display matrix rather than just an angle?
On 9/27/2024 1:43 PM, Anton Khirnov wrote: > Quoting James Almer (2024-09-25 02:14:46) >> Based on a patch by Hacene Bouaroua. >> >> Co-authored-by: Hacene Bouaroua <hbouaroua@freebox.fr> >> Signed-off-by: James Almer <jamrial@gmail.com> >> --- >> libavformat/avformat.h | 6 +++++ >> libavformat/isom.h | 1 + >> libavformat/mov.c | 54 ++++++++++++++++++++++++++++++++++++++---- >> 3 files changed, 57 insertions(+), 4 deletions(-) >> >> diff --git a/libavformat/avformat.h b/libavformat/avformat.h >> index 56c1c80289..a54aac0f3a 100644 >> --- a/libavformat/avformat.h >> +++ b/libavformat/avformat.h >> @@ -1082,6 +1082,12 @@ typedef struct AVStreamGroupTileGrid { >> * final image before presentation. >> */ >> int height; >> + >> + /** >> + * The angle in which the reconstructed image is rotated (in anti-clockwise >> + * direction) before presentation, in units of degrees. >> + */ >> + AVRational rotation; > > Should it not be a display matrix rather than just an angle? What's the benefit? There's av_display_rotation_set() for that.
Quoting James Almer (2024-09-27 19:07:42) > On 9/27/2024 1:43 PM, Anton Khirnov wrote: > > Quoting James Almer (2024-09-25 02:14:46) > >> Based on a patch by Hacene Bouaroua. > >> > >> Co-authored-by: Hacene Bouaroua <hbouaroua@freebox.fr> > >> Signed-off-by: James Almer <jamrial@gmail.com> > >> --- > >> libavformat/avformat.h | 6 +++++ > >> libavformat/isom.h | 1 + > >> libavformat/mov.c | 54 ++++++++++++++++++++++++++++++++++++++---- > >> 3 files changed, 57 insertions(+), 4 deletions(-) > >> > >> diff --git a/libavformat/avformat.h b/libavformat/avformat.h > >> index 56c1c80289..a54aac0f3a 100644 > >> --- a/libavformat/avformat.h > >> +++ b/libavformat/avformat.h > >> @@ -1082,6 +1082,12 @@ typedef struct AVStreamGroupTileGrid { > >> * final image before presentation. > >> */ > >> int height; > >> + > >> + /** > >> + * The angle in which the reconstructed image is rotated (in anti-clockwise > >> + * direction) before presentation, in units of degrees. > >> + */ > >> + AVRational rotation; > > > > Should it not be a display matrix rather than just an angle? > > What's the benefit? A consistent interface.
diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 56c1c80289..a54aac0f3a 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1082,6 +1082,12 @@ typedef struct AVStreamGroupTileGrid { * final image before presentation. */ int height; + + /** + * The angle in which the reconstructed image is rotated (in anti-clockwise + * direction) before presentation, in units of degrees. + */ + AVRational rotation; } AVStreamGroupTileGrid; /** diff --git a/libavformat/isom.h b/libavformat/isom.h index 4723397048..204addbab2 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -283,6 +283,7 @@ typedef struct HEIFItem { int64_t extent_offset; int width; int height; + int rotation; int type; int is_idat_relative; } HEIFItem; diff --git a/libavformat/mov.c b/libavformat/mov.c index a2333ac1fd..480e6c81a5 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -40,6 +40,7 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/dict.h" +#include "libavutil/display.h" #include "libavutil/mem.h" #include "libavutil/opt.h" #include "libavutil/aes.h" @@ -8929,6 +8930,27 @@ static int mov_read_ispe(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_irot(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + int angle; + + angle = avio_r8(pb) & 0x3; + + av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n", + c->cur_item_id, angle); + + for (int i = 0; i < c->nb_heif_item; i++) { + if (c->heif_item[i].item_id == c->cur_item_id) { + // angle * 90 specifies the angle (in anti-clockwise direction) + // in units of degrees. + c->heif_item[i].rotation = angle * 90; + break; + } + } + + return 0; +} + static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom) { typedef struct MOVAtoms { @@ -9155,6 +9177,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('i','d','a','t'), mov_read_idat }, { MKTAG('i','r','e','f'), mov_read_iref }, { MKTAG('i','s','p','e'), mov_read_ispe }, +{ MKTAG('i','r','o','t'), mov_read_irot }, { MKTAG('i','p','r','p'), mov_read_iprp }, { MKTAG('i','i','n','f'), mov_read_iinf }, { MKTAG('a','m','v','e'), mov_read_amve }, /* ambient viewing environment box */ @@ -9857,8 +9880,12 @@ static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, tile_grid->width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb); tile_grid->height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb); - av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d\n", - tile_rows, tile_cols, tile_grid->width, tile_grid->height); + /* rotation */ + tile_grid->rotation = av_make_q(item->rotation, 1); + + av_log(c->fc, AV_LOG_TRACE, "grid: grid_rows %d grid_cols %d output_width %d output_height %d " + "rotation %f\n", + tile_rows, tile_cols, tile_grid->width, tile_grid->height, av_q2d(tile_grid->rotation)); avio_seek(s->pb, pos, SEEK_SET); @@ -9947,8 +9974,12 @@ static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, tile_grid->coded_width = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb); tile_grid->height = tile_grid->coded_height = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb); - av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d\n", - tile_grid->width, tile_grid->height); + + /* rotation */ + tile_grid->rotation = av_make_q(item->rotation, 1); + + av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d, rotation %f\n", + tile_grid->width, tile_grid->height, av_q2d(tile_grid->rotation)); tile_grid->nb_tiles = grid->nb_tiles; tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets)); @@ -10149,6 +10180,21 @@ static int mov_read_header(AVFormatContext *s) if (item->item_id == mov->primary_item_id) st->disposition |= AV_DISPOSITION_DEFAULT; + if (item->rotation) { + int32_t *matrix; + AVPacketSideData *sd = av_packet_side_data_new(&st->codecpar->coded_side_data, + &st->codecpar->nb_coded_side_data, + AV_PKT_DATA_DISPLAYMATRIX, + 9 * sizeof(*matrix), 0); + if (!sd) + return AVERROR(ENOMEM); + matrix = (int32_t*)sd->data; + + /* rotation is in the counter-clockwise direction whereas + * av_display_rotation_set() expects its argument to be + * oriented clockwise, so we need to negate it. */ + av_display_rotation_set(matrix, -item->rotation); + } mov_build_index(mov, st); }
Based on a patch by Hacene Bouaroua. Co-authored-by: Hacene Bouaroua <hbouaroua@freebox.fr> Signed-off-by: James Almer <jamrial@gmail.com> --- libavformat/avformat.h | 6 +++++ libavformat/isom.h | 1 + libavformat/mov.c | 54 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 57 insertions(+), 4 deletions(-)