From patchwork Wed Sep 25 00:14:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 51815 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:9548:0:b0:48e:c0f8:d0de with SMTP id t8csp236578vqk; Tue, 24 Sep 2024 22:24:22 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXgVeLWtwggio8aVUXmf7vecH7KRHpOOWmOFApAhwgN6CP6+4BWKwmsnxiLgW/xnp7Z7LGjFvWTR/PI+GmBg0gx@gmail.com X-Google-Smtp-Source: AGHT+IGfb/kgFm4V9PSNKLrCEikzm/xS1hS2hv8ieZL39TPZ5mUVPh5OBdlpiec9jyaexM3kWpok X-Received: by 2002:a05:6512:ba8:b0:535:4144:d785 with SMTP id 2adb3069b0e04-538804acd28mr188904e87.11.1727241862053; Tue, 24 Sep 2024 22:24:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727241862; cv=none; d=google.com; s=arc-20240605; b=Ioh3LUbgdEUidUaEn3EZodHnunZxTlsxPBg2Zz6fFmPkthSxzv/KBReIFFOnq7kWPC MLtev0ufvQs5PTYGqXxIlHXNfEBfsngF2auVCP0Jp63Du0DwkQ8gYU1ANvg/vi+2H1Fd Mh1CDPrJJ34hFt2p9XdWKKYVL82+pCCwlpMdq7d274N1zSJnI92rub1Sj+3XIMn+Zofx gF9Xv3Q8K3wjNx6LssLZqisNWX8VGKjHskqxWOoi2oAshfG0pOEh2myT2OCfXA9Wq4EE NlcLonHbHOLGYuubTtG2lFEalbFI9lWDT9P7CthCjEbSBHZxHyXlZ2oRVUBKPPdlZGwM 43tQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=oWf82mV2Uif7SPR5t4ZFVw4x0VTS+gQGDLfq9hrxRE8=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=bBEkzuvpFgNBma3spUM2XD9FrPONGekb7i7edLG84QfOLYD1bny9fYI2wL5yMOp2JQ TeBn7AgSXbIK6ClX+T5nJqWCP6To1/bIq5bExImvrpdA0aBXV3x1Vkicp22pKb0Rf8RY HV3SVfn4A98Ev4qhcgg8Pqo1AyCGT+LcB1pSY1z06wHRH/G5doEG7kBURWuGXG0NeF2y NBytPPXE9g5HwGpK/WDkMR+xgEt/EuIyys3jtMQ+Es8alF3tyqPHMe81Kp6suhAVxGMv eJuifqphsj2ndIAsz2tcX39pyA+19QK6c2w6S6DWf/Mgl9QxlnKoohikwcuZy1Lbe25c 9A5w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=hD+ny3Aa; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 2adb3069b0e04-537a864cdc2si902460e87.542.2024.09.24.22.24.21; Tue, 24 Sep 2024 22:24:22 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=hD+ny3Aa; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C78DC68DB16; Wed, 25 Sep 2024 03:14:31 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-vs1-f48.google.com (mail-vs1-f48.google.com [209.85.217.48]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F3B1D68D97E for ; Wed, 25 Sep 2024 03:14:24 +0300 (EEST) Received: by mail-vs1-f48.google.com with SMTP id ada2fe7eead31-49bd250b0f2so261803137.0 for ; Tue, 24 Sep 2024 17:14:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727223263; x=1727828063; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=Mud+EN0B6GBhNyzTqBI4piWt56ffPfv0zREAdEgIrjc=; b=hD+ny3AayZWz1EhvgeRXEn4tOShZfmbsrD++DAvHHSIbXSYLaMIExgmSAMV/B33p/7 j5owp0E2nHpjdLK6ME2FReJVREpfTv0vElhCh9B8A1HtGCrRZJZAzQfb6E2lld8NMy0O yba1RFEgFeybP+V0Xt1+to0exCVcseQBDFcNTvRjmxdb+WCBJiRpfRcRds6uaRQYO2S+ pSHVh2C/keXFbnqvNGTiqKtK6XjcX+nolbS4E3bpCpP7kt3j0r03siN0D5oL3KeiqH0l Z8xPYO21PAV3c/stX6O8lJMZlpd1fglzsGD6Mp/PjDYVWk6YgepV6we8sjW6y7ymBJ44 sUpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727223263; x=1727828063; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Mud+EN0B6GBhNyzTqBI4piWt56ffPfv0zREAdEgIrjc=; b=EkFD39vhgx2UuG5GIVd7dyL/yWPXqPOmeXQhUJNUxXCaQuVGPudNqme52XmXkYR9OS WlIjw0wvbn7j7um1pq8cXkezp7ghwV5qV9/SqEu3Di6Xw3O5sgVO2Zm4BZ2KDXyW62vs harypoN93gfLRNJCk82rJfvqHfvv5IQ6vHoegbrGLvyNpZ0XsHHhK+xmGGDQRCJjKOXr KTB3iokzAucs7+2/LVKGcJZd1BCHdbNN5Zj3rIUpR79697OPgqVvpUpcJIJKX47tWQzA AdeyDUr949tWNvtZl0iiZcO1jMZc+e4uV1I0SpwXDLTPoqO/xcPtC9USblwxmCVh5NCj 79kg== X-Gm-Message-State: AOJu0YwSmm+hjsRMsOJMPoknu2x5cjtWC7X3+860Ezz7BKV9Cs7f3Wne PlNRI77fVvZH/QL5vF9rttuurtBYCLyxwPJ2suy40f8gh6W9/ILL2zzlFQ== X-Received: by 2002:a05:6102:374b:b0:49b:d489:d467 with SMTP id ada2fe7eead31-4a14e98e84cmr4064309137.8.1727223262597; Tue, 24 Sep 2024 17:14:22 -0700 (PDT) Received: from localhost.localdomain ([181.92.233.116]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-84e73b7539asm1174504241.18.2024.09.24.17.14.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Sep 2024 17:14:21 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Tue, 24 Sep 2024 21:14:46 -0300 Message-ID: <20240925001446.1905-1-jamrial@gmail.com> X-Mailer: git-send-email 2.46.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avformat/mov: get heif image rotation from irot box X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: ZC0WboDsYfxU Based on a patch by Hacene Bouaroua. Co-authored-by: Hacene Bouaroua Signed-off-by: James Almer --- 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; } 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); }