Skip to content

Commit

Permalink
Add codec "avifenc" with various speed param values. Using "avifenc" …
Browse files Browse the repository at this point in the history
…binary -- a libavif-based tool.
  • Loading branch information
adityamavlankar committed Sep 17, 2020
1 parent e11b7db commit adf6e67
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 20 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ parallel_*txt
4*.png
__pycache__/
stats.json
stats.log
stats.log
bdrates_*.db.txt
bitrate_savings_*.db.txt
60 changes: 45 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ENV FFMPEG_VERSION=4.2.1 \
OGG_VERSION=1.3.2 \
OPUS_VERSION=1.2 \
OPENJPEG_VERSION=2.3.1 \
THEORA_VERSION=1.1.1 \
# THEORA_VERSION=1.1.1 \
VORBIS_VERSION=1.3.5 \
VPX_VERSION=1.8.1 \
WEBP_VERSION=1.0.3 \
Expand All @@ -46,7 +46,7 @@ ENV FFMPEG_VERSION=4.2.1 \
ARG OGG_SHA256SUM="e19ee34711d7af328cb26287f4137e70630e7261b17cbe3cd41011d73a654692 libogg-1.3.2.tar.gz"
ARG OPUS_SHA256SUM="77db45a87b51578fbc49555ef1b10926179861d854eb2613207dc79d9ec0a9a9 opus-1.2.tar.gz"
ARG VORBIS_SHA256SUM="6efbcecdd3e5dfbf090341b485da9d176eb250d893e3eb378c428a2db38301ce libvorbis-1.3.5.tar.gz"
ARG THEORA_SHA256SUM="40952956c47811928d1e7922cda3bc1f427eb75680c3c37249c91e949054916b libtheora-1.1.1.tar.gz"
# ARG THEORA_SHA256SUM="40952956c47811928d1e7922cda3bc1f427eb75680c3c37249c91e949054916b libtheora-1.1.1.tar.gz"
ARG XVID_SHA256SUM="4e9fd62728885855bc5007fe1be58df42e5e274497591fec37249e1052ae316f xvidcore-1.3.4.tar.gz"
ARG FREETYPE_SHA256SUM="5d03dd76c2171a7601e9ce10551d52d4471cf92cd205948e60289251daddffa8 freetype-2.5.5.tar.gz"
ARG LIBVIDSTAB_SHA256SUM="14d2a053e56edad4f397be0cb3ef8eb1ec3150404ce99a426c4eb641861dc0bb v1.1.0.tar.gz"
Expand All @@ -66,15 +66,18 @@ RUN buildDeps="autoconf \
gperf \
imagemagick \
libexpat1-dev \
libpng-dev \
libjpeg-dev \
libssl-dev \
libtool \
make \
nasm \
ninja-build \
patchelf \
perl \
pkg-config \
python3 \
python3-pip \
re2c \
subversion \
unzip \
wget \
Expand All @@ -87,6 +90,33 @@ RUN buildDeps="autoconf \
# SQLite3 is to store metrics.
RUN apt-get install -y sqlite3 libsqlite3-dev

# Install nasm 2.14
RUN curl -L https://download.videolan.org/contrib/nasm/nasm-2.14.tar.gz | tar xvz && \
cd nasm-2.14 && \
./configure && make -j2 && make install && \
cd .. && \
nasm --version

# Install latest ninja
RUN git clone -b release https://github.com/ninja-build/ninja.git && \
cd ninja/ && \
python3 ./configure.py && \
ninja && \
cp ninja `which ninja` && \
cd .. && \
ninja --version

# AVIFENC
RUN mkdir -p /tools && \
cd /tools && \
git clone https://github.com/AOMediaCodec/libavif && \
cd /tools/libavif/ext && \
$SHELL ./aom.cmd && \
cd /tools/libavif && \
mkdir build && cd build && \
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DAVIF_CODEC_AOM=ON -DAVIF_LOCAL_AOM=ON -DAVIF_CODEC_DAV1D=OFF -DAVIF_LOCAL_DAV1D=OFF -DAVIF_CODEC_RAV1E=OFF -DAVIF_LOCAL_RAV1E=OFF -DAVIF_CODEC_LIBGAV1=OFF -DAVIF_LOCAL_LIBGAV1=OFF -DAVIF_BUILD_TESTS=1 -DAVIF_BUILD_APPS=1 && \
ninja

## opencore-amr https://sourceforge.net/projects/opencore-amr/
# RUN \
# DIR=/tmp/opencore-amr && \
Expand Down Expand Up @@ -166,17 +196,17 @@ RUN \
rm -rf ${DIR}

### libtheora http:https://www.theora.org/
RUN \
DIR=/tmp/theora && \
mkdir -p ${DIR} && \
cd ${DIR} && \
curl -sLO http:https://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.gz && \
echo ${THEORA_SHA256SUM} | sha256sum --check && \
tar -zx --strip-components=1 -f libtheora-${THEORA_VERSION}.tar.gz && \
./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared && \
make && \
make install && \
rm -rf ${DIR}
#RUN \
# DIR=/tmp/theora && \
# mkdir -p ${DIR} && \
# cd ${DIR} && \
# curl -sLO http:https://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.gz && \
# echo ${THEORA_SHA256SUM} | sha256sum --check && \
# tar -zx --strip-components=1 -f libtheora-${THEORA_VERSION}.tar.gz && \
# ./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared && \
# make && \
# make install && \
# rm -rf ${DIR}

### libvpx https://www.webmproject.org/code/
RUN \
Expand Down Expand Up @@ -387,7 +417,7 @@ RUN \
# --enable-libmp3lame \
--enable-libopenjpeg \
--enable-libopus \
--enable-libtheora \
# --enable-libtheora \
--enable-libvorbis \
--enable-libvpx \
# --enable-libwebp \
Expand Down
5 changes: 3 additions & 2 deletions analyze_encoding_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ def main(argv):
baseline_codec = 'jpeg'
sub_sampling_arr = ['420', '444']
codecs = ['jpeg-mse', 'jpeg-ms-ssim', 'jpeg-im', 'jpeg-hvs-psnr', 'webp', 'kakadu-mse', 'kakadu-visual', 'openjpeg',
'hevc', 'avif-mse', 'avif-ssim']
plot_list = ['webp', 'kakadu-mse', 'kakadu-visual', 'hevc', 'avif-mse', 'avif-ssim']
'hevc', 'avif-mse', 'avif-ssim', 'avifenc-sp-0', 'avifenc-sp-2', 'avifenc-sp-4', 'avifenc-sp-8']
# plot_list = ['webp', 'kakadu-mse', 'kakadu-visual', 'hevc', 'avif-mse', 'avif-ssim']
plot_list = ['webp', 'avif-mse', 'avifenc-sp-0', 'avifenc-sp-2', 'avifenc-sp-4', 'avifenc-sp-8']
color_list = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']
marker_list = ['o', 'v', '>', '<', 's', 'p', 'd', '4', 'P', 'X']
assert len(color_list) == len(marker_list) # 10 curves on one plot is the limit, beyond that is sensory overload
Expand Down
4 changes: 2 additions & 2 deletions compute_BD_rates.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ def main(argv):
baseline_codec = 'jpeg'
sub_sampling_arr = ['420', '444']
codecs = ['jpeg-mse', 'jpeg-ms-ssim', 'jpeg-im', 'jpeg-hvs-psnr', 'webp', 'kakadu-mse', 'kakadu-visual', 'openjpeg',
'hevc', 'avif-mse', 'avif-ssim']
metrics_for_BDRate = ['vmaf', 'ssim', 'ms_ssim', 'vif', 'psnr_y', 'psnr_avg']
'hevc', 'avif-mse', 'avif-ssim', 'avifenc-sp-0', 'avifenc-sp-2', 'avifenc-sp-4', 'avifenc-sp-8']
metrics_for_BDRate = ['vmaf', 'ssim', 'ms_ssim', 'vif', 'adm2', 'psnr_y', 'psnr_avg']
for sub_sampling in sub_sampling_arr:
bdrates_various_metrics = dict()
black_list_source_various_metrics = dict()
Expand Down
52 changes: 52 additions & 0 deletions script_compress_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@
CodecType('hevc', True, 10, 51, 1, '444'),
CodecType('hevc', True, 10, 51, 1, '444u'),

# The codecs 'avif-mse' and 'avif-ssim' write out a "single-frame video" file in IVF format,
# so technically not a proper AVIF. But they accomplish "full-range" YUV encoding similar to a "proper" AVIF.
CodecType('avif-mse', True, 8, 63, 1, '420'),
CodecType('avif-mse', True, 8, 63, 1, '444'),
CodecType('avif-mse', True, 8, 63, 1, '444u'),
Expand All @@ -95,6 +97,24 @@
CodecType('avif-ssim', True, 8, 63, 1, '444'),
CodecType('avif-ssim', True, 8, 63, 1, '444u'),

# Codecs starting with 'avifenc' prefix write out a proper AVIF; avifenc is a libavif-based tool.
# https://github.com/AOMediaCodec/libavif
CodecType('avifenc-sp-0', True, 8, 62, 1, '420'),
CodecType('avifenc-sp-0', True, 8, 62, 1, '444'),
CodecType('avifenc-sp-0', True, 8, 62, 1, '444u'),

CodecType('avifenc-sp-2', True, 8, 62, 1, '420'),
CodecType('avifenc-sp-2', True, 8, 62, 1, '444'),
CodecType('avifenc-sp-2', True, 8, 62, 1, '444u'),

CodecType('avifenc-sp-4', True, 8, 62, 1, '420'),
CodecType('avifenc-sp-4', True, 8, 62, 1, '444'),
CodecType('avifenc-sp-4', True, 8, 62, 1, '444u'),

CodecType('avifenc-sp-8', True, 8, 62, 1, '420'),
CodecType('avifenc-sp-8', True, 8, 62, 1, '444'),
CodecType('avifenc-sp-8', True, 8, 62, 1, '444u'),

)

LOGGER = logging.getLogger('image.compression')
Expand Down Expand Up @@ -601,6 +621,38 @@ def f(param, codec, image, width, height, temp_folder, subsampling):
cmd = ['aomdec', '--rawvideo', '-o', decoded_yuv, encoded_file]
my_exec(cmd)

elif codec in ['avifenc-sp-0', 'avifenc-sp-2', 'avifenc-sp-4', 'avifenc-sp-8'] and subsampling in ['420', '444u', '444']:
min_QP = int(param) - 1
max_QP = int(param) + 1
info = codec.split('-')
speed = info[2]

cmd = ['ffmpeg', '-y', '-i', image, '-pix_fmt', get_pixel_format_for_encoding(subsampling), source_yuv]
my_exec(cmd)

source_y4m = get_filename_with_temp_folder(temp_folder, 'source.y4m')
cmd = ['ffmpeg', '-y', '-f', 'rawvideo', '-pix_fmt', get_pixel_format_for_encoding(subsampling),
'-s:v', '%s,%s' % (width, height), '-i', source_yuv, source_y4m]
my_exec(cmd)

encoded_file = get_filename_with_temp_folder(temp_folder, 'temp.avif')
# bit-depth and yuv subsampling are maintained for y4m input
cmd = ['/tools/libavif/build/avifenc', source_y4m, encoded_file, '--nclx', '1/13/1', '--min', str(min_QP),
'--max', str(max_QP), '--speed', speed, '--codec', 'aom', '--jobs', '4']
my_exec(cmd)

decoded_y4m = get_filename_with_temp_folder(temp_folder, 'decoded.y4m')
cmd = ['/tools/libavif/build/avifdec', '--codec', 'aom', encoded_file, decoded_y4m]
my_exec(cmd)

# explicitly convert to 420 or 444 depending on the case from the y4m
cmd = ['ffmpeg', '-y', '-i', decoded_y4m, '-pix_fmt', get_pixel_format_for_encoding(subsampling),
decoded_yuv]
my_exec(cmd)

if subsampling == '444u':
source_yuv, decoded_yuv = convert_420_to_444_source_and_decoded(source_yuv, decoded_yuv, image, width, height, subsampling)

else:
raise RuntimeError('Unsupported codec and subsampling ' + codec + ' / ' + subsampling)

Expand Down

0 comments on commit adf6e67

Please sign in to comment.