From patchwork Tue Nov 23 18:42:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pierre-Anthony Lemieux X-Patchwork-Id: 31609 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:d206:0:0:0:0:0 with SMTP id q6csp9094137iob; Tue, 23 Nov 2021 10:43:07 -0800 (PST) X-Google-Smtp-Source: ABdhPJwY7nztwCmOKRk0BfpR/xwH3j3BI6B2eWjPnDKljTpkfln/pAqPlii0a4fZQafb6wrk9DC3 X-Received: by 2002:aa7:cf9a:: with SMTP id z26mr12822819edx.136.1637692987719; Tue, 23 Nov 2021 10:43:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1637692987; cv=none; d=google.com; s=arc-20160816; b=H2xn3Gdq7Kef+Nuh/XLV40Fl71kKwimVhAKdE3Zy18aszkeWm8fwqqos+pL7TLw6fw vbj1H2JQEPvcf1qoqM9FyB2tlu42paGPpS3D+tdqxGAILKRfuqcSz863bXlwlTnLhGDP KqFsw6ce9EpAt5Fx3+PqP6x7yEelFnmmOupvrihpPpY2Kb8P5GM8oYJJtf0BzEWsLJ52 /w0bI833UTi+UNoPErAb+3KUCbJkSlBlp69Z2K5l+hXecbJSvNJDrOky0DWJz/1NrYqA WdYM+mu2Ox9V8MsE60uFJK1Xc4KTJIDhi1bwf98bEm91hAmOXWPCvxRE+9DROa5oslkZ LYyQ== 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 :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:delivered-to; bh=Z/6yHS/6s/7BO0eOn3skg601PCeDloUDYXCwokCh8Zc=; b=k4i/tkc9a3Rz3KGl8XfIN08iiY1+857m6g568ZdFQdpW+vD9WVHJjo68nL/prnnmM4 hZxbUktcvTeq0bwg59F6sUD3yoMUlBbQJ5rniCcXNbEomxB49ikuvvAnHvhAK8fkubMe NqpjG24El1lvDnOOCvdsybquz1tmBN0cQ5EpJ06H/B2N1w7cT5m/wXG/2bbmscg2Fz/G 7CDyu+NNBUjxg45xJFUHURyhlI+G5fT6z6gIqTdMxHrr4QM4Au0Zb2YcLldCIrdRA3EV 6IGHZVBH/2TXISqE78zN62eeTSu6nEiyg+heaRgj/BqFdCrYnG08i7PsG5UQFrqXlBW6 VUAA== 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 he37si38088365ejc.123.2021.11.23.10.43.06; Tue, 23 Nov 2021 10:43:07 -0800 (PST) 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 D2BD568AF3A; Tue, 23 Nov 2021 20:42:38 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B9C9E68AEE5 for ; Tue, 23 Nov 2021 20:42:32 +0200 (EET) Received: by mail-pj1-f53.google.com with SMTP id iq11so171496pjb.3 for ; Tue, 23 Nov 2021 10:42:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ShUsF+3I4TgFJaUTLq3DoStgzDVhnCIhbsPCFizYrzU=; b=nvgp1io//9EXZ10PEnrdK4JHMnf9LzrNGtsw3RxQ3k/eRTuAPQzNzPzluGlxAPNnTP OAMjHLr0kV9OkY7StWrJBEuugCIxkiNKc0ai/jaNjdqinRc3FcM7oZVPx8TvFyQo0OsH Lj802X3hJe5cg0aUwYm+D853hN1gM1M3oLZK4ViAthxompagbXpcdH2xqiQs+092tn43 hefvm4mrMdjs1JkoFcOXUI1NBaIPbfKEf7WIdZ5nQcCcw+d15aT58Zv2dFNGKWOPz93O Z72YeCdMsszhBZXJdBrkbKP/JwiPsCfzT5muimnPOJhSbnRHoAUy5ekkVwcU8UUq9gAy +aPQ== X-Gm-Message-State: AOAM530Y7mN5AWzNkFjwOVgjAxVz7DoG2Ira8o4dvKs80HpY6rn6wFHO NSzwVf94W8+nSFXA8bIcTBQv30YwU04= X-Received: by 2002:a17:90a:df8d:: with SMTP id p13mr5559071pjv.197.1637692950472; Tue, 23 Nov 2021 10:42:30 -0800 (PST) Received: from localhost (76-14-89-2.sf-cable.astound.net. [76.14.89.2]) by smtp.gmail.com with ESMTPSA id i10sm1858222pjd.3.2021.11.23.10.42.28 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 23 Nov 2021 10:42:29 -0800 (PST) Received: by localhost (sSMTP sendmail emulation); Tue, 23 Nov 2021 10:42:25 -0800 From: pal@sandflow.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 23 Nov 2021 10:42:11 -0800 Message-Id: <20211123184211.24479-4-pal@sandflow.com> X-Mailer: git-send-email 2.34.0.windows.1 In-Reply-To: <20211123184211.24479-1-pal@sandflow.com> References: <20211123184211.24479-1-pal@sandflow.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v5 4/4] avformat/imf: Tests and build files 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 Cc: Pierre-Anthony Lemieux Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: qtOimiR3LqmA From: Pierre-Anthony Lemieux Signed-off-by: Pierre-Anthony Lemieux --- Notes: Tests and build files for the IMF demuxer. MAINTAINERS | 1 + configure | 3 +- doc/demuxers.texi | 6 + libavformat/Makefile | 2 + libavformat/allformats.c | 1 + libavformat/tests/imf.c | 498 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 510 insertions(+), 1 deletion(-) create mode 100644 libavformat/tests/imf.c diff --git a/MAINTAINERS b/MAINTAINERS index dcac46003e..7a6972fe1a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -433,6 +433,7 @@ Muxers/Demuxers: idroqdec.c Mike Melanson iff.c Jaikrishnan Menon img2*.c Michael Niedermayer + imf*.c Marc-Antoine Arnaud, Pierre-Anthony Lemieux, Valentin Noël ipmovie.c Mike Melanson ircam* Paul B Mahol iss.c Stefan Gehrer diff --git a/configure b/configure index d068b11073..ee39528835 100755 --- a/configure +++ b/configure @@ -298,7 +298,7 @@ External library support: --enable-libxvid enable Xvid encoding via xvidcore, native MPEG-4/Xvid encoder exists [no] --enable-libxml2 enable XML parsing using the C library libxml2, needed - for dash demuxing support [no] + for dash and imf demuxing support [no] --enable-libzimg enable z.lib, needed for zscale filter [no] --enable-libzmq enable message passing via libzmq [no] --enable-libzvbi enable teletext support via libzvbi [no] @@ -3377,6 +3377,7 @@ hls_muxer_select="mpegts_muxer" hls_muxer_suggest="gcrypt openssl" image2_alias_pix_demuxer_select="image2_demuxer" image2_brender_pix_demuxer_select="image2_demuxer" +imf_demuxer_deps="libxml2" ipod_muxer_select="mov_muxer" ismv_muxer_select="mov_muxer" ivf_muxer_select="av1_metadata_bsf vp9_superframe_bsf" diff --git a/doc/demuxers.texi b/doc/demuxers.texi index cab8a7072c..655704d2c4 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -267,6 +267,12 @@ which streams to actually receive. Each stream mirrors the @code{id} and @code{bandwidth} properties from the @code{} as metadata keys named "id" and "variant_bitrate" respectively. +@section imf + +Interoperable Master Format demuxer. + +This demuxer presents audio and video streams found in an IMF Composition. + @section flv, live_flv, kux Adobe Flash Video Format demuxer. diff --git a/libavformat/Makefile b/libavformat/Makefile index 3d6c8ef8f5..dda2bc9a47 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -285,6 +285,7 @@ OBJS-$(CONFIG_IMAGE_WEBP_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_XBM_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_XPM_PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE_XWD_PIPE_DEMUXER) += img2dec.o img2.o +OBJS-$(CONFIG_IMF_DEMUXER) += imfdec.o imf_cpl.o OBJS-$(CONFIG_INGENIENT_DEMUXER) += ingenientdec.o rawdec.o OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o OBJS-$(CONFIG_IPU_DEMUXER) += ipudec.o rawdec.o @@ -694,6 +695,7 @@ TESTPROGS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh TESTPROGS-$(CONFIG_MOV_MUXER) += movenc TESTPROGS-$(CONFIG_NETWORK) += noproxy TESTPROGS-$(CONFIG_SRTP) += srtp +TESTPROGS-$(CONFIG_IMF_DEMUXER) += imf TOOLS = aviocat \ ismindex \ diff --git a/libavformat/allformats.c b/libavformat/allformats.c index cbfadcb639..91cd9a4c73 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -212,6 +212,7 @@ extern const AVInputFormat ff_image2pipe_demuxer; extern const AVOutputFormat ff_image2pipe_muxer; extern const AVInputFormat ff_image2_alias_pix_demuxer; extern const AVInputFormat ff_image2_brender_pix_demuxer; +extern const AVInputFormat ff_imf_demuxer; extern const AVInputFormat ff_ingenient_demuxer; extern const AVInputFormat ff_ipmovie_demuxer; extern const AVOutputFormat ff_ipod_muxer; diff --git a/libavformat/tests/imf.c b/libavformat/tests/imf.c new file mode 100644 index 0000000000..51bbbc579d --- /dev/null +++ b/libavformat/tests/imf.c @@ -0,0 +1,498 @@ +/* + * Copyright (c) Sandflow Consulting LLC + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * 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 + */ + +/** + * Tests for IMF CPL and ASSETMAP processing + * + * @author Valentin Noel + * @author Pierre-Anthony Lemieux + * @file + * @ingroup lavu_imf + */ + +#include "libavformat/imf_cpl.c" +#include "libavformat/imfdec.c" +#include "libavformat/mxf.h" + +#include + +const char *cpl_doc = + "" + "urn:uuid:8713c020-2489-45f5-a9f7-87be539e20b5" + "2021-07-13T17:06:22Z" + "FFMPEG" + "FFMPEG sample content" + "" + " " + " urn:uuid:8e097bb0-cff7-4969-a692-bad47bfb528f" + " " + "" + "24000 1001" + "" + "" + "urn:uuid:81fed4e5-9722-400a-b9d1-7f2bd21df4b6" + "" + "" + "urn:uuid:16327185-9205-47ef-a17b-ee28df251db7" + "urn:uuid:461f5424-8f6e-48a9-a385-5eda46fda381" + "" + "" + "urn:uuid:ea3d0f23-55d6-4e03-86ec-cfe0666f0e6a" + "24" + "" + "" + "5" + "" + "" + "" + "" + "" + "urn:uuid:6ae100b0-92d1-41be-9321-85e0933dfc42" + "urn:uuid:e8ef9653-565c-479c-8039-82d4547973c5" + "" + "" + "urn:uuid:7d418acb-07a3-4e57-984c-b8ea2f7de4ec" + "24" + "urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751" + "urn:uuid:6f768ca4-c89e-4dac-9056-a29425d40ba1" + "" + "" + "" + "" + "urn:uuid:754dae53-c25f-4f3c-97e4-2bfe5463f83b" + "urn:uuid:68e3fae5-d94b-44d2-92a6-b94877fbcdb5" + "" + "" + "urn:uuid:61ce2a70-10a2-4521-850b-4218755ff3c9" + "24" + "urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751" + "urn:uuid:381dadd2-061e-46cc-a63a-e3d58ce7f488" + "" + "" + "" + "" + "urn:uuid:d29b3884-6633-4dad-9c67-7154af342bc6" + "urn:uuid:6978c106-95bc-424b-a17c-628206a5892d" + "" + "" + "urn:uuid:001ea472-f5da-436c-86de-acaa68c1a7e4" + "24" + "urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751" + "urn:uuid:381dadd2-061e-46cc-a63a-e3d58ce7f488" + "" + "" + "" + "" + "urn:uuid:02af22bf-f776-488a-b001-eb6e16953119" + "urn:uuid:19ff6da1-be79-4235-8d04-42201ad06e65" + "" + "" + "urn:uuid:dfa84292-0609-4097-824c-8e2e15e2ce4d" + "24" + "urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751" + "urn:uuid:bd6272b6-511e-47c1-93bc-d56ebd314a70" + "" + "" + "" + "" + "" + "" + "urn:uuid:a94be493-cd55-4bf7-b496-ea87bfe38632" + "" + "" + "urn:uuid:20c6020b-1fc0-4080-bcf7-89f09f95bea8" + "urn:uuid:461f5424-8f6e-48a9-a385-5eda46fda381" + "" + "" + "urn:uuid:d1f93845-d3e5-4c3b-aa67-8d96c45cfe9c" + "36" + "" + "" + "20" + "" + "" + "" + "24" + "" + "" + "" + "" + "" + "urn:uuid:9b509f42-e4e8-4f78-8c2a-12ddd79ef3c5" + "urn:uuid:e8ef9653-565c-479c-8039-82d4547973c5" + "" + "" + "urn:uuid:a733d812-a3d7-45e9-ba50-13b856d5d35a" + "36" + "urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751" + "urn:uuid:f3b263b3-096b-4360-a952-b1a9623cd0ca" + "" + "" + "" + "" + "urn:uuid:19a282e6-beac-4d99-a008-afa61378eb6c" + "urn:uuid:68e3fae5-d94b-44d2-92a6-b94877fbcdb5" + "" + "" + "urn:uuid:53de5ff9-f5f7-47c5-a2d8-117c36cce517" + "36" + "urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751" + "urn:uuid:2484d613-bb7d-4bcc-8b0f-2e65938f0535" + "" + "" + "" + "" + "urn:uuid:94b0ef77-0621-4086-95a2-85432fa97d40" + "urn:uuid:6978c106-95bc-424b-a17c-628206a5892d" + "" + "" + "urn:uuid:2ce499f2-59bc-4053-87bc-80f4b7e7b73e" + "36" + "urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751" + "urn:uuid:2484d613-bb7d-4bcc-8b0f-2e65938f0535" + "" + "" + "" + "" + "urn:uuid:9ac3b905-c599-4da8-8f0f-fc07e619899d" + "urn:uuid:19ff6da1-be79-4235-8d04-42201ad06e65" + "" + "" + "urn:uuid:0239017b-2ad9-4235-b46d-c4c1126e29fc" + "36" + "urn:uuid:f00e49a8-0dec-4e6c-95e7-078df988b751" + "urn:uuid:bd6272b6-511e-47c1-93bc-d56ebd314a70" + "" + "" + "" + "" + "" + "" + ""; + +const char *cpl_bad_doc = ""; + +const char *asset_map_doc = + "" + "" + "urn:uuid:68d9f591-8191-46b5-38b4-affb87a14132" + "IMF_TEST_ASSET_MAP" + "Some tool" + "1" + "2021-06-07T12:00:00+00:00" + "FFmpeg" + "" + "" + "urn:uuid:b5d674b8-c6ce-4bce-3bdf-be045dfdb2d0" + "" + "" + "IMF_TEST_ASSET_MAP_video.mxf" + "1" + "0" + "1234567" + "" + "" + "" + "" + "urn:uuid:ec3467ec-ab2a-4f49-c8cb-89caa3761f4a" + "" + "" + "IMF_TEST_ASSET_MAP_video_1.mxf" + "1" + "0" + "234567" + "" + "" + "" + "" + "urn:uuid:5cf5b5a7-8bb3-4f08-eaa6-3533d4b77fa6" + "" + "" + "IMF_TEST_ASSET_MAP_audio.mxf" + "1" + "0" + "34567" + "" + "" + "" + "" + "urn:uuid:559777d6-ec29-4375-f90d-300b0bf73686" + "" + "" + "CPL_IMF_TEST_ASSET_MAP.xml" + "1" + "0" + "12345" + "" + "" + "" + "" + "urn:uuid:dd04528d-9b80-452a-7a13-805b08278b3d" + "true" + "" + "" + "PKL_IMF_TEST_ASSET_MAP.xml" + "1" + "0" + "2345" + "" + "" + "" + "" + ""; + +static int test_cpl_parsing(void) +{ + xmlDocPtr doc; + IMFCPL *cpl; + int ret; + + doc = xmlReadMemory(cpl_doc, strlen(cpl_doc), NULL, NULL, 0); + if (doc == NULL) { + printf("XML parsing failed.\n"); + return 1; + } + + ret = parse_imf_cpl_from_xml_dom(doc, &cpl); + xmlFreeDoc(doc); + if (ret) { + printf("CPL parsing failed.\n"); + return 1; + } + + printf("%s\n", cpl->content_title_utf8); + printf(IMF_UUID_FORMAT "\n", UID_ARG(cpl->id_uuid)); + printf("%i %i\n", cpl->edit_rate.num, cpl->edit_rate.den); + + printf("Marker resource count: %lu\n", cpl->main_markers_track->resource_count); + for (unsigned long i = 0; i < cpl->main_markers_track->resource_count; i++) { + printf("Marker resource %lu\n", i); + for (unsigned long j = 0; j < cpl->main_markers_track->resources[i].marker_count; j++) { + printf(" Marker %lu\n", j); + printf(" Label %s\n", cpl->main_markers_track->resources[i].markers[j].label_utf8); + printf(" Offset %lu\n", cpl->main_markers_track->resources[i].markers[j].offset); + } + } + + printf("Main image resource count: %lu\n", cpl->main_image_2d_track->resource_count); + for (unsigned long i = 0; i < cpl->main_image_2d_track->resource_count; i++) { + printf("Track file resource %lu\n", i); + printf(" " IMF_UUID_FORMAT "\n", UID_ARG(cpl->main_image_2d_track->resources[i].track_file_uuid)); + } + + printf("Main audio track count: %lu\n", cpl->main_audio_track_count); + for (unsigned long i = 0; i < cpl->main_audio_track_count; i++) { + printf(" Main audio virtual track %lu\n", i); + printf(" Main audio resource count: %lu\n", cpl->main_audio_tracks[i].resource_count); + for (unsigned long j = 0; j < cpl->main_audio_tracks[i].resource_count; j++) { + printf(" Track file resource %lu\n", j); + printf(" " IMF_UUID_FORMAT "\n", UID_ARG(cpl->main_audio_tracks[i].resources[j].track_file_uuid)); + } + } + + imf_cpl_free(cpl); + + return 0; +} + +static int test_bad_cpl_parsing(void) +{ + xmlDocPtr doc; + IMFCPL *cpl; + int ret; + + doc = xmlReadMemory(cpl_bad_doc, strlen(cpl_bad_doc), NULL, NULL, 0); + if (doc == NULL) { + printf("XML parsing failed.\n"); + return ret; + } + + ret = parse_imf_cpl_from_xml_dom(doc, &cpl); + xmlFreeDoc(doc); + if (ret) { + printf("CPL parsing failed.\n"); + return ret; + } + + return 0; +} + +static int check_asset_locator_attributes(IMFAssetLocator *asset, IMFAssetLocator expected_asset) +{ + + printf("\tCompare " IMF_UUID_FORMAT " to " IMF_UUID_FORMAT ".\n", UID_ARG(asset->uuid), UID_ARG(expected_asset.uuid)); + for (int i = 0; i < 16; ++i) { + if (asset->uuid[i] != expected_asset.uuid[i]) { + printf("Invalid asset locator UUID: found " IMF_UUID_FORMAT " instead of " IMF_UUID_FORMAT " expected.\n", UID_ARG(asset->uuid), UID_ARG(expected_asset.uuid)); + return 1; + } + } + + printf("\tCompare %s to %s.\n", asset->absolute_uri, expected_asset.absolute_uri); + if (strcmp(asset->absolute_uri, expected_asset.absolute_uri) != 0) { + printf("Invalid asset locator URI: found %s instead of %s expected.\n", asset->absolute_uri, expected_asset.absolute_uri); + return 1; + } + + return 0; +} + +static IMFAssetLocator ASSET_MAP_EXPECTED_LOCATORS[5] = { + [0] = {.uuid = {0xb5, 0xd6, 0x74, 0xb8, 0xc6, 0xce, 0x4b, 0xce, 0x3b, 0xdf, 0xbe, 0x04, 0x5d, 0xfd, 0xb2, 0xd0}, .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_video.mxf"}, + [1] = {.uuid = {0xec, 0x34, 0x67, 0xec, 0xab, 0x2a, 0x4f, 0x49, 0xc8, 0xcb, 0x89, 0xca, 0xa3, 0x76, 0x1f, 0x4a}, .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_video_1.mxf"}, + [2] = {.uuid = {0x5c, 0xf5, 0xb5, 0xa7, 0x8b, 0xb3, 0x4f, 0x08, 0xea, 0xa6, 0x35, 0x33, 0xd4, 0xb7, 0x7f, 0xa6}, .absolute_uri = (char *)"IMF_TEST_ASSET_MAP_audio.mxf"}, + [3] = {.uuid = {0x55, 0x97, 0x77, 0xd6, 0xec, 0x29, 0x43, 0x75, 0xf9, 0x0d, 0x30, 0x0b, 0x0b, 0xf7, 0x36, 0x86}, .absolute_uri = (char *)"CPL_IMF_TEST_ASSET_MAP.xml"}, + [4] = {.uuid = {0xdd, 0x04, 0x52, 0x8d, 0x9b, 0x80, 0x45, 0x2a, 0x7a, 0x13, 0x80, 0x5b, 0x08, 0x27, 0x8b, 0x3d}, .absolute_uri = (char *)"PKL_IMF_TEST_ASSET_MAP.xml"}, +}; + +static int test_asset_map_parsing(void) +{ + IMFAssetLocatorMap *asset_locator_map; + xmlDoc *doc; + int ret; + + doc = xmlReadMemory(asset_map_doc, strlen(asset_map_doc), NULL, NULL, 0); + if (doc == NULL) { + printf("Asset map XML parsing failed.\n"); + return 1; + } + + printf("Allocate asset map\n"); + asset_locator_map = imf_asset_locator_map_alloc(); + + printf("Parse asset map XML document\n"); + ret = parse_imf_asset_map_from_xml_dom(NULL, doc, asset_locator_map, doc->name); + if (ret) { + printf("Asset map parsing failed.\n"); + goto cleanup; + } + + printf("Compare assets count: %d to 5\n", asset_locator_map->asset_count); + if (asset_locator_map->asset_count != 5) { + printf("Asset map parsing failed: found %d assets instead of 5 expected.\n", asset_locator_map->asset_count); + ret = 1; + goto cleanup; + } + + for (int i = 0; i < asset_locator_map->asset_count; ++i) { + printf("For asset: %d:\n", i); + ret = check_asset_locator_attributes(asset_locator_map->assets[i], ASSET_MAP_EXPECTED_LOCATORS[i]); + if (ret > 0) { + goto cleanup; + } + } + +cleanup: + imf_asset_locator_map_free(asset_locator_map); + xmlFreeDoc(doc); + return ret; +} + +typedef struct PathTypeTestStruct { + const char *path; + int is_url; + int is_unix_absolute_path; + int is_dos_absolute_path; +} PathTypeTestStruct; + +static const PathTypeTestStruct PATH_TYPE_TEST_STRUCTS[11] = { + [0] = {.path = "file://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0}, + [1] = {.path = "http://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0}, + [2] = {.path = "https://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0}, + [3] = {.path = "s3://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0}, + [4] = {.path = "ftp://path/to/somewhere", .is_url = 1, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0}, + [5] = {.path = "/path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 1, .is_dos_absolute_path = 0}, + [6] = {.path = "path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0}, + [7] = {.path = "C:\\path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1}, + [8] = {.path = "C:/path/to/somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1}, + [9] = {.path = "\\\\path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 1}, + [10] = {.path = "path\\to\\somewhere", .is_url = 0, .is_unix_absolute_path = 0, .is_dos_absolute_path = 0}, +}; + +static int test_path_type_functions(void) +{ + PathTypeTestStruct path_type; + for (int i = 0; i < 11; ++i) { + path_type = PATH_TYPE_TEST_STRUCTS[i]; + if (imf_uri_is_url(path_type.path) != path_type.is_url) { + fprintf(stderr, "URL comparison test failed for '%s', got %d instead of expected %d\n", path_type.path, path_type.is_url, !path_type.is_url); + goto fail; + } + + if (imf_uri_is_unix_abs_path(path_type.path) != path_type.is_unix_absolute_path) { + fprintf(stderr, "Unix absolute path comparison test failed for '%s', got %d instead of expected %d\n", path_type.path, path_type.is_unix_absolute_path, !path_type.is_unix_absolute_path); + goto fail; + } + + if (imf_uri_is_dos_abs_path(path_type.path) != path_type.is_dos_absolute_path) { + fprintf(stderr, "DOS absolute path comparison test failed for '%s', got %d instead of expected %d\n", path_type.path, path_type.is_dos_absolute_path, !path_type.is_dos_absolute_path); + goto fail; + } + } + + return 0; + +fail: + return 1; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + + if (test_cpl_parsing() != 0) + ret = 1; + + if (test_asset_map_parsing() != 0) + ret = 1; + + if (test_path_type_functions() != 0) + ret = 1; + + printf("#### The following should fail ####\n"); + if (test_bad_cpl_parsing() == 0) + ret = 1; + printf("#### End failing test ####\n"); + + return ret; +}