From patchwork Wed Oct 4 04:20:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vignesh Venkat X-Patchwork-Id: 44137 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:4f21:b0:15d:8365:d4b8 with SMTP id gi33csp280799pzb; Tue, 3 Oct 2023 21:21:15 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHeDUGmeeHwxSI7kovIRYOcWflYRKoalK4z60RMBd2vkFnpMqZemy1i/x8y6HG9WtwpftQD X-Received: by 2002:a2e:b0c9:0:b0:2bd:ddf:8aa6 with SMTP id g9-20020a2eb0c9000000b002bd0ddf8aa6mr1088331ljl.23.1696393275097; Tue, 03 Oct 2023 21:21:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696393275; cv=none; d=google.com; s=arc-20160816; b=MupjVWnTG4hHKoTE9Dkh16MZRP5lo/0d+3aZicBfDPz5dm/MmbmEKC0jtB6wvZ6Xul Md8YUIJm05C1lxXJOtjLP/4Jz+0QdAtrmGcJQrSVlwIffDWBBccTVSPmuT7cOfFkMOIx bN7i0f8ek8ahQxe9I4mMybbjRoZxwGWC7BKS5fx5fDJQw5h5yzOO7h0gu3fk6uUtZ/Re DI2WGNOXbA2SAsoxQPWJzqZMrL7RJbh/HppRMEpxlOocX1gr1ewBsEeG/R/l49zxk+MT A+h/o8kbSbVs0BMb99wBKZc7qeXJalsAuV+VXD5ueKO5McNLASGAeYFocUYgNCJTEnZP GJGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to:from :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:to:message-id:references:mime-version :in-reply-to:date:delivered-to; bh=m3ZZ2sU1PSYAo/H5g/Ry/s1ZZaaEviBDmQG9RcPaRyU=; fh=zLTX2kwa8L5gNw1IDWXMzP8nX5h2CbyibdEHyEbl1/E=; b=d3+H84ULPyanintmfM8YFYNRBb0YNh/8hV9ZP1yuS/ieSdrZfnCd72mHNTJQ3UYoLr ybFDNTspAFsrIzavbzxzmCz8syQrAKna2Pdfn1ylEfAPptrjiUEkQVOOMkDi5Ae9zfqm DBIY4G5h330c86ufTLDbujTJ3km5rCh8gcffEYmSSS12bkhbUjM9P/CEIbtd5DDBIGg7 g3JqAF5Wif5JJrAycmAF4eRdag4vhZGRtpdIaYZGTJ6Fm5o0UKKF7bam8HTxVaPhuosR SGe/n0H0WJvUXIODRQpyxwqn5i3BNg0KecRIy/5MBe4aDKErOVMv3XM1kzp1VVtb1eK5 K/3A== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id kg5-20020a17090776e500b0099bc9254c6asi1306281ejc.903.2023.10.03.21.21.14; Tue, 03 Oct 2023 21:21:15 -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; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C376468CBDD; Wed, 4 Oct 2023 07:21:12 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AC52068CB25 for ; Wed, 4 Oct 2023 07:21:05 +0300 (EEST) Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-59f8188b718so25844587b3.1 for ; Tue, 03 Oct 2023 21:21:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696393264; x=1696998064; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ikXeMLE2/qV2vLtoXxhxjCj1p1usRoisDVE5387PPU0=; b=AzNd5M3KvkUnCtqIep25d2Esht9lmzmvCuPx7ka0oUlCtaC9vO/xrxegj6sYTxo0Pp uAmnxsWKBF+sxft/m42SctxWkFp2BCluFV4HA/LRHZ1i2ki+KhiF1ZRX0J/sZnXI5wDv V6fmn8tNe9dHX73iHUgjz+YQQC+wOocLsvncd/IIL6D58nSyEWdph73VoaQbj9KHERur s0qNyOU+sKDxiNWt7DDwMt5StyE5lkpJL5zWZbAFaoGHvQHnufDQz79hqJ7fSEQGJW1+ ewwQ2FNFqnwgPmf3TTOCddKpygOf4Iqd/FGqmki39TSvsUx9LDqS5S8vOvJYFEfEuDUw 7ywA== X-Gm-Message-State: AOJu0Yy2fATF6l/6e4NADEG8d4ysIltG7YEhPO15ImOTsSc9uO3j68ES BDH/lKrm9SzqOkUmz8BNGVxIJy+GUzjE5MpOBwO/jvusToyF5nn0TswNAE09g4JNaOgFyUYBxXD PaQ1UWc0z15GySPdn2VxKHQMIXb3L81QFODdNkKnRB0Rr4WcUy2UL9qZ5dlAMfERL6H3J X-Received: from vigneshv3.mtv.corp.google.com ([2620:0:1000:2511:e58:8b17:6065:ec86]) (user=vigneshv job=sendgmr) by 2002:a81:ac25:0:b0:59b:ee27:bbe9 with SMTP id k37-20020a81ac25000000b0059bee27bbe9mr22404ywh.9.1696393264113; Tue, 03 Oct 2023 21:21:04 -0700 (PDT) Date: Tue, 3 Oct 2023 21:20:46 -0700 In-Reply-To: Mime-Version: 1.0 References: X-Mailer: git-send-email 2.42.0.582.g8ccd20d70d-goog Message-ID: <20231004042054.1030417-1-vigneshv@google.com> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH v2] avformat/mov: Add support for demuxing still HEIC images 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: , X-Patchwork-Original-From: Vignesh Venkatasubramanian via ffmpeg-devel From: Vignesh Venkat Reply-To: FFmpeg development discussions and patches Cc: Vignesh Venkatasubramanian Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: aOoJY1gmRxcC They are similar to AVIF images (both use the HEIF container). The only additional work needed is to parse the hvcC box and put it in the extradata. With this patch applied, ffmpeg (when built with an HEVC decoder) is able to decode the files in https://github.com/nokiatech/heif/tree/gh-pages/content/images Partially fixes trac ticket #6521. Signed-off-by: Vignesh Venkatasubramanian --- libavformat/isom.h | 2 ++ libavformat/mov.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 3d375d7a46..b30b9da65e 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -327,6 +327,8 @@ typedef struct MOVContext { int64_t extent_offset; } *avif_info; int avif_info_size; + int64_t hvcC_offset; + int hvcC_size; int interleaved_read; } MOVContext; diff --git a/libavformat/mov.c b/libavformat/mov.c index 1996e0028c..8ee93f321e 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1218,7 +1218,8 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) c->isom = 1; av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type); av_dict_set(&c->fc->metadata, "major_brand", type, 0); - c->is_still_picture_avif = !strncmp(type, "avif", 4); + c->is_still_picture_avif = !strncmp(type, "avif", 4) || + !strncmp(type, "mif1", 4); minor_ver = avio_rb32(pb); /* minor version */ av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0); @@ -4911,6 +4912,19 @@ static int avif_add_stream(MOVContext *c, int item_id) st->priv_data = sc; st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = AV_CODEC_ID_AV1; + if (c->hvcC_offset >= 0) { + int ret; + int64_t pos = avio_tell(c->fc->pb); + st->codecpar->codec_id = AV_CODEC_ID_HEVC; + if (avio_seek(c->fc->pb, c->hvcC_offset, SEEK_SET) != c->hvcC_offset) { + av_log(c->fc, AV_LOG_ERROR, "Failed to seek to hvcC data.\n"); + return AVERROR_UNKNOWN; + } + ret = ff_get_extradata(c->fc, st->codecpar, c->fc->pb, c->hvcC_size); + if (ret < 0) + return ret; + avio_seek(c->fc->pb, pos, SEEK_SET); + } sc->ffindex = st->index; c->trak_index = st->index; st->avg_frame_rate.num = st->avg_frame_rate.den = 1; @@ -4953,6 +4967,8 @@ static int avif_add_stream(MOVContext *c, int item_id) static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom) { + c->hvcC_offset = -1; + c->hvcC_size = 0; while (atom.size > 8) { uint32_t tag; if (avio_feof(pb)) @@ -7826,6 +7842,28 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom) return atom.size; } +static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + int size = avio_rb32(pb); + if (avio_rl32(pb) != MKTAG('i','p','c','o')) + return AVERROR_INVALIDDATA; + size -= 8; + while (size > 0) { + int sub_size, sub_type; + sub_size = avio_rb32(pb); + sub_type = avio_rl32(pb); + sub_size -= 8; + size -= sub_size + 8; + if (sub_type == MKTAG('h','v','c','C')) { + c->hvcC_offset = avio_tell(pb); + c->hvcC_size = sub_size; + break; + } + avio_skip(pb, sub_size); + } + return atom.size; +} + static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('A','C','L','R'), mov_read_aclr }, { MKTAG('A','P','R','G'), mov_read_avid }, @@ -7933,6 +7971,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */ { MKTAG('p','i','t','m'), mov_read_pitm }, { MKTAG('e','v','c','C'), mov_read_glbl }, +{ MKTAG('i','p','r','p'), mov_read_iprp }, { 0, NULL } };