From patchwork Fri Sep 27 18:38:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 51917 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:d8ca:0:b0:48e:c0f8:d0de with SMTP id dy10csp1076857vqb; Sat, 28 Sep 2024 09:56:14 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVWDTmclMnW9P3jZT0tFpNTHWrkqjAlkY4j2/LSg3Kq3+504k2ba1/XNUkfPD6rg4grZZExVHn+ub/S3g6sHOcl@gmail.com X-Google-Smtp-Source: AGHT+IHB26k8cIVyngBcDjvt0tStUrpEADkvaydbW9BmQWyEeubP0nDC2c5g9VKfXsEHnSBws49b X-Received: by 2002:a17:907:982:b0:a90:17fc:3f60 with SMTP id a640c23a62f3a-a93c49668bemr354319866b.8.1727542574171; Sat, 28 Sep 2024 09:56:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727542574; cv=none; d=google.com; s=arc-20240605; b=dmzSXVbShSffXsAIekuZlA7Q+Z+7LsUeUJKx+xl6iYiF87sqWPIbdo1Bu3l7hIsD8p oarBGJCympwTCPCQsZFM+RMm84whtZ5yvX+e2FwNc6BaRNx9eQ9w2jYLO4Us85fEeaGq 2UqK4ZdDmtMMeedlC2dycxg86NH79IceM3zh+UIxKO3N8YN8R7MYXicgL7tWkZagX99R OLI8PQZPS4PInZoTHD8F8n/ebV1GsO0HhaYf1ZkrMH1R/FF9Hy1lWhNHwUTe6uqQmUEU 0F/aK6BlbLJDNuWvLBpP24mH3Y0tjyHkssU1n8VRMNt5f02FM2UHg/PjByf4LQod4Oah grWA== 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:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=uJfCiqfLNbxc/2KxWD4aJOCvAvPewXVD2NRaE3YkEGs=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=HLwdtiacHECi56b6VYbJI98VGhhqwXH9nlqqtliSA5+OJ9saaqo5CJg4FwrGqFJmoh 7zqo8oCmiEyQBCUPYzEaekGUvBeKN0TDBttnFOracqykUBK/QRl1rvIYxF98YqV42OA0 8IL13lwsBQ5m7oj6lq/zPaWMq4oIs7pFZ6GxrSCcFuLHX6xwgcokoam/1hERJZT5ZLvs XPpnZNwV1fBxLw3wxWN2DHBKdsm4HOnMmnPu/wmPbW3Q+PtCR/Wko+66hN4TTR1om8qN T0mls3I2w6tGKoYozrdJZ4N9d8DRZtuidv6u5XVU3MG2MfyYkTRKsJbvLeaKqNMQNrkF VPXw==; 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=ZE7O13If; 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 a640c23a62f3a-a93c2aade64si348677866b.1018.2024.09.28.09.56.13; Sat, 28 Sep 2024 09:56:14 -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=ZE7O13If; 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 E2C2468DDF4; Fri, 27 Sep 2024 21:37:49 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.178]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 84B7C68DDF7 for ; Fri, 27 Sep 2024 21:37:42 +0300 (EEST) Received: by mail-pf1-f178.google.com with SMTP id d2e1a72fcca58-71781f42f75so2221909b3a.1 for ; Fri, 27 Sep 2024 11:37:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727462260; x=1728067060; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=TEyhFfSDvlF5iUIAiZvOlQEemdNcVxR24mR3dIHVyr0=; b=ZE7O13If8vImyHvy6g1S3hrtZJ24loJ4NO8MEK+bq+cPCkMVlchmOoiaU4EDI9Pry4 LiABoz6HVRFz4zz3CR1LYzeaBkWX9TLKXwHbbdbXWJmXvDHiZIx7M+3DQigGubLdq8VM yEnJiN1pZEz56GBQ/Liiij1l19OS7lVnPOOZCSQ85Edhoaux/dYlK5cO4f4M2cgTfHzM 3Bqgv1j0onvrJJ8jPw4gUS9LCDqlUJSHyTzBDuQ/CciaphVmrkGP3wKyBBk9+o3s/FpK A+sN7DLFwicYcDUr8XPuS5ta4K1bTPdZj57vjERsEJOMMf+AXF7Ax0a8/OlXes5vz8FL qn7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727462260; x=1728067060; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TEyhFfSDvlF5iUIAiZvOlQEemdNcVxR24mR3dIHVyr0=; b=N4OROs9lcDT6t0PJ/K36g2XXlFJY9d+4wuyhDXnfDSQqNAU+ZzmmHnMrfFI8IJ0wIK Du5Op9mOEc3qumnW5QLdXDLZQRFNujBVaFOKEtvlnUeP2A9QlI3MpxnvpyAWI6pI6qid vuVIquIiY+soqkDoqr9nuHk3WdC/mRj6tazYrl4TN3f5o4De5bhzNoSW/vrNS8EaKj3T 8aehCcTsZhi7H71KP8uC2Mj91cEEYzG0Wx4K315AV+Oel6W6pmb4eMRYNZYyECVposBh z/ur740qKQ2/tYmPwNqs6dTNR5jwtHzfMG61Jp0Fc+vdx50z2CLl4kZhdspaVyDGp4Px /9xw== X-Gm-Message-State: AOJu0Yw7Fk3DKBh9AOLcQl9BlXkwsxvAvL6sLtfUcfnSsQ6PTnCpgKck kaq0n2DmiAoYllx++ovaHfVxPPX0gvYuENfwfbeGEmVtARvi5QBkeiVdeg== X-Received: by 2002:a05:6a00:1956:b0:710:591e:b52f with SMTP id d2e1a72fcca58-71b25f01b93mr6580006b3a.5.1727462259786; Fri, 27 Sep 2024 11:37:39 -0700 (PDT) Received: from localhost.localdomain ([181.92.233.116]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71b264b7dd6sm1925639b3a.46.2024.09.27.11.37.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Sep 2024 11:37:39 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Sep 2024 15:38:09 -0300 Message-ID: <20240927183809.4150-2-jamrial@gmail.com> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20240927183809.4150-1-jamrial@gmail.com> References: <20240927183809.4150-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] 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: mOBJy9c/YYhx Based on a patch by Hacene Bouaroua. Co-authored-by: Hacene Bouaroua Signed-off-by: James Almer --- libavformat/isom.h | 1 + libavformat/mov.c | 75 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 4 deletions(-) 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..fc43d7c826 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 */ @@ -9824,6 +9847,26 @@ fail: return ret; } +static int set_display_matrix_from_item(AVPacketSideData **coded_side_data, int *nb_coded_side_data, + const HEIFItem *item) +{ + int32_t *matrix; + AVPacketSideData *sd = av_packet_side_data_new(coded_side_data, + 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); + + return 0; +} + static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, AVStreamGroupTileGrid *tile_grid) { @@ -9857,8 +9900,17 @@ 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 */ + if (item->rotation) { + int ret = set_display_matrix_from_item(&tile_grid->coded_side_data, + &tile_grid->nb_coded_side_data, item); + if (ret < 0) + return ret; + } + + 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, (double)item->rotation); avio_seek(s->pb, pos, SEEK_SET); @@ -9947,8 +9999,16 @@ 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); + + if (item->rotation) { + int ret = set_display_matrix_from_item(&tile_grid->coded_side_data, + &tile_grid->nb_coded_side_data, item); + if (ret < 0) + return ret; + } + + av_log(c->fc, AV_LOG_TRACE, "iovl: output_width %d, output_height %d, rotation %f\n", + tile_grid->width, tile_grid->height, (double)item->rotation); tile_grid->nb_tiles = grid->nb_tiles; tile_grid->offsets = av_malloc_array(tile_grid->nb_tiles, sizeof(*tile_grid->offsets)); @@ -10149,6 +10209,13 @@ static int mov_read_header(AVFormatContext *s) if (item->item_id == mov->primary_item_id) st->disposition |= AV_DISPOSITION_DEFAULT; + if (item->rotation) { + int ret = set_display_matrix_from_item(&st->codecpar->coded_side_data, + &st->codecpar->nb_coded_side_data, item); + if (ret < 0) + return ret; + } + mov_build_index(mov, st); }