vpxenc.sh 13 KB

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