From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <ffmpeg-devel-bounces@ffmpeg.org>
Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100])
	by master.gitmailbox.com (Postfix) with ESMTPS id BD5A149424
	for <ffmpegdev@gitmailbox.com>; Wed, 23 Apr 2025 14:13:04 +0000 (UTC)
Received: from [127.0.1.1] (localhost [127.0.0.1])
	by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DD1EB688146;
	Wed, 23 Apr 2025 17:12:58 +0300 (EEST)
Received: from mailout2.w1.samsung.com (mailout2.w1.samsung.com
 [210.118.77.12])
 by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1FB5E687DF6
 for <ffmpeg-devel@ffmpeg.org>; Wed, 23 Apr 2025 17:12:56 +0300 (EEST)
Received: from eucas1p2.samsung.com (unknown [182.198.249.207])
 by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id
 20250423141255euoutp02bc1535b34db92126ffdc7e78f18b606c~4_AmkHrkg0570605706euoutp02W
 for <ffmpeg-devel@ffmpeg.org>; Wed, 23 Apr 2025 14:12:55 +0000 (GMT)
DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com
 20250423141255euoutp02bc1535b34db92126ffdc7e78f18b606c~4_AmkHrkg0570605706euoutp02W
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com;
 s=mail20170921; t=1745417575;
 bh=KLtIwansEEx17pLWYQ/3If+OgZizCqiEeUT3MgnFgl8=;
 h=From:To:Cc:Subject:Date:References:From;
 b=sHKqyH2FJA2UtAYJDp5K6HYWGGnuAGBKS2Q86LN8ubwcU+jW6SB7S+x3AofLraaKz
 dMJetA0C692rKDzekDqnHK1bdTEh9IYW0vg8a/TCczxaFQ2R2ZRjbtgdphtXk1URU6
 0l0w54+ryRkhAGS2XKxLOoiSQFYIingZ1qVwaF2s=
Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by
 eucas1p1.samsung.com (KnoxPortal) with ESMTP id
 20250423141255eucas1p16769b9838ba02fd3c085b6d895c59489~4_AmZBAQY2816128161eucas1p1z;
 Wed, 23 Apr 2025 14:12:55 +0000 (GMT)
Received: from eucas1p2.samsung.com ( [182.198.249.207]) by
 eusmges3new.samsung.com (EUCPMTA) with SMTP id 8F.B8.06072.765F8086; Wed, 23
 Apr 2025 15:12:55 +0100 (BST)
Received: from eusmtrp2.samsung.com (unknown [182.198.249.139]) by
 eucas1p1.samsung.com (KnoxPortal) with ESMTPA id
 20250423141255eucas1p1a1c35cdfe1d12ca5615a4f6533abb69a~4_Al1bv5R1337413374eucas1p1b;
 Wed, 23 Apr 2025 14:12:55 +0000 (GMT)
Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by
 eusmtrp2.samsung.com (KnoxPortal) with ESMTP id
 20250423141255eusmtrp283da2f88ff59b4d25657df2a4f33e9fd~4_AlyOo-70771007710eusmtrp2W;
 Wed, 23 Apr 2025 14:12:55 +0000 (GMT)
X-AuditID: cbfec7f5-7e1ff700000017b8-b7-6808f567c2df
Received: from eusmtip2.samsung.com ( [203.254.199.222]) by
 eusmgms2.samsung.com (EUCPMTA) with SMTP id 1E.E7.19654.665F8086; Wed, 23
 Apr 2025 15:12:54 +0100 (BST)
Received: from AMDC5021.local (unknown [106.120.41.33]) by
 eusmtip2.samsung.com (KnoxPortal) with ESMTPA id
 20250423141254eusmtip284aaf5340a779495ddbf92cf782d058e~4_Alh6Y0F2744927449eusmtip2M;
 Wed, 23 Apr 2025 14:12:54 +0000 (GMT)
From: Dawid Kozinski <d.kozinski@samsung.com>
To: ffmpeg-devel@ffmpeg.org
Date: Wed, 23 Apr 2025 16:12:51 +0200
Message-Id: <20250423141251.1858040-1-d.kozinski@samsung.com>
X-Mailer: git-send-email 2.34.1
MIME-Version: 1.0
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrBIsWRmVeSWpSXmKPExsWy7djP87rpXzkyDH581LBY+e03i8W3T2eY
 HZg8/izazOLRt2UVYwBTFJdNSmpOZllqkb5dAlfG0Z03mAu2TGWsWDHvJXsD44rcLkZODgkB
 E4nN3Z2sXYxcHEICKxgl9qzawAjhfGGUuHe/iwnC+cwoMWPvfCaYlttHP0FVLWeU2HVvJzOE
 84ZR4tPuI8wgVWwCuhIvPzwC6xARkJaYtHcHWJxZQFti3d3vbCC2sEC8xMZpj1hAbBYBVYlT
 x76C2bwCthJXN21lh9gmL7H/4FlmiLigxMmZT1gg5shLNG+dDbZYQuAtu8T2l09ZIBpcJI4v
 3MUGYQtLvDq+BWqQjMT/nSAvcADZxRKH+h0gzBqJQz/SISqsJd42HmcECTMLaEqs36UPEXaU
 2LT/FjNENZ/EjbeCEAfwSUzaNh0qzCvR0SYEYapI9HWKQTRKSTxdNocZwvaQWHjoLpgtJBAr
 8W7OUbYJjAqzkHw1C8lXsxBOWMDIvIpRPLW0ODc9tdg4L7Vcrzgxt7g0L10vOT93EyMwMZz+
 d/zrDsYVrz7qHWJk4mA8xCjBwawkwvvLjT1DiDclsbIqtSg/vqg0J7X4EKM0B4uSOO+i/a3p
 QgLpiSWp2ampBalFMFkmDk6pBiYZqYTgGyr+hu/WhV4UaW3Zn3E3K/77xEcieRMk+w+7vj/Z
 tmfZFG2n+14/c5cnxLzsXfci8pSTwI7/nXKfIox27eEsYDHoUHy78/DsfUXRz/YZMt0u5Mk3
 N7daMeFIc+VKJv7eQ/xyxeErV/NvnLrLc4FBUYXVN2O/2Qx9bgmfbb+tnsS96nXqZ449HWkl
 fwUmfbYzvzbpMlvxy903b3oVT2CZpxT1N+4bq2dd5cqTB6+efb9m9aHFO144WP76w/6dW6L9
 82f+uYJL1tgl5xTHf1RWdBPW4bGMnjHN5/HXypyaJ9/jDi03PGk7iSNkM++5SS+TCtnNCvec
 PV3BFbpe4luEs22B5tK8aw8u96sosRRnJBpqMRcVJwIALcXpCHsDAAA=
X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrELMWRmVeSWpSXmKPExsVy+t/xe7ppXzkyDHbdsbFY+e03i8W3T2eY
 HZg8/izazOLRt2UVYwBTlJ5NUX5pSapCRn5xia1StKGFkZ6hpYWekYmlnqGxeayVkamSvp1N
 SmpOZllqkb5dgl7G0Z03mAu2TGWsWDHvJXsD44rcLkZODgkBE4nbRz8xdjFycQgJLGWUuHfn
 GxNEQkpi6dJFjBC2sMSfa11sEEWvGCU+3N/ODpJgE9CVePnhEViDiIC0xKS9O5hBbGYBbYl1
 d7+zgdjCArESJw5eBKthEVCVOHXsKwuIzStgK3F101Z2iAXyEvsPnmWGiAtKnJz5hAVijrxE
 89bZzBMY+WYhSc1CklrAyLSKUSS1tDg3PbfYSK84Mbe4NC9dLzk/dxMjMDC3Hfu5ZQfjylcf
 9Q4xMnEwHmKU4GBWEuH95caeIcSbklhZlVqUH19UmpNafIjRFOi+icxSosn5wNjIK4k3NDMw
 NTQxszQwtTQzVhLnZbtyPk1IID2xJDU7NbUgtQimj4mDU6qBSWTHGo8fP9vXPuyMY3Ou3nJT
 +eLrbpWsi9H7OfNXfhWe/d+gea2ojUOY+gG1T79Z5fRLCjcUFT85n/iMZ+MN/sNKt1e/zL/w
 u/5aaeb3Cbdrkr6dmHX5rpm3z/mrvpuseh27jkitXxK+89iTZ/HX5D++iv1bf4v/1+aqm1+i
 f3eVyRq8OrjNaa3vF2+tb3yGDa3HS5acZtf13D9L/O6v5x2r+jxn717btPbD/nmHmPaq9imZ
 L+AXjjIIvv1zR8KcK/+vn5oqli2002hWS3HEp5iQG3WTrUoeWy77dHsz11pPuQvmDDNbj71w
 2C2nolF/7IIZi5BZtsdBh0uZ1/SbU/1XTjeVvHZjheD3INUEW0klluKMREMt5qLiRAD8PZAm
 1QIAAA==
X-CMS-MailID: 20250423141255eucas1p1a1c35cdfe1d12ca5615a4f6533abb69a
X-Msg-Generator: CA
X-RootMTR: 20250423141255eucas1p1a1c35cdfe1d12ca5615a4f6533abb69a
X-EPHeader: CA
CMS-TYPE: 201P
X-CMS-RootMailID: 20250423141255eucas1p1a1c35cdfe1d12ca5615a4f6533abb69a
References: <CGME20250423141255eucas1p1a1c35cdfe1d12ca5615a4f6533abb69a@eucas1p1.samsung.com>
Subject: [FFmpeg-devel] [PATCH v1 4/8] avformat/apv_demuxer: Added demuxer
 to handle reading APV video files
X-BeenThere: ffmpeg-devel@ffmpeg.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: FFmpeg development discussions and patches <ffmpeg-devel.ffmpeg.org>
List-Unsubscribe: <https://ffmpeg.org/mailman/options/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=unsubscribe>
List-Archive: <https://ffmpeg.org/pipermail/ffmpeg-devel>
List-Post: <mailto:ffmpeg-devel@ffmpeg.org>
List-Help: <mailto:ffmpeg-devel-request@ffmpeg.org?subject=help>
List-Subscribe: <https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=subscribe>
Reply-To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Cc: Dawid Kozinski <d.kozinski@samsung.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: ffmpeg-devel-bounces@ffmpeg.org
Sender: "ffmpeg-devel" <ffmpeg-devel-bounces@ffmpeg.org>
Archived-At: <https://master.gitmailbox.com/ffmpegdev/20250423141251.1858040-1-d.kozinski@samsung.com/>
List-Archive: <https://master.gitmailbox.com/ffmpegdev/>
List-Post: <mailto:ffmpegdev@gitmailbox.com>

- Provided AVInputFormat struct describing APV input format (ff_apv_demuxer)

Signed-off-by: Dawid Kozinski <d.kozinski@samsung.com>
---
 libavformat/Makefile     |   1 +
 libavformat/allformats.c |   1 +
 libavformat/apvdec.c     | 441 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 443 insertions(+)
 create mode 100644 libavformat/apvdec.c

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 5ccd9ebfb0..5a4ffc1568 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -120,6 +120,7 @@ OBJS-$(CONFIG_APTX_MUXER)                += rawenc.o
 OBJS-$(CONFIG_APTX_HD_DEMUXER)           += aptxdec.o
 OBJS-$(CONFIG_APTX_HD_MUXER)             += rawenc.o
 OBJS-$(CONFIG_APV_MUXER)                 += rawenc.o
+OBJS-$(CONFIG_APV_DEMUXER)               += apvdec.o rawdec.o
 OBJS-$(CONFIG_AQTITLE_DEMUXER)           += aqtitledec.o subtitles.o
 OBJS-$(CONFIG_ARGO_ASF_DEMUXER)          += argo_asf.o
 OBJS-$(CONFIG_ARGO_ASF_MUXER)            += argo_asf.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 59440f8ad5..b5a23f9c17 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -72,6 +72,7 @@ extern const FFInputFormat  ff_aptx_demuxer;
 extern const FFOutputFormat ff_aptx_muxer;
 extern const FFInputFormat  ff_aptx_hd_demuxer;
 extern const FFOutputFormat ff_aptx_hd_muxer;
+extern const FFInputFormat  ff_apv_demuxer;
 extern const FFOutputFormat ff_apv_muxer;
 extern const FFInputFormat  ff_aqtitle_demuxer;
 extern const FFInputFormat  ff_argo_asf_demuxer;
diff --git a/libavformat/apvdec.c b/libavformat/apvdec.c
new file mode 100644
index 0000000000..69b68cbe5e
--- /dev/null
+++ b/libavformat/apvdec.c
@@ -0,0 +1,441 @@
+/*
+ * RAW APV video demuxer
+ *
+ * Copyright (c) 2025 Dawid Kozinski <d.kozinski@samsung.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavcodec/get_bits.h"
+#include "libavcodec/golomb.h"
+#include "libavcodec/internal.h"
+#include "libavcodec/apv.h"
+#include "libavcodec/apv_parse.h"
+
+#include "libavutil/opt.h"
+
+#include "rawdec.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "internal.h"
+
+typedef struct APVParserContext {
+    int got_frame_data;
+
+    APVPBUHeader pbu_header;
+    APVFrameInfo frame_info;
+} APVParserContext;
+
+typedef struct APVDemuxContext {
+    const AVClass *class;
+    AVRational framerate;
+
+    APVParamSets ps;
+
+} APVDemuxContext;
+
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+#define OFFSET(x) offsetof(APVDemuxContext, x)
+static const AVOption apv_options[] = {
+    { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC},
+    { NULL },
+};
+#undef OFFSET
+
+static const AVClass apv_demuxer_class = {
+    .class_name = "APV Annex B demuxer",
+    .item_name  = av_default_item_name,
+    .option     = apv_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+// @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#section-5.3.3
+// @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-primitive-bitstream-unit-he
+static int apv_parse_pbu_header(GetBitContext *gb, APVPBUHeader *pbuh)
+{
+    pbuh->pbu_type                      = get_bits(gb, 8);
+    pbuh->group_id                      = get_bits(gb, 16);
+    pbuh->reserved_zer_8bits            = get_bits(gb, 8);
+        
+    return 0;
+}
+
+// https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-frame-information
+static int apv_parse_frame_info(GetBitContext *gb, APVFrameInfo *frame_info)
+{
+    frame_info->profile_idc                    = get_bits(gb, 8);
+    frame_info->level_idc                      = get_bits(gb, 8);
+    frame_info->band_idc                       = get_bits(gb, 3);
+    frame_info->reserved_zero_5bits            = get_bits(gb, 5);
+    frame_info->frame_width                    = get_bits(gb, 24);
+    frame_info->frame_height                   = get_bits(gb, 24);
+    frame_info->chroma_format_idc              = get_bits(gb, 4);
+    frame_info->bit_depth_minus8               = get_bits(gb, 4);
+    frame_info->capture_time_distance          = get_bits(gb, 8);
+    frame_info->reserved_zero_8bits            = get_bits(gb, 8);
+    
+    return 0;
+}
+
+// The implementation of the probe function is in accordance with the documentation provided in draft-lim-apv-04 version 04. 
+// https://www.ietf.org/archive/id/draft-lim-apv-04.html
+static int apv_annexb_probe(const AVProbeData *p)
+{
+    APVParserContext ev = {0};
+
+    GetBitContext gb;
+
+    unsigned char *bs = (unsigned char *)p->buf;
+    int bs_size = p->buf_size;
+    int ret = 0;
+    uint32_t signature;
+
+    if (bs_size < APV_PBU_SIZE_PREFIX_LENGTH + APV_AU_SIZE_PREFIX_LENGTH + APV_PBU_HEADER_SIZE)
+        return 0;
+
+    ret = init_get_bits8(&gb, bs, bs_size);
+    if (ret < 0)
+        return 0;
+
+    // skip a four-byte length Access Unit Size syntax element, which indicates the size of the AU in bytes
+    skip_bits_long(&gb, 32);
+
+    // A four-character code that identifies the bitstream as an APV AU. The value MUST be 'aPv1' (0x61507631)
+    signature = get_bits_long(&gb, 32);
+    if (signature != 0x61507631) {
+        return 0;
+    }
+
+    // skip a four-byte length PBU Size syntax element, which indicates the size of the PBU in bytes
+    skip_bits_long(&gb, 32);
+
+    apv_parse_pbu_header(&gb, &ev.pbu_header);
+    
+    if( ev.pbu_header.pbu_type == 1  ||
+        ev.pbu_header.pbu_type == 2  ||
+        ev.pbu_header.pbu_type == 25 ||
+        ev.pbu_header.pbu_type == 26 ||
+        ev.pbu_header.pbu_type == 27 ) {
+
+        apv_parse_frame_info(&gb, &ev.frame_info);
+    
+        // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-422-10-profile
+        // Conformance of a coded frame to the 422-10 profile is indicated by profile_idc equal to 33
+        if(ev.frame_info.profile_idc == 33 && 
+            ev.frame_info.chroma_format_idc == 2 &&  
+            ev.frame_info.bit_depth_minus8 == 2 && 
+            ev.pbu_header.pbu_type == 1 )
+        {
+            ev.got_frame_data = 1;
+        }
+        // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-422-12-profile
+        // Conformance of a coded frame to the 422-12 profile is indicated by profile_idc equal to 44
+        else if(ev.frame_info.profile_idc == 44 && 
+            ev.frame_info.chroma_format_idc == 2 &&  
+            ev.frame_info.bit_depth_minus8 >= 2 && ev.frame_info.bit_depth_minus8 <= 4 && 
+            ev.pbu_header.pbu_type == 1 )
+        {
+            ev.got_frame_data = 1;
+        }
+        // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-444-10-profile
+        // Conformance of a coded frame to the 444-10 profile is indicated by profile_idc equal to 55
+        else if(ev.frame_info.profile_idc == 55 && 
+            ev.frame_info.chroma_format_idc >= 2 && ev.frame_info.chroma_format_idc <= 3  &&  
+            ev.frame_info.bit_depth_minus8 == 2 && 
+            ev.pbu_header.pbu_type == 1 )
+        {
+            ev.got_frame_data = 1;
+        }
+        // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-444-12-profile
+        // Conformance of a coded frame to the 444-12 profile is indicated by profile_idc equal to 66
+        else if(ev.frame_info.profile_idc == 66 && 
+            ev.frame_info.chroma_format_idc >= 2 && ev.frame_info.chroma_format_idc <= 3  &&  
+            ev.frame_info.bit_depth_minus8 >= 2 && ev.frame_info.bit_depth_minus8 <= 4 && 
+            ev.pbu_header.pbu_type == 1 )
+        {
+            ev.got_frame_data = 1;
+        }
+        // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-4444-10-profile
+        // Conformance of a coded frame to the 4444-10 profile is indicated by profile_idc equal to 77
+        else if(ev.frame_info.profile_idc == 77 && 
+            ev.frame_info.chroma_format_idc >= 2 && ev.frame_info.chroma_format_idc <= 4  &&  
+            ev.frame_info.bit_depth_minus8 == 2  && 
+            ev.pbu_header.pbu_type == 1 )
+        {
+            ev.got_frame_data = 1;
+        }
+        // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-4444-12-profile
+        // Conformance of a coded frame to the 4444-12 profile is indicated by profile_idc equal to 88
+        else if(ev.frame_info.profile_idc == 88 && 
+            ev.frame_info.chroma_format_idc >= 2 && ev.frame_info.chroma_format_idc <= 4  &&  
+            ev.frame_info.bit_depth_minus8 >= 2 && ev.frame_info.bit_depth_minus8 <= 4 &&
+            ev.pbu_header.pbu_type == 1 )
+        {
+            ev.got_frame_data = 1;
+        }
+        // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-400-10-profile
+        // Conformance of a coded frame to the 400-10 profile is indicated by profile_idc equal to 99
+        else if(ev.frame_info.profile_idc == 99 && 
+            ev.frame_info.chroma_format_idc == 0  &&  
+            ev.frame_info.bit_depth_minus8 == 2 &&
+            ev.pbu_header.pbu_type == 1 )
+        {
+            ev.got_frame_data = 1;
+        }
+    }
+    
+    if (ev.got_frame_data && 
+        ev.pbu_header.reserved_zer_8bits == 0 && 
+        ev.frame_info.reserved_zero_5bits == 0 &&
+        ev.frame_info.reserved_zero_8bits == 0 ) {
+        return AVPROBE_SCORE_MAX;
+    }
+
+    return 0;
+}
+
+static int apv_read_header(AVFormatContext *s)
+{
+    AVStream *st;
+    FFStream *sti;
+
+    APVDemuxContext *c = s->priv_data;
+    APVFrameInfo frame_info;
+    APVPBUHeader pbu_header;
+
+    GetBitContext gb;
+    int ret;
+    uint32_t to_read = 0;
+
+    int eof = avio_feof (s->pb);
+    if(eof) {
+        return AVERROR_EOF;
+    }
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    sti = ffstream(st);
+
+    ret = init_get_bits8(&gb, s->pb->buffer, s->pb->buffer_size);
+    if (ret < 0)
+        return 0;
+
+    to_read += APV_AU_SIZE_PREFIX_LENGTH;
+    to_read += APV_SIGNATURE_LENGTH;
+    to_read += APV_PBU_SIZE_PREFIX_LENGTH;
+    to_read += APV_PBU_HEADER_SIZE;
+    to_read += APV_FRAME_INFO_SIZE;
+
+    if(s->pb->buffer_size < to_read)
+        return 0; 
+    
+    skip_bits_long(&gb, 32); // AU size
+    skip_bits_long(&gb, 32); // signature
+    skip_bits_long(&gb, 32); // PBU size
+
+    apv_parse_pbu_header(&gb, &pbu_header);
+
+    if((1  <= pbu_header.pbu_type && pbu_header.pbu_type <=2) ||
+       (25 <= pbu_header.pbu_type && pbu_header.pbu_type <= 27))    {
+        apv_parse_frame_info(&gb,  &frame_info);
+    } else if(pbu_header.pbu_type == 65) {
+        apv_parse_frame_info(&gb, &frame_info);
+    } else {
+        return 0;
+    }
+
+    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+    st->codecpar->codec_id = AV_CODEC_ID_APV;
+    st->codecpar->width = frame_info.frame_width;
+    st->codecpar->height = frame_info.frame_height;
+
+    // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-422-10-profile
+    // Conformance of a coded frame to the 422-10 profile is indicated by profile_idc equal to 33
+    if(frame_info.profile_idc == 33 && 
+       frame_info.chroma_format_idc == 2 &&  
+       frame_info.bit_depth_minus8 == 2 && 
+       pbu_header.pbu_type == 1 ) 
+    {
+        st->codecpar->format = AV_PIX_FMT_YUV422P10;
+    } 
+    // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-422-12-profile
+    // Conformance of a coded frame to the 422-12 profile is indicated by profile_idc equal to 44
+    else if(frame_info.profile_idc == 44 && 
+            frame_info.chroma_format_idc == 2 &&  
+            frame_info.bit_depth_minus8 >= 2 && frame_info.bit_depth_minus8 <= 4 && 
+            pbu_header.pbu_type == 1 )
+    {
+        if(frame_info.bit_depth_minus8 == 2) {
+            st->codecpar->format = AV_PIX_FMT_YUV422P10;
+        } else {
+            st->codecpar->format = AV_PIX_FMT_YUV422P12;
+        }
+    }
+    // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-444-10-profile
+    // Conformance of a coded frame to the 444-10 profile is indicated by profile_idc equal to 55
+    else if(frame_info.profile_idc == 55 && 
+            frame_info.chroma_format_idc >= 2 && frame_info.chroma_format_idc <= 3  &&  
+            frame_info.bit_depth_minus8 == 2 && 
+            pbu_header.pbu_type == 1 )
+    {
+        if(frame_info.chroma_format_idc == 2) {
+            st->codecpar->format = AV_PIX_FMT_YUV422P10;
+        } else {
+            st->codecpar->format = AV_PIX_FMT_YUV444P10;
+        }
+    }
+    // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-444-12-profile
+    // Conformance of a coded frame to the 444-12 profile is indicated by profile_idc equal to 66
+    else if(frame_info.profile_idc == 66 && 
+            frame_info.chroma_format_idc >= 2 && frame_info.chroma_format_idc <= 3  &&  
+            frame_info.bit_depth_minus8 >= 2 && frame_info.bit_depth_minus8 <= 4 && 
+            pbu_header.pbu_type == 1 )
+    {
+            if(frame_info.chroma_format_idc == 2) {
+                if(frame_info.bit_depth_minus8 == 2) {
+                    st->codecpar->format = AV_PIX_FMT_YUV422P10;
+                } else {
+                    st->codecpar->format = AV_PIX_FMT_YUV422P12;
+                }
+            } else {
+                if(frame_info.bit_depth_minus8 == 2) {
+                    st->codecpar->format = AV_PIX_FMT_YUV444P10;
+                } else {
+                    st->codecpar->format = AV_PIX_FMT_YUV444P12;
+                }
+            }  
+    }
+    // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-4444-10-profile
+    // Conformance of a coded frame to the 4444-10 profile is indicated by profile_idc equal to 77
+    else if(frame_info.profile_idc == 77 && 
+            frame_info.chroma_format_idc >= 2 && frame_info.chroma_format_idc <= 4  &&  
+            frame_info.bit_depth_minus8 == 2  && 
+            pbu_header.pbu_type == 1 )
+    {
+        if(frame_info.chroma_format_idc == 2) {
+            st->codecpar->format = AV_PIX_FMT_YUV422P10;
+        } else if (frame_info.chroma_format_idc == 3) {
+            st->codecpar->format = AV_PIX_FMT_YUV444P10;
+        } else {
+            st->codecpar->format = AV_PIX_FMT_YUVA444P10;
+        }
+    }
+    // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-4444-12-profile
+    // Conformance of a coded frame to the 4444-12 profile is indicated by profile_idc equal to 88
+    else if(frame_info.profile_idc == 88 && 
+        frame_info.chroma_format_idc >= 2 && frame_info.chroma_format_idc <= 4  &&  
+        frame_info.bit_depth_minus8 >= 2 && frame_info.bit_depth_minus8 <= 4 &&
+        pbu_header.pbu_type == 1 )
+    {
+        if(frame_info.chroma_format_idc == 2) {
+            if(frame_info.bit_depth_minus8 == 2) {
+                st->codecpar->format = AV_PIX_FMT_YUV422P10;
+            } else {
+                st->codecpar->format = AV_PIX_FMT_YUV422P12;
+            }
+        } else if(frame_info.chroma_format_idc == 3) {
+            if(frame_info.bit_depth_minus8 == 2) {
+                st->codecpar->format = AV_PIX_FMT_YUV444P10;
+            } else {
+                st->codecpar->format = AV_PIX_FMT_YUV444P12;
+            }
+        } else {
+            if(frame_info.bit_depth_minus8 == 2) {
+                st->codecpar->format = AV_PIX_FMT_YUVA444P10;
+            } else {
+                st->codecpar->format = AV_PIX_FMT_YUVA444P12;
+            }
+        }  
+    }
+    // @see https://www.ietf.org/archive/id/draft-lim-apv-04.html#name-400-10-profile
+    // Conformance of a coded frame to the 400-10 profile is indicated by profile_idc equal to 99
+    else if(frame_info.profile_idc == 99 && 
+            frame_info.chroma_format_idc == 0  &&  
+            frame_info.bit_depth_minus8 == 2 &&
+            pbu_header.pbu_type == 1 )
+    {
+        st->codecpar->format = AV_PIX_FMT_GRAY10;
+    } else {
+        st->codecpar->format = AV_PIX_FMT_NONE;
+    }
+
+    sti->need_parsing = PARSER_FLAG_COMPLETE_FRAMES; // AVSTREAM_PARSE_FULL_RAW;
+
+    st->avg_frame_rate = c->framerate;
+
+    avpriv_set_pts_info(st, 64, 1, 1200000);
+
+    return 0;
+}
+
+static int apv_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    int ret;
+    uint32_t au_size;
+    uint8_t buf[APV_AU_SIZE_PREFIX_LENGTH];
+
+    int eof = avio_feof (s->pb);
+    if(eof) {
+        return AVERROR_EOF;
+    }
+
+    ret = ffio_ensure_seekback(s->pb, APV_AU_SIZE_PREFIX_LENGTH);
+    if (ret < 0)
+        return ret;
+    ret = avio_read(s->pb, buf, APV_AU_SIZE_PREFIX_LENGTH);
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (ret != APV_AU_SIZE_PREFIX_LENGTH)
+        return AVERROR_INVALIDDATA;
+
+    au_size = apv_read_au_size(buf, APV_AU_SIZE_PREFIX_LENGTH, s);
+    if (!au_size || au_size > INT_MAX)
+            return AVERROR_INVALIDDATA;
+
+    avio_seek(s->pb, -APV_AU_SIZE_PREFIX_LENGTH, SEEK_CUR);
+
+    ret = av_get_packet(s->pb, pkt, au_size + APV_AU_SIZE_PREFIX_LENGTH);
+    if (ret < 0)
+        return ret;
+    
+    pkt->pos= avio_tell(s->pb);
+    pkt->stream_index = 0;
+    
+    if (ret != (au_size + APV_AU_SIZE_PREFIX_LENGTH)) {
+            return AVERROR_INVALIDDATA;
+    }
+
+    return ret;
+}
+
+const FFInputFormat ff_apv_demuxer = {
+    .p.name         = "apv",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("APV Annex B"),
+    .p.extensions   = "apv",
+    .p.flags        = AVFMT_GENERIC_INDEX | AVFMT_NOTIMESTAMPS,
+    .p.priv_class   = &apv_demuxer_class,
+    .read_probe     = apv_annexb_probe,
+    .read_header    = apv_read_header,
+    .read_packet    = apv_read_packet,
+    .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
+    .raw_codec_id   = AV_CODEC_ID_APV,
+    .priv_data_size = sizeof(APVDemuxContext),
+};
\ No newline at end of file
-- 
2.34.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".