xref: /aosp_15_r20/external/libvpx/test/vpxenc.sh (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1#!/bin/sh
2##
3##  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
4##
5##  Use of this source code is governed by a BSD-style license
6##  that can be found in the LICENSE file in the root of the source
7##  tree. An additional intellectual property rights grant can be found
8##  in the file PATENTS.  All contributing project authors may
9##  be found in the AUTHORS file in the root of the source tree.
10##
11##  This file tests vpxenc using hantro_collage_w352h288.yuv as input. To add
12##  new tests to this file, do the following:
13##    1. Write a shell function (this is your test).
14##    2. Add the function to vpxenc_tests (on a new line).
15##
16. $(dirname $0)/tools_common.sh
17
18readonly TEST_FRAMES=10
19
20# Environment check: Make sure input is available.
21vpxenc_verify_environment() {
22  if [ ! -e "${YUV_RAW_INPUT}" ]; then
23    elog "The file ${YUV_RAW_INPUT##*/} must exist in LIBVPX_TEST_DATA_PATH."
24    return 1
25  fi
26  if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
27    if [ ! -e "${Y4M_NOSQ_PAR_INPUT}" ]; then
28      elog "The file ${Y4M_NOSQ_PAR_INPUT##*/} must exist in"
29      elog "LIBVPX_TEST_DATA_PATH."
30      return 1
31    fi
32  fi
33  if [ -z "$(vpx_tool_path vpxenc)" ]; then
34    elog "vpxenc not found. It must exist in LIBVPX_BIN_PATH or its parent."
35    return 1
36  fi
37}
38
39vpxenc_can_encode_vp8() {
40  if [ "$(vp8_encode_available)" = "yes" ]; then
41    echo yes
42  fi
43}
44
45vpxenc_can_encode_vp9() {
46  if [ "$(vp9_encode_available)" = "yes" ]; then
47    echo yes
48  fi
49}
50
51# Echo vpxenc command line parameters allowing use of
52# hantro_collage_w352h288.yuv as input.
53yuv_input_hantro_collage() {
54  echo ""${YUV_RAW_INPUT}"
55       --width="${YUV_RAW_INPUT_WIDTH}"
56       --height="${YUV_RAW_INPUT_HEIGHT}""
57}
58
59y4m_input_non_square_par() {
60  echo ""${Y4M_NOSQ_PAR_INPUT}""
61}
62
63y4m_input_720p() {
64  echo ""${Y4M_720P_INPUT}""
65}
66
67# Echo default vpxenc real time encoding params. $1 is the codec, which defaults
68# to vp8 if unspecified.
69vpxenc_rt_params() {
70  local codec="${1:-vp8}"
71  echo "--codec=${codec}
72    --buf-initial-sz=500
73    --buf-optimal-sz=600
74    --buf-sz=1000
75    --cpu-used=-6
76    --end-usage=cbr
77    --error-resilient=1
78    --kf-max-dist=90000
79    --lag-in-frames=0
80    --max-intra-rate=300
81    --max-q=56
82    --min-q=2
83    --noise-sensitivity=0
84    --overshoot-pct=50
85    --passes=1
86    --profile=0
87    --resize-allowed=0
88    --rt
89    --static-thresh=0
90    --undershoot-pct=50"
91}
92
93# Forces --passes to 1 with CONFIG_REALTIME_ONLY.
94vpxenc_passes_param() {
95  if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" = "yes" ]; then
96    echo "--passes=1"
97  else
98    echo "--passes=2"
99  fi
100}
101
102# Wrapper function for running vpxenc with pipe input. Requires that
103# LIBVPX_BIN_PATH points to the directory containing vpxenc. $1 is used as the
104# input file path and shifted away. All remaining parameters are passed through
105# to vpxenc.
106vpxenc_pipe() {
107  local encoder="$(vpx_tool_path vpxenc)"
108  local input="$1"
109  shift
110  cat "${input}" | eval "${VPX_TEST_PREFIX}" "${encoder}" - \
111    --test-decode=fatal \
112    "$@" ${devnull}
113}
114
115# Wrapper function for running vpxenc. Requires that LIBVPX_BIN_PATH points to
116# the directory containing vpxenc. $1 one is used as the input file path and
117# shifted away. All remaining parameters are passed through to vpxenc.
118vpxenc() {
119  local encoder="$(vpx_tool_path vpxenc)"
120  local input="$1"
121  shift
122  eval "${VPX_TEST_PREFIX}" "${encoder}" "${input}" \
123    --test-decode=fatal \
124    "$@" ${devnull}
125}
126
127vpxenc_vp8_ivf() {
128  if [ "$(vpxenc_can_encode_vp8)" = "yes" ]; then
129    local output="${VPX_TEST_OUTPUT_DIR}/vp8.ivf"
130    vpxenc $(yuv_input_hantro_collage) \
131      --codec=vp8 \
132      --limit="${TEST_FRAMES}" \
133      --ivf \
134      --output="${output}" || return 1
135
136    if [ ! -e "${output}" ]; then
137      elog "Output file does not exist."
138      return 1
139    fi
140  fi
141}
142
143vpxenc_vp8_webm() {
144  if [ "$(vpxenc_can_encode_vp8)" = "yes" ] && \
145     [ "$(webm_io_available)" = "yes" ]; then
146    local output="${VPX_TEST_OUTPUT_DIR}/vp8.webm"
147    vpxenc $(yuv_input_hantro_collage) \
148      --codec=vp8 \
149      --limit="${TEST_FRAMES}" \
150      --output="${output}" || return 1
151
152    if [ ! -e "${output}" ]; then
153      elog "Output file does not exist."
154      return 1
155    fi
156  fi
157}
158
159vpxenc_vp8_webm_rt() {
160  if [ "$(vpxenc_can_encode_vp8)" = "yes" ] && \
161     [ "$(webm_io_available)" = "yes" ]; then
162    local output="${VPX_TEST_OUTPUT_DIR}/vp8_rt.webm"
163    vpxenc $(yuv_input_hantro_collage) \
164      $(vpxenc_rt_params vp8) \
165      --output="${output}" || return 1
166
167    if [ ! -e "${output}" ]; then
168      elog "Output file does not exist."
169      return 1
170    fi
171  fi
172}
173
174vpxenc_vp8_webm_2pass() {
175  if [ "$(vpxenc_can_encode_vp8)" = "yes" ] && \
176     [ "$(webm_io_available)" = "yes" ]; then
177    local output="${VPX_TEST_OUTPUT_DIR}/vp8.webm"
178    vpxenc $(yuv_input_hantro_collage) \
179      --codec=vp8 \
180      --limit="${TEST_FRAMES}" \
181      --output="${output}" \
182      --passes=2 || return 1
183
184    if [ ! -e "${output}" ]; then
185      elog "Output file does not exist."
186      return 1
187    fi
188  fi
189}
190
191vpxenc_vp8_webm_lag10_frames20() {
192  if [ "$(vpxenc_can_encode_vp8)" = "yes" ] && \
193     [ "$(webm_io_available)" = "yes" ]; then
194    local lag_total_frames=20
195    local lag_frames=10
196    local output="${VPX_TEST_OUTPUT_DIR}/vp8_lag10_frames20.webm"
197    vpxenc $(yuv_input_hantro_collage) \
198      --codec=vp8 \
199      --limit="${lag_total_frames}" \
200      --lag-in-frames="${lag_frames}" \
201      --output="${output}" \
202      --auto-alt-ref=1 \
203      --passes=2 || return 1
204
205    if [ ! -e "${output}" ]; then
206      elog "Output file does not exist."
207      return 1
208    fi
209  fi
210}
211
212vpxenc_vp8_ivf_piped_input() {
213  if [ "$(vpxenc_can_encode_vp8)" = "yes" ]; then
214    local output="${VPX_TEST_OUTPUT_DIR}/vp8_piped_input.ivf"
215    vpxenc_pipe $(yuv_input_hantro_collage) \
216      --codec=vp8 \
217      --limit="${TEST_FRAMES}" \
218      --ivf \
219      --output="${output}" || return 1
220
221    if [ ! -e "${output}" ]; then
222      elog "Output file does not exist."
223      return 1
224    fi
225  fi
226}
227
228vpxenc_vp9_ivf() {
229  if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
230    local output="${VPX_TEST_OUTPUT_DIR}/vp9.ivf"
231    local passes=$(vpxenc_passes_param)
232    vpxenc $(yuv_input_hantro_collage) \
233      --codec=vp9 \
234      --limit="${TEST_FRAMES}" \
235      "${passes}" \
236      --ivf \
237      --output="${output}" || return 1
238
239    if [ ! -e "${output}" ]; then
240      elog "Output file does not exist."
241      return 1
242    fi
243  fi
244}
245
246vpxenc_vp9_webm() {
247  if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
248     [ "$(webm_io_available)" = "yes" ]; then
249    local output="${VPX_TEST_OUTPUT_DIR}/vp9.webm"
250    local passes=$(vpxenc_passes_param)
251    vpxenc $(yuv_input_hantro_collage) \
252      --codec=vp9 \
253      --limit="${TEST_FRAMES}" \
254      "${passes}" \
255      --output="${output}" || return 1
256
257    if [ ! -e "${output}" ]; then
258      elog "Output file does not exist."
259      return 1
260    fi
261  fi
262}
263
264vpxenc_vp9_webm_rt() {
265  if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
266     [ "$(webm_io_available)" = "yes" ]; then
267    local output="${VPX_TEST_OUTPUT_DIR}/vp9_rt.webm"
268    vpxenc $(yuv_input_hantro_collage) \
269      $(vpxenc_rt_params vp9) \
270      --output="${output}" || return 1
271
272    if [ ! -e "${output}" ]; then
273      elog "Output file does not exist."
274      return 1
275    fi
276  fi
277}
278
279vpxenc_vp9_webm_rt_multithread_tiled() {
280  if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
281     [ "$(webm_io_available)" = "yes" ]; then
282    local output="${VPX_TEST_OUTPUT_DIR}/vp9_rt_multithread_tiled.webm"
283    local tilethread_min=2
284    local tilethread_max=4
285    local num_threads="$(seq ${tilethread_min} ${tilethread_max})"
286    local num_tile_cols="$(seq ${tilethread_min} ${tilethread_max})"
287
288    for threads in ${num_threads}; do
289      for tile_cols in ${num_tile_cols}; do
290        vpxenc $(y4m_input_720p) \
291          $(vpxenc_rt_params vp9) \
292          --threads=${threads} \
293          --tile-columns=${tile_cols} \
294          --output="${output}" || return 1
295
296        if [ ! -e "${output}" ]; then
297          elog "Output file does not exist."
298          return 1
299        fi
300        rm "${output}"
301      done
302    done
303  fi
304}
305
306vpxenc_vp9_webm_rt_multithread_tiled_frameparallel() {
307  if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
308     [ "$(webm_io_available)" = "yes" ]; then
309    local output="${VPX_TEST_OUTPUT_DIR}/vp9_rt_mt_t_fp.webm"
310    local tilethread_min=2
311    local tilethread_max=4
312    local num_threads="$(seq ${tilethread_min} ${tilethread_max})"
313    local num_tile_cols="$(seq ${tilethread_min} ${tilethread_max})"
314
315    for threads in ${num_threads}; do
316      for tile_cols in ${num_tile_cols}; do
317        vpxenc $(y4m_input_720p) \
318          $(vpxenc_rt_params vp9) \
319          --threads=${threads} \
320          --tile-columns=${tile_cols} \
321          --frame-parallel=1 \
322          --output="${output}" || return 1
323
324        if [ ! -e "${output}" ]; then
325          elog "Output file does not exist."
326          return 1
327        fi
328        rm "${output}"
329      done
330    done
331  fi
332}
333
334vpxenc_vp9_webm_2pass() {
335  if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
336     [ "$(webm_io_available)" = "yes" ]; then
337    local output="${VPX_TEST_OUTPUT_DIR}/vp9.webm"
338    vpxenc $(yuv_input_hantro_collage) \
339      --codec=vp9 \
340      --limit="${TEST_FRAMES}" \
341      --output="${output}" \
342      --passes=2 || return 1
343
344    if [ ! -e "${output}" ]; then
345      elog "Output file does not exist."
346      return 1
347    fi
348  fi
349}
350
351vpxenc_vp9_ivf_lossless() {
352  if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
353    local output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless.ivf"
354    local passes=$(vpxenc_passes_param)
355    vpxenc $(yuv_input_hantro_collage) \
356      --codec=vp9 \
357      --limit="${TEST_FRAMES}" \
358      --ivf \
359      --output="${output}" \
360      "${passes}" \
361      --lossless=1 || return 1
362
363    if [ ! -e "${output}" ]; then
364      elog "Output file does not exist."
365      return 1
366    fi
367  fi
368}
369
370vpxenc_vp9_ivf_minq0_maxq0() {
371  if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
372    local output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless_minq0_maxq0.ivf"
373    local passes=$(vpxenc_passes_param)
374    vpxenc $(yuv_input_hantro_collage) \
375      --codec=vp9 \
376      --limit="${TEST_FRAMES}" \
377      --ivf \
378      --output="${output}" \
379      "${passes}" \
380      --min-q=0 \
381      --max-q=0 || return 1
382
383    if [ ! -e "${output}" ]; then
384      elog "Output file does not exist."
385      return 1
386    fi
387  fi
388}
389
390vpxenc_vp9_webm_lag10_frames20() {
391  if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
392     [ "$(webm_io_available)" = "yes" ]; then
393    local lag_total_frames=20
394    local lag_frames=10
395    local output="${VPX_TEST_OUTPUT_DIR}/vp9_lag10_frames20.webm"
396    local passes=$(vpxenc_passes_param)
397    vpxenc $(yuv_input_hantro_collage) \
398      --codec=vp9 \
399      --limit="${lag_total_frames}" \
400      --lag-in-frames="${lag_frames}" \
401      --output="${output}" \
402      "${passes}" \
403      --auto-alt-ref=1 || return 1
404
405    if [ ! -e "${output}" ]; then
406      elog "Output file does not exist."
407      return 1
408    fi
409  fi
410}
411
412# TODO(fgalligan): Test that DisplayWidth is different than video width.
413vpxenc_vp9_webm_non_square_par() {
414  if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
415     [ "$(webm_io_available)" = "yes" ]; then
416    local output="${VPX_TEST_OUTPUT_DIR}/vp9_non_square_par.webm"
417    local passes=$(vpxenc_passes_param)
418    vpxenc $(y4m_input_non_square_par) \
419      --codec=vp9 \
420      --limit="${TEST_FRAMES}" \
421      "${passes}" \
422      --output="${output}" || return 1
423
424    if [ ! -e "${output}" ]; then
425      elog "Output file does not exist."
426      return 1
427    fi
428  fi
429}
430
431vpxenc_vp9_webm_sharpness() {
432  if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
433    local sharpnesses="0 1 2 3 4 5 6 7"
434    local output="${VPX_TEST_OUTPUT_DIR}/vpxenc_vp9_webm_sharpness.ivf"
435    local last_size=0
436    local this_size=0
437
438    for sharpness in ${sharpnesses}; do
439
440      vpxenc $(yuv_input_hantro_collage) \
441        --sharpness="${sharpness}" \
442        --codec=vp9 \
443        --limit=1 \
444        --cpu-used=2 \
445        --end-usage=q \
446        --cq-level=40 \
447        --output="${output}" \
448        "${passes}" || return 1
449
450      if [ ! -e "${output}" ]; then
451        elog "Output file does not exist."
452        return 1
453      fi
454
455      this_size=$(stat -c '%s' "${output}")
456      if [ "${this_size}" -lt "${last_size}" ]; then
457        elog "Higher sharpness value yielded lower file size."
458        echo "${this_size}" " < " "${last_size}"
459        return 1
460      fi
461      last_size="${this_size}"
462
463    done
464  fi
465}
466
467vpxenc_tests="vpxenc_vp8_ivf
468              vpxenc_vp8_webm
469              vpxenc_vp8_webm_rt
470              vpxenc_vp8_ivf_piped_input
471              vpxenc_vp9_ivf
472              vpxenc_vp9_webm
473              vpxenc_vp9_webm_rt
474              vpxenc_vp9_webm_rt_multithread_tiled
475              vpxenc_vp9_webm_rt_multithread_tiled_frameparallel
476              vpxenc_vp9_ivf_lossless
477              vpxenc_vp9_ivf_minq0_maxq0
478              vpxenc_vp9_webm_lag10_frames20
479              vpxenc_vp9_webm_non_square_par
480              vpxenc_vp9_webm_sharpness"
481
482if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" != "yes" ]; then
483  vpxenc_tests="$vpxenc_tests
484                vpxenc_vp8_webm_2pass
485                vpxenc_vp8_webm_lag10_frames20
486                vpxenc_vp9_webm_2pass"
487fi
488
489run_tests vpxenc_verify_environment "${vpxenc_tests}"
490