Skip to content

Commit

Permalink
Add golden tests for the written AVIF metadata structure. (AOMediaCod…
Browse files Browse the repository at this point in the history
…ec#1554)

Depends on MP4Box (from the gpac project) to dump an AVIF file's
metadata as XML.

This test catches changes in write.c that may or may not be intentional.
On failure, it prints instructions on how to update the goldens if needed.
The test is disabled by default, but enabled in a new CI workflow.
  • Loading branch information
maryla-uc authored Sep 8, 2023
1 parent fac3bae commit a120c6f
Show file tree
Hide file tree
Showing 11 changed files with 786 additions and 0 deletions.
90 changes: 90 additions & 0 deletions .github/workflows/ci-linux-golden-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Workflow that builds libabvif with aom and libyuv, also builds MP4box,
# and runs tests with "golden" in their name. Test results are saved as artifacts
# which can be downloaded from GitHub'S UI or with 'gh run download'.

name: CI Linux Golden Tests
on: [push, pull_request]

permissions:
contents: read

jobs:
build-shared-run-golden-tests:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]

steps:
- uses: actions/checkout@v3
- name: Set GCC & G++ 10 compiler (on Linux)
run: echo "CC=gcc-10" >> $GITHUB_ENV && echo "CXX=g++-10" >> $GITHUB_ENV
- uses: actions/setup-python@v4
with:
python-version: '3.x'

- name: Cache external dependencies
id: cache-ext
uses: actions/cache@v3
with:
path: ext
key: ${{ runner.os }}-golden-tests-${{ hashFiles('ext/aom.cmd', 'ext/libyuv.cmd', 'ext/mp4box.sh') }}
- name: Setup cmake
uses: jwlawson/[email protected]
with:
cmake-version: '3.13.x'
- name: Print cmake version
run: cmake --version
- uses: ilammy/setup-nasm@v1
with:
version: 2.15.05
- uses: seanmiddleditch/gha-setup-ninja@v3
- name: Build aom
if: steps.cache-ext.outputs.cache-hit != 'true'
working-directory: ./ext
run: bash -e aom.cmd
- name: Build libyuv
if: steps.cache-ext.outputs.cache-hit != 'true'
working-directory: ./ext
run: bash -e libyuv.cmd
- name: Build mp4box
if: steps.cache-ext.outputs.cache-hit != 'true'
working-directory: ./ext
run: bash -e mp4box.sh

- name: Prepare libavif (cmake)
run: >
mkdir build && cd build
cmake .. -G Ninja
-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
-DAVIF_CODEC_AOM=ON -DAVIF_LOCAL_AOM=ON
-DAVIF_LOCAL_LIBYUV=ON
-DAVIF_BUILD_EXAMPLES=ON -DAVIF_BUILD_APPS=ON
-DAVIF_BUILD_TESTS=ON -DAVIF_ENABLE_GOLDEN_TESTS=ON
-DAVIF_ENABLE_GTEST=OFF
-DGOLDEN_TESTS_OUTPUT_DIR=${{ runner.temp }}/golden_tests
- name: Build libavif (ninja)
working-directory: ./build
run: ninja
- name: Run AVIF golden tests
working-directory: ./build
# Runs test that have "golden" in their name.
run: ctest -j $(getconf _NPROCESSORS_ONLN) --output-on-failure -R golden

# See https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts
- name: Archive golden tests output for debugging
if: failure()
uses: actions/upload-artifact@v3
with:
name: golden-tests-output
path: ${{ runner.temp }}/golden_tests/**/*

# Print instructions to help fix the tests.
- name: How to fix failing tests
if: failure()
run: >
echo "If the tests fail, download the test results from the Artifacts list at https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} or with:
gh run download --dir /tmp/golden-tests-output --repo ${{ github.repository }} --name golden-tests-output ${{ github.run_id }}
Then look at the instructions in the unzipped file or in /tmp/golden-tests-output if you used the command line."
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/ext/avm
/ext/dav1d
/ext/googletest
/ext/gpac
/ext/libjpeg
/ext/libgav1
/ext/libpng
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,9 @@ endif()

option(AVIF_BUILD_APPS "Build avif apps." OFF)
option(AVIF_BUILD_TESTS "Build avif tests." OFF)
option(AVIF_ENABLE_GOLDEN_TESTS
"Build tests that compare encoding outputs to golden files. Needs AVIF_BUILD_APPS=ON, and depends on MP4box which can be built with ext/mp4box.sh" OFF
)
option(AVIF_ENABLE_GTEST
"Build avif C++ tests, which depend on GoogleTest. Requires GoogleTest. Has no effect unless AVIF_BUILD_TESTS is ON." ON
)
Expand Down
16 changes: 16 additions & 0 deletions ext/mp4box.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
#
# Local build of MP4Box (part of the gpac project) for tests.

set -e

git clone https://github.com/gpac/gpac.git

cd gpac
git checkout b34e385 # GPAC 2.2.1

./configure --static-bin
make -j
# MP4Box is in ext/gpac/bin/gcc/MP4Box

cd ..
16 changes: 16 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,22 @@ if(AVIF_BUILD_APPS)
${CMAKE_CURRENT_SOURCE_DIR}/data
)

if(AVIF_ENABLE_GOLDEN_TESTS AND AVIF_CODEC_AOM_ENCODE)
# test_cmd_enc_boxes_golden.sh depends on MP4Box
# Only allow a locally built version to avoid differences with versioning.
set(MP4BOX_DIR ${CMAKE_SOURCE_DIR}/ext/gpac/bin/gcc/)
if(NOT EXISTS ${MP4BOX_DIR}/MP4Box)
message(FATAL_ERROR "AVIF_ENABLE_GOLDEN_TESTS is ON but ${MP4BOX_DIR}/MP4Box is missing. Run ext/mp4box.sh")
endif()

set(GOLDEN_TESTS_OUTPUT_DIR "" CACHE STRING "Output path for golden tests (will be a temp dir if empty)")

add_test(NAME test_cmd_enc_boxes_golden
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/test_cmd_enc_boxes_golden.sh ${CMAKE_BINARY_DIR} ${MP4BOX_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/data ${GOLDEN_TESTS_OUTPUT_DIR}
)
endif()

if(NOT AVIF_CODEC_AOM OR NOT AVIF_CODEC_AOM_ENCODE)
# Only aom encoder supports AV1 lossless encoding.
set_property(TEST test_cmd_animation PROPERTY DISABLED True)
Expand Down
81 changes: 81 additions & 0 deletions tests/data/goldens/circle-trns-after-plte.png.avif.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<ISOBaseMediaFileTrace>
<!--MP4Box dump trace-->
<IsoMediaFile xmlns="urn:mpeg:isobmff:schema:file:2016" Name="circle-trns-after-plte.png.avif">
<FileTypeBox Size="32" Type="ftyp" Specification="p12" Container="file otyp" MajorBrand="avif" MinorVersion="0">
<BrandEntry AlternateBrand="avif"/>
<BrandEntry AlternateBrand="mif1"/>
<BrandEntry AlternateBrand="miaf"/>
<BrandEntry AlternateBrand="MA1A"/>
</FileTypeBox>
<MetaBox Size="397" Type="meta" Version="0" Flags="0" Specification="p12" Container="file moov trak moof traf udta" >
<HandlerBox Size="40" Type="hdlr" Version="0" Flags="0" Specification="p12" Container="mdia meta minf" hdlrType="pict" Name="libavif" reserved1="0" reserved2="data:application/octet-string,000000000000000000000000">
</HandlerBox>
<PrimaryItemBox Size="14" Type="pitm" Version="0" Flags="0" Specification="p12" Container="meta" item_ID="1">
</PrimaryItemBox>
<ItemLocationBox Size="44" Type="iloc" Version="0" Flags="0" Specification="p12" Container="meta" offset_size="4" length_size="4" base_offset_size="0" index_size="0">
<ItemLocationEntry item_ID="1" data_reference_index="0" base_offset="0" construction_method="0">
<ItemExtentEntry extent_offset="REDACTED" extent_length="REDACTED" extent_index="0" />
</ItemLocationEntry>
<ItemLocationEntry item_ID="2" data_reference_index="0" base_offset="0" construction_method="0">
<ItemExtentEntry extent_offset="REDACTED" extent_length="REDACTED" extent_index="0" />
</ItemLocationEntry>
</ItemLocationBox>
<ItemInfoBox Size="66" Type="iinf" Version="0" Flags="0" Specification="p12" Container="meta" >
<ItemInfoEntryBox Size="26" Type="infe" Version="2" Flags="0" Specification="p12" Container="iinf" item_ID="1" item_protection_index="0" item_name="Color" content_type="(null)" content_encoding="(null)" item_type="av01">
</ItemInfoEntryBox>
<ItemInfoEntryBox Size="26" Type="infe" Version="2" Flags="0" Specification="p12" Container="iinf" item_ID="2" item_protection_index="0" item_name="Alpha" content_type="(null)" content_encoding="(null)" item_type="av01">
</ItemInfoEntryBox>
</ItemInfoBox>
<ItemReferenceBox Size="26" Type="iref" Version="0" Flags="0" Specification="p12" Container="meta" >
<ItemReferenceBox Size="14" Type="auxl" Specification="p12" Container="iref" from_item_id="2">
<ItemReferenceBoxEntry ItemID="1"/>
</ItemReferenceBox>
</ItemReferenceBox>
<ItemPropertiesBox Size="195" Type="iprp" Specification="iff" Container="meta" >
<ItemPropertyContainerBox Size="157" Type="ipco" Specification="iff" Container="iprp" >
<ImageSpatialExtentsPropertyBox Size="20" Type="ispe" Version="0" Flags="0" Specification="iff" Container="ipco" image_width="100" image_height="60">
</ImageSpatialExtentsPropertyBox>
<PixelInformationPropertyBox Size="16" Type="pixi" Version="0" Flags="0" Specification="iff" Container="ipco" >
<BitPerChannel bits_per_channel="8"/>
<BitPerChannel bits_per_channel="8"/>
<BitPerChannel bits_per_channel="8"/>
</PixelInformationPropertyBox>
<AV1ConfigurationBox>
<AV1Config version="1" profile="1" level_idx0="0" tier="0" high_bitdepth="0" twelve_bit="0" monochrome="0" chroma_subsampling_x="0" chroma_subsampling_y="0" chroma_sample_position="0" initial_presentation_delay="1" OBUs_count="0">
</AV1Config>
</AV1ConfigurationBox>
<ColourInformationBox Size="19" Type="colr" Specification="iff" Container="video_sample_entry ipco encv resv" colour_type="nclx" colour_primaries="1" transfer_characteristics="13" matrix_coefficients="6" full_range_flag="1">
</ColourInformationBox>
<PixelInformationPropertyBox Size="14" Type="pixi" Version="0" Flags="0" Specification="iff" Container="ipco" >
<BitPerChannel bits_per_channel="8"/>
</PixelInformationPropertyBox>
<AV1ConfigurationBox>
<AV1Config version="1" profile="0" level_idx0="0" tier="0" high_bitdepth="0" twelve_bit="0" monochrome="1" chroma_subsampling_x="1" chroma_subsampling_y="1" chroma_sample_position="0" initial_presentation_delay="1" OBUs_count="0">
</AV1Config>
</AV1ConfigurationBox>
<AuxiliaryTypePropertyBox Size="56" Type="auxC" Version="0" Flags="0" Specification="iff" Container="ipco" aux_type="urn:mpeg:mpegB:cicp:systems:auxiliary:alpha" aux_subtype="">
</AuxiliaryTypePropertyBox>
</ItemPropertyContainerBox>
<ItemPropertyAssociationBox Size="30" Type="ipma" Version="0" Flags="0" Specification="iff" Container="iprp" entry_count="2">
<AssociationEntry item_ID="1" association_count="4">
<Property index="1" essential="0"/>
<Property index="2" essential="0"/>
<Property index="3" essential="1"/>
<Property index="4" essential="0"/>
</AssociationEntry>
<AssociationEntry item_ID="2" association_count="4">
<Property index="1" essential="0"/>
<Property index="5" essential="0"/>
<Property index="6" essential="1"/>
<Property index="7" essential="0"/>
</AssociationEntry>
</ItemPropertyAssociationBox>
</ItemPropertiesBox>
</MetaBox>
<MediaDataBox Size="REDACTED" Type="mdat" Specification="p12" Container="file" dataSize="REDACTED">
</MediaDataBox>
</IsoMediaFile>
<Tracks>
</Tracks>
</ISOBaseMediaFileTrace>
116 changes: 116 additions & 0 deletions tests/data/goldens/dog_exif_extended_xmp_icc.jpg.avif.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<ISOBaseMediaFileTrace>
<!--MP4Box dump trace-->
<IsoMediaFile xmlns="urn:mpeg:isobmff:schema:file:2016" Name="dog_exif_extended_xmp_icc.jpg.avif">
<FileTypeBox Size="32" Type="ftyp" Specification="p12" Container="file otyp" MajorBrand="avif" MinorVersion="0">
<BrandEntry AlternateBrand="avif"/>
<BrandEntry AlternateBrand="mif1"/>
<BrandEntry AlternateBrand="miaf"/>
<BrandEntry AlternateBrand="MA1B"/>
</FileTypeBox>
<MetaBox Size="495" Type="meta" Version="0" Flags="0" Specification="p12" Container="file moov trak moof traf udta" >
<HandlerBox Size="40" Type="hdlr" Version="0" Flags="0" Specification="p12" Container="mdia meta minf" hdlrType="pict" Name="libavif" reserved1="0" reserved2="data:application/octet-string,000000000000000000000000">
</HandlerBox>
<PrimaryItemBox Size="14" Type="pitm" Version="0" Flags="0" Specification="p12" Container="meta" item_ID="1">
</PrimaryItemBox>
<ItemLocationBox Size="86" Type="iloc" Version="0" Flags="0" Specification="p12" Container="meta" offset_size="4" length_size="4" base_offset_size="0" index_size="0">
<ItemLocationEntry item_ID="1" data_reference_index="0" base_offset="0" construction_method="0">
<ItemExtentEntry extent_offset="REDACTED" extent_length="REDACTED" extent_index="0" />
</ItemLocationEntry>
<ItemLocationEntry item_ID="2" data_reference_index="0" base_offset="0" construction_method="0">
<ItemExtentEntry extent_offset="REDACTED" extent_length="REDACTED" extent_index="0" />
</ItemLocationEntry>
<ItemLocationEntry item_ID="3" data_reference_index="0" base_offset="0" construction_method="0">
<ItemExtentEntry extent_offset="REDACTED" extent_length="REDACTED" extent_index="0" />
</ItemLocationEntry>
<ItemLocationEntry item_ID="4" data_reference_index="0" base_offset="0" construction_method="0">
<ItemExtentEntry extent_offset="REDACTED" extent_length="REDACTED" extent_index="0" />
</ItemLocationEntry>
<ItemLocationEntry item_ID="5" data_reference_index="0" base_offset="0" construction_method="0">
<ItemExtentEntry extent_offset="REDACTED" extent_length="REDACTED" extent_index="0" />
</ItemLocationEntry>
</ItemLocationBox>
<ItemInfoBox Size="144" Type="iinf" Version="0" Flags="0" Specification="p12" Container="meta" >
<ItemInfoEntryBox Size="26" Type="infe" Version="2" Flags="0" Specification="p12" Container="iinf" item_ID="1" item_protection_index="0" item_name="Color" content_type="(null)" content_encoding="(null)" item_type="grid">
</ItemInfoEntryBox>
<ItemInfoEntryBox Size="26" Type="infe" Version="2" Flags="1" Specification="p12" Container="iinf" item_ID="2" item_protection_index="0" item_name="Color" content_type="(null)" content_encoding="(null)" item_type="av01">
</ItemInfoEntryBox>
<ItemInfoEntryBox Size="26" Type="infe" Version="2" Flags="1" Specification="p12" Container="iinf" item_ID="3" item_protection_index="0" item_name="Color" content_type="(null)" content_encoding="(null)" item_type="av01">
</ItemInfoEntryBox>
<ItemInfoEntryBox Size="26" Type="infe" Version="2" Flags="1" Specification="p12" Container="iinf" item_ID="4" item_protection_index="0" item_name="Color" content_type="(null)" content_encoding="(null)" item_type="av01">
</ItemInfoEntryBox>
<ItemInfoEntryBox Size="26" Type="infe" Version="2" Flags="1" Specification="p12" Container="iinf" item_ID="5" item_protection_index="0" item_name="Color" content_type="(null)" content_encoding="(null)" item_type="av01">
</ItemInfoEntryBox>
</ItemInfoBox>
<ItemReferenceBox Size="32" Type="iref" Version="0" Flags="0" Specification="p12" Container="meta" >
<ItemReferenceBox Size="20" Type="dimg" Specification="p12" Container="iref" from_item_id="1">
<ItemReferenceBoxEntry ItemID="2"/>
<ItemReferenceBoxEntry ItemID="3"/>
<ItemReferenceBoxEntry ItemID="4"/>
<ItemReferenceBoxEntry ItemID="5"/>
</ItemReferenceBox>
</ItemReferenceBox>
<ItemPropertiesBox Size="167" Type="iprp" Specification="iff" Container="meta" >
<ItemPropertyContainerBox Size="104" Type="ipco" Specification="iff" Container="iprp" >
<ImageSpatialExtentsPropertyBox Size="20" Type="ispe" Version="0" Flags="0" Specification="iff" Container="ipco" image_width="4032" image_height="3024">
</ImageSpatialExtentsPropertyBox>
<PixelInformationPropertyBox Size="16" Type="pixi" Version="0" Flags="0" Specification="iff" Container="ipco" >
<BitPerChannel bits_per_channel="8"/>
<BitPerChannel bits_per_channel="8"/>
<BitPerChannel bits_per_channel="8"/>
</PixelInformationPropertyBox>
<ColourInformationBox Size="19" Type="colr" Specification="iff" Container="video_sample_entry ipco encv resv" colour_type="nclx" colour_primaries="2" transfer_characteristics="2" matrix_coefficients="6" full_range_flag="1">
</ColourInformationBox>
<ImageRotationBox Size="9" Type="irot" Specification="iff" Container="ipco" angle="270">
</ImageRotationBox>
<ImageSpatialExtentsPropertyBox Size="20" Type="ispe" Version="0" Flags="0" Specification="iff" Container="ipco" image_width="2016" image_height="1512">
</ImageSpatialExtentsPropertyBox>
<AV1ConfigurationBox>
<AV1Config version="1" profile="0" level_idx0="12" tier="0" high_bitdepth="0" twelve_bit="0" monochrome="0" chroma_subsampling_x="1" chroma_subsampling_y="1" chroma_sample_position="0" initial_presentation_delay="1" OBUs_count="0">
</AV1Config>
</AV1ConfigurationBox>
</ItemPropertyContainerBox>
<ItemPropertyAssociationBox Size="55" Type="ipma" Version="0" Flags="0" Specification="iff" Container="iprp" entry_count="5">
<AssociationEntry item_ID="1" association_count="4">
<Property index="1" essential="0"/>
<Property index="2" essential="0"/>
<Property index="3" essential="0"/>
<Property index="4" essential="1"/>
</AssociationEntry>
<AssociationEntry item_ID="2" association_count="5">
<Property index="5" essential="0"/>
<Property index="2" essential="0"/>
<Property index="6" essential="1"/>
<Property index="3" essential="0"/>
<Property index="4" essential="1"/>
</AssociationEntry>
<AssociationEntry item_ID="3" association_count="5">
<Property index="5" essential="0"/>
<Property index="2" essential="0"/>
<Property index="6" essential="1"/>
<Property index="3" essential="0"/>
<Property index="4" essential="1"/>
</AssociationEntry>
<AssociationEntry item_ID="4" association_count="5">
<Property index="5" essential="0"/>
<Property index="2" essential="0"/>
<Property index="6" essential="1"/>
<Property index="3" essential="0"/>
<Property index="4" essential="1"/>
</AssociationEntry>
<AssociationEntry item_ID="5" association_count="5">
<Property index="5" essential="0"/>
<Property index="2" essential="0"/>
<Property index="6" essential="1"/>
<Property index="3" essential="0"/>
<Property index="4" essential="1"/>
</AssociationEntry>
</ItemPropertyAssociationBox>
</ItemPropertiesBox>
</MetaBox>
<MediaDataBox Size="REDACTED" Type="mdat" Specification="p12" Container="file" dataSize="REDACTED">
</MediaDataBox>
</IsoMediaFile>
<Tracks>
</Tracks>
</ISOBaseMediaFileTrace>
Loading

0 comments on commit a120c6f

Please sign in to comment.