firefox 126.0-0.b8.1 (znver1;x86_64;aarch64) 2024-17707
9999

Status published
Submitter rugyada [@T] gmail.com
Platform rolling
Repository main
URL https://abf.openmandriva.org/build_lists/418917
Packages
firefox-126.0-0.b8.1.znver1.source
firefox-126.0-0.b8.1.znver1.binary
firefox-af-126.0-0.b8.1.znver1.binary
firefox-ar-126.0-0.b8.1.znver1.binary
firefox-ast-126.0-0.b8.1.znver1.binary
firefox-bg-126.0-0.b8.1.znver1.binary
firefox-bn-126.0-0.b8.1.znver1.binary
firefox-br-126.0-0.b8.1.znver1.binary
firefox-bs-126.0-0.b8.1.znver1.binary
firefox-ca-126.0-0.b8.1.znver1.binary
firefox-cs-126.0-0.b8.1.znver1.binary
firefox-cy-126.0-0.b8.1.znver1.binary
firefox-da-126.0-0.b8.1.znver1.binary
firefox-de-126.0-0.b8.1.znver1.binary
firefox-debuginfo-126.0-0.b8.1.znver1.debuginfo
firefox-debugsource-126.0-0.b8.1.znver1.binary
firefox-devel-126.0-0.b8.1.znver1.binary
firefox-el-126.0-0.b8.1.znver1.binary
firefox-en_GB-126.0-0.b8.1.znver1.binary
firefox-eo-126.0-0.b8.1.znver1.binary
firefox-es_AR-126.0-0.b8.1.znver1.binary
firefox-es_CL-126.0-0.b8.1.znver1.binary
firefox-es_ES-126.0-0.b8.1.znver1.binary
firefox-es_MX-126.0-0.b8.1.znver1.binary
firefox-et-126.0-0.b8.1.znver1.binary
firefox-eu-126.0-0.b8.1.znver1.binary
firefox-fa-126.0-0.b8.1.znver1.binary
firefox-fi-126.0-0.b8.1.znver1.binary
firefox-fr-126.0-0.b8.1.znver1.binary
firefox-fy-126.0-0.b8.1.znver1.binary
firefox-ga_IE-126.0-0.b8.1.znver1.binary
firefox-gd-126.0-0.b8.1.znver1.binary
firefox-gl-126.0-0.b8.1.znver1.binary
firefox-gu_IN-126.0-0.b8.1.znver1.binary
firefox-he-126.0-0.b8.1.znver1.binary
firefox-hi-126.0-0.b8.1.znver1.binary
firefox-hr-126.0-0.b8.1.znver1.binary
firefox-hu-126.0-0.b8.1.znver1.binary
firefox-hy-126.0-0.b8.1.znver1.binary
firefox-id-126.0-0.b8.1.znver1.binary
firefox-is-126.0-0.b8.1.znver1.binary
firefox-it-126.0-0.b8.1.znver1.binary
firefox-ja-126.0-0.b8.1.znver1.binary
firefox-kk-126.0-0.b8.1.znver1.binary
firefox-km-126.0-0.b8.1.znver1.binary
firefox-kn-126.0-0.b8.1.znver1.binary
firefox-ko-126.0-0.b8.1.znver1.binary
firefox-lt-126.0-0.b8.1.znver1.binary
firefox-lv-126.0-0.b8.1.znver1.binary
firefox-mk-126.0-0.b8.1.znver1.binary
firefox-mr-126.0-0.b8.1.znver1.binary
firefox-nb_NO-126.0-0.b8.1.znver1.binary
firefox-nl-126.0-0.b8.1.znver1.binary
firefox-nn_NO-126.0-0.b8.1.znver1.binary
firefox-pa_IN-126.0-0.b8.1.znver1.binary
firefox-pl-126.0-0.b8.1.znver1.binary
firefox-pt_BR-126.0-0.b8.1.znver1.binary
firefox-pt_PT-126.0-0.b8.1.znver1.binary
firefox-ro-126.0-0.b8.1.znver1.binary
firefox-ru-126.0-0.b8.1.znver1.binary
firefox-si-126.0-0.b8.1.znver1.binary
firefox-sk-126.0-0.b8.1.znver1.binary
firefox-sl-126.0-0.b8.1.znver1.binary
firefox-sq-126.0-0.b8.1.znver1.binary
firefox-sr-126.0-0.b8.1.znver1.binary
firefox-sv_SE-126.0-0.b8.1.znver1.binary
firefox-ta-126.0-0.b8.1.znver1.binary
firefox-te-126.0-0.b8.1.znver1.binary
firefox-th-126.0-0.b8.1.znver1.binary
firefox-tr-126.0-0.b8.1.znver1.binary
firefox-uk-126.0-0.b8.1.znver1.binary
firefox-vi-126.0-0.b8.1.znver1.binary
firefox-zh_CN-126.0-0.b8.1.znver1.binary
firefox-zh_TW-126.0-0.b8.1.znver1.binary
firefox-126.0-0.b8.1.x86_64.binary
firefox-126.0-0.b8.1.x86_64.source
firefox-af-126.0-0.b8.1.x86_64.binary
firefox-ar-126.0-0.b8.1.x86_64.binary
firefox-ast-126.0-0.b8.1.x86_64.binary
firefox-bg-126.0-0.b8.1.x86_64.binary
firefox-bn-126.0-0.b8.1.x86_64.binary
firefox-br-126.0-0.b8.1.x86_64.binary
firefox-bs-126.0-0.b8.1.x86_64.binary
firefox-ca-126.0-0.b8.1.x86_64.binary
firefox-cs-126.0-0.b8.1.x86_64.binary
firefox-cy-126.0-0.b8.1.x86_64.binary
firefox-da-126.0-0.b8.1.x86_64.binary
firefox-de-126.0-0.b8.1.x86_64.binary
firefox-debuginfo-126.0-0.b8.1.x86_64.debuginfo
firefox-debugsource-126.0-0.b8.1.x86_64.binary
firefox-devel-126.0-0.b8.1.x86_64.binary
firefox-el-126.0-0.b8.1.x86_64.binary
firefox-en_GB-126.0-0.b8.1.x86_64.binary
firefox-eo-126.0-0.b8.1.x86_64.binary
firefox-es_AR-126.0-0.b8.1.x86_64.binary
firefox-es_CL-126.0-0.b8.1.x86_64.binary
firefox-es_ES-126.0-0.b8.1.x86_64.binary
firefox-es_MX-126.0-0.b8.1.x86_64.binary
firefox-et-126.0-0.b8.1.x86_64.binary
firefox-eu-126.0-0.b8.1.x86_64.binary
firefox-fa-126.0-0.b8.1.x86_64.binary
firefox-fi-126.0-0.b8.1.x86_64.binary
firefox-fr-126.0-0.b8.1.x86_64.binary
firefox-fy-126.0-0.b8.1.x86_64.binary
firefox-ga_IE-126.0-0.b8.1.x86_64.binary
firefox-gd-126.0-0.b8.1.x86_64.binary
firefox-gl-126.0-0.b8.1.x86_64.binary
firefox-gu_IN-126.0-0.b8.1.x86_64.binary
firefox-he-126.0-0.b8.1.x86_64.binary
firefox-hi-126.0-0.b8.1.x86_64.binary
firefox-hr-126.0-0.b8.1.x86_64.binary
firefox-hu-126.0-0.b8.1.x86_64.binary
firefox-hy-126.0-0.b8.1.x86_64.binary
firefox-id-126.0-0.b8.1.x86_64.binary
firefox-is-126.0-0.b8.1.x86_64.binary
firefox-it-126.0-0.b8.1.x86_64.binary
firefox-ja-126.0-0.b8.1.x86_64.binary
firefox-kk-126.0-0.b8.1.x86_64.binary
firefox-km-126.0-0.b8.1.x86_64.binary
firefox-kn-126.0-0.b8.1.x86_64.binary
firefox-ko-126.0-0.b8.1.x86_64.binary
firefox-lt-126.0-0.b8.1.x86_64.binary
firefox-lv-126.0-0.b8.1.x86_64.binary
firefox-mk-126.0-0.b8.1.x86_64.binary
firefox-mr-126.0-0.b8.1.x86_64.binary
firefox-nb_NO-126.0-0.b8.1.x86_64.binary
firefox-nl-126.0-0.b8.1.x86_64.binary
firefox-nn_NO-126.0-0.b8.1.x86_64.binary
firefox-pa_IN-126.0-0.b8.1.x86_64.binary
firefox-pl-126.0-0.b8.1.x86_64.binary
firefox-pt_BR-126.0-0.b8.1.x86_64.binary
firefox-pt_PT-126.0-0.b8.1.x86_64.binary
firefox-ro-126.0-0.b8.1.x86_64.binary
firefox-ru-126.0-0.b8.1.x86_64.binary
firefox-si-126.0-0.b8.1.x86_64.binary
firefox-sk-126.0-0.b8.1.x86_64.binary
firefox-sl-126.0-0.b8.1.x86_64.binary
firefox-sq-126.0-0.b8.1.x86_64.binary
firefox-sr-126.0-0.b8.1.x86_64.binary
firefox-sv_SE-126.0-0.b8.1.x86_64.binary
firefox-ta-126.0-0.b8.1.x86_64.binary
firefox-te-126.0-0.b8.1.x86_64.binary
firefox-th-126.0-0.b8.1.x86_64.binary
firefox-tr-126.0-0.b8.1.x86_64.binary
firefox-uk-126.0-0.b8.1.x86_64.binary
firefox-vi-126.0-0.b8.1.x86_64.binary
firefox-zh_CN-126.0-0.b8.1.x86_64.binary
firefox-zh_TW-126.0-0.b8.1.x86_64.binary
firefox-126.0-0.b8.1.aarch64.source
firefox-126.0-0.b8.1.aarch64.binary
firefox-af-126.0-0.b8.1.aarch64.binary
firefox-ar-126.0-0.b8.1.aarch64.binary
firefox-ast-126.0-0.b8.1.aarch64.binary
firefox-bg-126.0-0.b8.1.aarch64.binary
firefox-bn-126.0-0.b8.1.aarch64.binary
firefox-br-126.0-0.b8.1.aarch64.binary
firefox-bs-126.0-0.b8.1.aarch64.binary
firefox-ca-126.0-0.b8.1.aarch64.binary
firefox-cs-126.0-0.b8.1.aarch64.binary
firefox-cy-126.0-0.b8.1.aarch64.binary
firefox-da-126.0-0.b8.1.aarch64.binary
firefox-de-126.0-0.b8.1.aarch64.binary
firefox-debuginfo-126.0-0.b8.1.aarch64.debuginfo
firefox-debugsource-126.0-0.b8.1.aarch64.binary
firefox-devel-126.0-0.b8.1.aarch64.binary
firefox-el-126.0-0.b8.1.aarch64.binary
firefox-en_GB-126.0-0.b8.1.aarch64.binary
firefox-eo-126.0-0.b8.1.aarch64.binary
firefox-es_AR-126.0-0.b8.1.aarch64.binary
firefox-es_CL-126.0-0.b8.1.aarch64.binary
firefox-es_ES-126.0-0.b8.1.aarch64.binary
firefox-es_MX-126.0-0.b8.1.aarch64.binary
firefox-et-126.0-0.b8.1.aarch64.binary
firefox-eu-126.0-0.b8.1.aarch64.binary
firefox-fa-126.0-0.b8.1.aarch64.binary
firefox-fi-126.0-0.b8.1.aarch64.binary
firefox-fr-126.0-0.b8.1.aarch64.binary
firefox-fy-126.0-0.b8.1.aarch64.binary
firefox-ga_IE-126.0-0.b8.1.aarch64.binary
firefox-gd-126.0-0.b8.1.aarch64.binary
firefox-gl-126.0-0.b8.1.aarch64.binary
firefox-gu_IN-126.0-0.b8.1.aarch64.binary
firefox-he-126.0-0.b8.1.aarch64.binary
firefox-hi-126.0-0.b8.1.aarch64.binary
firefox-hr-126.0-0.b8.1.aarch64.binary
firefox-hu-126.0-0.b8.1.aarch64.binary
firefox-hy-126.0-0.b8.1.aarch64.binary
firefox-id-126.0-0.b8.1.aarch64.binary
firefox-is-126.0-0.b8.1.aarch64.binary
firefox-it-126.0-0.b8.1.aarch64.binary
firefox-ja-126.0-0.b8.1.aarch64.binary
firefox-kk-126.0-0.b8.1.aarch64.binary
firefox-km-126.0-0.b8.1.aarch64.binary
firefox-kn-126.0-0.b8.1.aarch64.binary
firefox-ko-126.0-0.b8.1.aarch64.binary
firefox-lt-126.0-0.b8.1.aarch64.binary
firefox-lv-126.0-0.b8.1.aarch64.binary
firefox-mk-126.0-0.b8.1.aarch64.binary
firefox-mr-126.0-0.b8.1.aarch64.binary
firefox-nb_NO-126.0-0.b8.1.aarch64.binary
firefox-nl-126.0-0.b8.1.aarch64.binary
firefox-nn_NO-126.0-0.b8.1.aarch64.binary
firefox-pa_IN-126.0-0.b8.1.aarch64.binary
firefox-pl-126.0-0.b8.1.aarch64.binary
firefox-pt_BR-126.0-0.b8.1.aarch64.binary
firefox-pt_PT-126.0-0.b8.1.aarch64.binary
firefox-ro-126.0-0.b8.1.aarch64.binary
firefox-ru-126.0-0.b8.1.aarch64.binary
firefox-si-126.0-0.b8.1.aarch64.binary
firefox-sk-126.0-0.b8.1.aarch64.binary
firefox-sl-126.0-0.b8.1.aarch64.binary
firefox-sq-126.0-0.b8.1.aarch64.binary
firefox-sr-126.0-0.b8.1.aarch64.binary
firefox-sv_SE-126.0-0.b8.1.aarch64.binary
firefox-ta-126.0-0.b8.1.aarch64.binary
firefox-te-126.0-0.b8.1.aarch64.binary
firefox-th-126.0-0.b8.1.aarch64.binary
firefox-tr-126.0-0.b8.1.aarch64.binary
firefox-uk-126.0-0.b8.1.aarch64.binary
firefox-vi-126.0-0.b8.1.aarch64.binary
firefox-zh_CN-126.0-0.b8.1.aarch64.binary
firefox-zh_TW-126.0-0.b8.1.aarch64.binary
Build Date 2024-05-02 14:41:56 +0000 UTC
Last Updated 2024-05-03 19:50:00.307318215 +0000 UTC
$ git diff --patch-with-stat --summary 14ca66b8029a7a9596044c5b73429e99b947f05c..11417f83c6853da992973dca25047b7b4e6a747d

 .abf.yml                  |   141 +-
 05d7a7c92cf2.patch        |   903 ++
 5759fe6ed8a5.patch        | 20606 ++++++++++++++++++++++++++++++++++++++++++++
 5970587d9a7a.patch        | 15072 ++++++++++++++++++++++++++++++++
 d55beebe2605.patch        |    33 +
 download.sh               |     3 +
 fb10bab6cd18.patch        |   187 +
 firefox.spec              |    20 +-
 mozilla-107.0.1-kde.patch |   175 +-
 mozilla-1890593.patch     |    17 -
 10 files changed, 36980 insertions(+), 177 deletions(-)
 create mode 100644 05d7a7c92cf2.patch
 create mode 100644 5759fe6ed8a5.patch
 create mode 100644 5970587d9a7a.patch
 create mode 100644 d55beebe2605.patch
 create mode 100644 fb10bab6cd18.patch
 delete mode 100644 mozilla-1890593.patch

diff --git a/.abf.yml b/.abf.yml
index 35e4b50..181cc2d 100644
--- a/.abf.yml
+++ b/.abf.yml
@@ -1,71 +1,72 @@
 sources:
-  af.xpi: 614f71e4c0a8c51c3973d851f530c33f2a5812a4
-  ar.xpi: 1205b18c6eaadc6db32f338cb4d18613b1571949
-  ast.xpi: f45e925716d8385eb76e1d0cae0dab31ccae4aa4
-  bg.xpi: 6035200b9e69bbe44b6864bffa0e52d3ba9012cf
-  bn.xpi: af0382e68d66b88567e76d2c25b0edf9382399bc
-  br.xpi: bb757fd59df926bba4aed75c3f9d4d1e46eae992
-  bs.xpi: 68332fd34229cc4312b5c012121e79e35cbc94ba
-  ca.xpi: 0666710faeba68359d01d9c542b9a4cae5271b4e
-  cs.xpi: fa432a7fa2daf68e1ffda9547634c5302c60fe60
-  cy.xpi: d3a161f62b4469f16999678be8480951eeefde10
-  da.xpi: c8059f22f06482ba644ad39e13b654429eea99c4
-  de.xpi: 1ed21e35eab4991678083d1bf660a2f825cb6005
-  el.xpi: 18fef566d93719ad09172ffc4dfd66306b7b1d96
-  en-GB.xpi: c0e01184d2a81206864c399bea8c005e061bfb87
-  eo.xpi: 9acd5f90d81c7d847ce26694dab4223b6dc26c68
-  es-AR.xpi: 976fa487bf65a4c94f5b48589049a0ba392688ce
-  es-CL.xpi: 1792369a4ae4d6e9b8b3c903b78a62a646f16f3e
-  es-ES.xpi: 521220f86640c2e2eabcd9a2a1efe652d715b39a
-  es-MX.xpi: 2ea04cef7fadb3a50af5221185fdeadee1427eb7
-  et.xpi: 98539381399e085c1143c55644f98b69f90d953d
-  eu.xpi: b3813c7a3411f77437b13014f52596b1dde53165
-  fa.xpi: 60d852c3e196a2e6bd4c0ee0f267afe786975a97
-  fi.xpi: b169ec2aa126ed9d042128510abf3777fbb55ec7
-  firefox-125.0.2.source.tar.xz: 859c79a352f7faa31dd1fda7c950b223a97ec637
-  fr.xpi: 472207747fec5fb27cd60653570cc429c3e407f0
-  fy-NL.xpi: 67b4c8c705fe4362fdd8c4442b787212f31bbaed
-  ga-IE.xpi: b850ae9e14cdfbefbdbacb5ace53007f309021a5
-  gd.xpi: 121f2aabcec11caf9090176d46ea7709312877a9
-  gl.xpi: dbb2f04baad07e1f2b44aa2b5b3fef0d21df0784
-  gu-IN.xpi: 4e24c042f052bddee946169eec2e4b4da79d9a2a
-  he.xpi: 3f6b7f14aea60a29ec1de7b4f53da50f6470cdd3
-  hi-IN.xpi: e59fa425aa07755c7fab25a721f19e9c776422b3
-  hr.xpi: 2fb6740328df56b1db6d4250a20675ba3402a811
-  hu.xpi: 5e27ba728c7bc24ee225958623c27e369dd93f81
-  hy-AM.xpi: 9eba60438dc7b49f03cc210fd37468e2c32cc597
-  id.xpi: 6579b4afe18d434ee404d1d04fdab50cc091a0b4
-  is.xpi: d1163cb3eed5b84c2567851aaa97f4f7ec8acc31
-  it.xpi: 3bf63f690bbe43c20a527a79be5710b39dca47ff
-  ja.xpi: 6ba04132fe8e79f089e7f8e1350704afb2c2cf96
-  kk.xpi: 1ea48782aba9ec7a0122420418f13775892bd524
-  km.xpi: 4a15e1e2c9ffacf9f9214a9137896a2f0565d571
-  kn.xpi: cd1aa6a802dab4c6cb9b107a908540bc3bfd598b
-  ko.xpi: 2a4774227f1f92cf07bf21ac93107c002a35e2af
-  lt.xpi: 3113f41aa94c57e4ce284d9eb7cec3cfef9a6426
-  lv.xpi: 25851463b4210e41ec426afd15365496e31d4902
-  mk.xpi: 00ac9c7ccfd981cde6171135743f45a6bc63102d
-  mr.xpi: 0144ffc444f6aff7faa7a5289fd2fcf93169103d
-  nb-NO.xpi: c055c3a09a720dbbb87035f0b71854a8c4f68cd2
-  nl.xpi: b84d6257ba43732d58b98c3dd247751fd2ffccb0
-  nn-NO.xpi: 429de262785b7216a72b400d6baf2ea0190512bd
-  pa-IN.xpi: 9633df1067fdaf76f9495e5986a1bb6c3341af9f
-  pl.xpi: bed3a4751b58d4a9600a97def7e99311c8359ef1
-  pt-BR.xpi: 83022d45442905ac42789d423af71f528b913e4f
-  pt-PT.xpi: 27704b3dd62052b57fae11b9c06d38b56588756b
-  ro.xpi: bd5c3a17da7314f04ad402d5b07ac1bcc3b7b175
-  ru.xpi: 2522a1ec4bfb2de41701b95659e65e6d2cdc8fe2
-  si.xpi: d4e74bfc2733112207ee6d6e52e19609f25da489
-  sk.xpi: 4175c4c31115c4e7e11d9daa9cb369eb5e146e25
-  sl.xpi: 854b364b6b76e54bd91d265ddd7bf0fe03d713c0
-  sq.xpi: 51d46e315cc8a7d72a911c62e8b1bb5b6ba8dc4e
-  sr.xpi: 4056db70420c8c37936dcb9e147cfb814005f740
-  sv-SE.xpi: b7b228e4d382138d49934d6e135431564325f24c
-  ta.xpi: 9bf4d60c4f75166faf1fba40116432ab1204e67b
-  te.xpi: 315147c9adea8fb6668c273a6561fba81700ad46
-  th.xpi: 1b82320f647a734fe7d875ae77fc1a1d035ac1d1
-  tr.xpi: b02bf157541da689f463673ff83cb26e37f37084
-  uk.xpi: 637351160b10bfe2cb180dae20d196ec4f8e104d
-  vi.xpi: 45ebdb5a4168a4d65084df07bd79fd5c0c8c0672
-  zh-CN.xpi: 20608b30615f9cf461082a2d55df46eb0d5e8b0d
-  zh-TW.xpi: e49f4da19d128b3d6f92e29092cca6b1f4947812
+  af.xpi: dca59c402e152a304bbf20141acc963b49a91c02
+  ar.xpi: ff8621af713a1cc1a26aa1ce023e905e36a6d259
+  ast.xpi: e2a065e9004a11fc1958d1ff53f985eccb7813db
+  be.xpi: 6eff4e3c1edeee5600f3bd4882d2ce5b02864aaf
+  bg.xpi: 7d665fbfc51141e59dd2cbf92537c8cbc00f5cbd
+  bn.xpi: e8927122ae74296753579748d3968f68b4546135
+  br.xpi: ae18830f021e2e08ada5877b27a1dd477f2b15df
+  bs.xpi: 440ecf37be0402d84e4e9502464a4d3c00f314fa
+  ca.xpi: 3f8c11f1d5f173b005f7c801c77dfe69a8016b21
+  cs.xpi: 5a238297ad41a44e09a0e6211bebf3e5e09c70d1
+  cy.xpi: cd56ecaeef4ed10314347e0acbcda53696d1dfbf
+  da.xpi: b3ecd535d9ac4ab80f2907097049100c2e86ad9e
+  de.xpi: 1fa2ef7e15435e3020326321e8e056c6fc6816c5
+  el.xpi: 227c31c589ccf5c63464f5be1c904703d13e7813
+  en-GB.xpi: 777e5682e8219323f33a9dd347013fe98b4f0c30
+  eo.xpi: cbc2bc848a2fd080c96c7156cfe81e2552a45ff3
+  es-AR.xpi: 0d387f4f7774d33498c7e0356e5cbbd4edf2df9f
+  es-CL.xpi: 8ff7a6b724aa83b9d7bad849f342f332e0f4ae50
+  es-ES.xpi: ee205515cd954bfa2d93477edf2e68160b6651cb
+  es-MX.xpi: 12e48aee7f9807ee2df4763fced81b7c4f464cc6
+  et.xpi: 17fb4a3f3a6ef35f9468c0518819614d0ace84f5
+  eu.xpi: eb7e45c12e26ed928250c0ce8ddfceff362728e4
+  fa.xpi: 4436efbea1606628a95de21db761811c2ce859f5
+  fi.xpi: 1547e6feb4078e5c6f710331ae5ecdad5c3922e4
+  firefox-126.0b8.source.tar.xz: f33b7eaacf4380fc38bcbce23092d497bdfb25e4
+  fr.xpi: 8f0d61fdd3eb6f2bc1bc8d74489e04d36d26462a
+  fy-NL.xpi: ff2484c0e7866bb013a4080c9de64a33294ae52b
+  ga-IE.xpi: c886f2e01e25a36f8068cf1f155d0ee61f56a0a0
+  gd.xpi: 95d819d62e0914d1beda6473f6b275b0f70fafad
+  gl.xpi: 9aead0093cf0ed80f9e9e06aee2d63d4ae529bfe
+  gu-IN.xpi: 7a1319f9447df551c413c814cd3057e6e3bfb574
+  he.xpi: 89c6c525510d704da7541349a6532dd6479a156d
+  hi-IN.xpi: dd16145e76e4e41053e62c67c91c05b7d12f6a11
+  hr.xpi: 363ec34d95c222057f1125d93ec89985240152db
+  hu.xpi: 6af46dc9eabdf17e62b730d964f3004c8967a390
+  hy-AM.xpi: ff12cd29bb25e326e207220adc8f13cacd868467
+  id.xpi: de69997f835f7a2cf43a5ed7a0d101ee95e18de4
+  is.xpi: 6a256a93fd61ef9eac3b874cac229e6009a026ec
+  it.xpi: 154e3b61ca9234cf6556326cbbf4d9b2182ae162
+  ja.xpi: cdb2a0ff17a8e92e299ba281b3dcab907a175393
+  kk.xpi: 91659297f768b263fbabb8e81ff030507a02fadc
+  km.xpi: fc0aa770890911e70d560d292c2c78693fe341d3
+  kn.xpi: 85004774258c6593836485f2ca24b712428cb406
+  ko.xpi: cfb050e4d25e2dbcc1c3cf24d728246692328651
+  lt.xpi: 9dcaa82b67fb76c8db5a2e260f2dcfbb1cda98ee
+  lv.xpi: 327c7c3127d6ef71b95310951a81f8d8c20fb1ec
+  mk.xpi: 1a8fc90e4feb7aad3a6ca8d3bea2ce251fb948ca
+  mr.xpi: 8738608b9d8508c3b51704aa0b0a29c722c809c5
+  nb-NO.xpi: 175f0e80165b33589276ae7b974151238ee117fa
+  nl.xpi: 4da16bf3faafb6a76d0d22e320962dd2276aa74d
+  nn-NO.xpi: 30c6999388523cbde13447f980a04f4d66331701
+  pa-IN.xpi: 5dcc29d491ac38b62a5d15ad1483f22fc957bd97
+  pl.xpi: 182e518a85a6aa78eb321a29c2a0d97914a68bbf
+  pt-BR.xpi: 5ed6d50c373730edb942e61f822d01bfef82d28c
+  pt-PT.xpi: 6c50c7455760af0976bdd7735718624e2801792a
+  ro.xpi: 90456d22b894b16caae7a3c70a20ed8e15a9469a
+  ru.xpi: 5ea1b7a4c05b31cba734291d33762d6fffcda05d
+  si.xpi: 913d169bb6d0503b3c5022075f7cebafe2dd86e9
+  sk.xpi: 9382bac3b0ba60291ec0d2de5bb48838fc94ce04
+  sl.xpi: 8e2c99450977ff2dc180565b82e6d32782cea28a
+  sq.xpi: 126652f778721f3533f4dee937caded2c4fab29b
+  sr.xpi: ec33d2fedbf901b72c14c69118f44e93ff49dbbf
+  sv-SE.xpi: 0b70d59e30af73e13fdbfe5fcdbe42f42f1c8072
+  ta.xpi: 2a456f2f9bebf3abd7a32b0d351a0e60dbc4277f
+  te.xpi: 49154e19815e9fe0d762d5d7c614a65e8988ddad
+  th.xpi: 6aa935b6dd176784acecd0d8ac24dd6a4334c250
+  tr.xpi: 6b49294013ad9a5f11b98435ddaa7172c055245b
+  uk.xpi: debfd662ea69daed5797fe524390e86c2c603c74
+  vi.xpi: 7eaeed6ea13072cb461c5ee58884a396bfd2bc8a
+  zh-CN.xpi: e2c2464c5d6b85efd38357a942de4df763d1ceda
+  zh-TW.xpi: cda8d7e81ca5e645560f94199f60bb1410b540f6
diff --git a/05d7a7c92cf2.patch b/05d7a7c92cf2.patch
new file mode 100644
index 0000000..93f7c49
--- /dev/null
+++ b/05d7a7c92cf2.patch
@@ -0,0 +1,903 @@
+
+# HG changeset patch
+# User Paul Adenot <paul@paul.cx>
+# Date 1714486906 0
+# Node ID 05d7a7c92cf24c6b47bf84a693c71a507b312f3c
+# Parent  5759fe6ed8a53b22ffac43c073687e127c07b0f7
+Bug 1889978 - Make all files using the FFmpeg API compatible with ffmpeg 7.0. r=media-playback-reviewers,alwu
+
+AVCodecContext.channels doesn't exist anymore.
+AVCodecContext.ch_layout.nb_channels is the equivalent.
+
+AVFrame.channels also has switched to .ch_layout.nb_channels.
+
+AVFrame.pkt_duration has switched to .duration (same meaning)
+
+AVPacket can't be allocated on the stack, it's size isn't part of the ABI. It
+needs to be allocated via av_packet_alloc, and freed using av_packet_free.
+
+
+AVCodecContext.reordered_opaque doesn't exist anymore, we don't really need it.
+
+Differential Revision: https://phabricator.services.mozilla.com/D206924
+
+diff --git a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
+@@ -1,15 +1,16 @@
+ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+ /* vim:set ts=2 sw=2 sts=2 et cindent: */
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #include "FFmpegAudioDecoder.h"
++#include "FFmpegUtils.h"
+ #include "AudioSampleFormat.h"
+ #include "FFmpegLog.h"
+ #include "TimeUnits.h"
+ #include "VideoUtils.h"
+ #include "BufferReader.h"
+ #include "libavutil/dict.h"
+ #include "libavutil/samplefmt.h"
+ #if defined(FFVPX_VERSION)
+@@ -245,17 +246,17 @@ MediaResult FFmpegAudioDecoder<LIBAV_VER
+   }
+ 
+   FFMPEG_LOG("FFmpegAudioDecoder decoded: [%s,%s] (Duration: %s) [%s]",
+              aSample->mTime.ToString().get(),
+              aSample->GetEndTime().ToString().get(),
+              aSample->mDuration.ToString().get(),
+              mLib->av_get_sample_fmt_name(mFrame->format));
+ 
+-  uint32_t numChannels = mCodecContext->channels;
++  uint32_t numChannels = ChannelCount(mCodecContext);
+   uint32_t samplingRate = mCodecContext->sample_rate;
+   if (!numChannels) {
+     numChannels = mAudioInfo.mChannels;
+   }
+   if (!samplingRate) {
+     samplingRate = mAudioInfo.mRate;
+   }
+   AlignedAudioBuffer audio =
+@@ -279,17 +280,17 @@ MediaResult FFmpegAudioDecoder<LIBAV_VER
+                duration.ToSeconds());
+     return MediaResult(
+         NS_ERROR_DOM_MEDIA_OVERFLOW_ERR,
+         RESULT_DETAIL("Invalid count of accumulated audio samples"));
+   }
+ 
+   RefPtr<AudioData> data =
+       new AudioData(aSample->mOffset, pts, std::move(audio), numChannels,
+-                    samplingRate, mCodecContext->channel_layout);
++                    samplingRate, numChannels);
+   MOZ_ASSERT(duration == data->mDuration, "must be equal");
+   aResults.AppendElement(std::move(data));
+ 
+   pts = newpts;
+ 
+   if (aGotFrame) {
+     *aGotFrame = true;
+   }
+@@ -390,41 +391,50 @@ MediaResult FFmpegAudioDecoder<LIBAV_VER
+ #endif
+ 
+ MediaResult FFmpegAudioDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
+                                                     uint8_t* aData, int aSize,
+                                                     bool* aGotFrame,
+                                                     DecodedData& aResults) {
+   MOZ_ASSERT(mTaskQueue->IsOnCurrentThread());
+   PROCESS_DECODE_LOG(aSample);
+-  AVPacket packet;
+-  mLib->av_init_packet(&packet);
++  AVPacket* packet;
++#if LIBAVCODEC_VERSION_MAJOR >= 61
++  packet = mLib->av_packet_alloc();
++  auto freePacket =
++    MakeScopeExit([&] { mLib->av_packet_free(&packet); });
++#else
++  AVPacket packet_mem;
++  packet = &packet_mem;
++  mLib->av_init_packet(packet);
++#endif
+ 
+   FFMPEG_LOG("FFmpegAudioDecoder::DoDecode: %d bytes, [%s,%s] (Duration: %s)",
+              aSize, aSample->mTime.ToString().get(),
+              aSample->GetEndTime().ToString().get(),
+              aSample->mDuration.ToString().get());
+ 
+-  packet.data = const_cast<uint8_t*>(aData);
+-  packet.size = aSize;
++  packet->data = const_cast<uint8_t*>(aData);
++  packet->size = aSize;
+ 
+   if (aGotFrame) {
+     *aGotFrame = false;
+   }
+ 
+   if (!PrepareFrame()) {
+     FFMPEG_LOG("FFmpegAudioDecoder: OOM in PrepareFrame");
+     return MediaResult(
+         NS_ERROR_OUT_OF_MEMORY,
+         RESULT_DETAIL("FFmpeg audio decoder failed to allocate frame"));
+   }
+ 
+   bool decoded = false;
+-  auto rv = DecodeUsingFFmpeg(&packet, decoded, aSample, aResults, aGotFrame);
++  auto rv = DecodeUsingFFmpeg(packet, decoded, aSample, aResults, aGotFrame);
+   NS_ENSURE_SUCCESS(rv, rv);
++
+   return NS_OK;
+ }
+ 
+ AVCodecID FFmpegAudioDecoder<LIBAV_VER>::GetCodecId(const nsACString& aMimeType,
+                                                     const AudioInfo& aInfo) {
+   if (aMimeType.EqualsLiteral("audio/mp4a-latm")) {
+     return AV_CODEC_ID_AAC;
+   }
+diff --git a/dom/media/platforms/ffmpeg/FFmpegAudioEncoder.cpp b/dom/media/platforms/ffmpeg/FFmpegAudioEncoder.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegAudioEncoder.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegAudioEncoder.cpp
+@@ -96,22 +96,23 @@ nsresult FFmpegAudioEncoder<LIBAV_VER>::
+       FFMPEG_LOG(
+           "Error creating resampler in FFmpegAudioEncoder %dHz -> %dHz (%dch)",
+           mInputSampleRate, mConfig.mSampleRate, mConfig.mNumberOfChannels);
+     }
+   }
+ 
+   // And now the audio-specific part
+   mCodecContext->sample_rate = AssertedCast<int>(mConfig.mSampleRate);
+-  mCodecContext->channels = AssertedCast<int>(mConfig.mNumberOfChannels);
+ 
+ #if LIBAVCODEC_VERSION_MAJOR >= 60
+   // Gecko's ordering intentionnally matches ffmepg's ordering
+   mLib->av_channel_layout_default(&mCodecContext->ch_layout,
+-                                  AssertedCast<int>(mCodecContext->channels));
++                                  AssertedCast<int>(mConfig.mNumberOfChannels));
++#else
++  mCodecContext->channels = AssertedCast<int>(mConfig.mNumberOfChannels);
+ #endif
+ 
+   switch (mConfig.mCodec) {
+     case CodecType::Opus:
+       // When using libopus, ffmpeg supports interleaved float and s16 input.
+       mCodecContext->sample_fmt = AV_SAMPLE_FMT_FLT;
+       break;
+     case CodecType::Vorbis:
+@@ -201,17 +202,17 @@ FFmpegAudioEncoder<LIBAV_VER>::EncodeOne
+   }
+ 
+   uint32_t frameCount = aSamples.Length() / mConfig.mNumberOfChannels;
+ 
+   // This method assumes that the audio has been packetized appropriately --
+   // packets smaller than the packet size are allowed when draining.
+   MOZ_ASSERT(AssertedCast<int>(frameCount) <= mCodecContext->frame_size);
+ 
+-  mFrame->channels = AssertedCast<int>(mConfig.mNumberOfChannels);
++  ChannelCount(mFrame) = AssertedCast<int>(mConfig.mNumberOfChannels);
+ 
+ #  if LIBAVCODEC_VERSION_MAJOR >= 60
+   int rv = mLib->av_channel_layout_copy(&mFrame->ch_layout,
+                                         &mCodecContext->ch_layout);
+   if (rv < 0) {
+     FFMPEG_LOG("channel layout copy error: %s",
+                MakeErrorString(mLib, rv).get());
+     return Err(NS_ERROR_DOM_MEDIA_FATAL_ERR);
+@@ -224,20 +225,20 @@ FFmpegAudioEncoder<LIBAV_VER>::EncodeOne
+   // Audio is converted below if needed
+   mFrame->format = mCodecContext->sample_fmt;
+   // Set presentation timestamp and duration of the AVFrame.
+ #  if LIBAVCODEC_VERSION_MAJOR >= 59
+   mFrame->time_base =
+       AVRational{.num = 1, .den = static_cast<int>(mConfig.mSampleRate)};
+ #  endif
+   mFrame->pts = aPts.ToTicksAtRate(mConfig.mSampleRate);
+-  mFrame->pkt_duration = frameCount;
+ #  if LIBAVCODEC_VERSION_MAJOR >= 60
+   mFrame->duration = frameCount;
+ #  else
++  mFrame->pkt_duration = frameCount;
+   // Save duration in the time_base unit.
+   mDurationMap.Insert(mFrame->pts, mFrame->pkt_duration);
+ #  endif
+ 
+   if (int ret = mLib->av_frame_get_buffer(mFrame, 16); ret < 0) {
+     FFMPEG_LOG("failed to allocate frame data: %s",
+                MakeErrorString(mLib, ret).get());
+     return Err(NS_ERROR_OUT_OF_MEMORY);
+@@ -253,17 +254,17 @@ FFmpegAudioEncoder<LIBAV_VER>::EncodeOne
+   // The input is always in f32 interleaved for now
+   if (mCodecContext->sample_fmt == AV_SAMPLE_FMT_FLT) {
+     PodCopy(reinterpret_cast<float*>(mFrame->data[0]), aSamples.data(),
+             aSamples.Length());
+   } else {
+     MOZ_ASSERT(mCodecContext->sample_fmt == AV_SAMPLE_FMT_FLTP);
+     for (uint32_t i = 0; i < mConfig.mNumberOfChannels; i++) {
+       DeinterleaveAndConvertBuffer(aSamples.data(), mFrame->nb_samples,
+-                                   mFrame->channels, mFrame->data);
++                                   mConfig.mNumberOfChannels, mFrame->data);
+     }
+   }
+ 
+   // Now send the AVFrame to ffmpeg for encoding, same code for audio and video.
+   return FFmpegDataEncoder<LIBAV_VER>::EncodeWithModernAPIs();
+ }
+ 
+ Result<MediaDataEncoder::EncodedData, nsresult> FFmpegAudioEncoder<
+diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
+@@ -64,26 +64,29 @@ FFmpegLibWrapper::LinkResult FFmpegLibWr
+     AV_FUNC_53 = 1 << 0,
+     AV_FUNC_54 = 1 << 1,
+     AV_FUNC_55 = 1 << 2,
+     AV_FUNC_56 = 1 << 3,
+     AV_FUNC_57 = 1 << 4,
+     AV_FUNC_58 = 1 << 5,
+     AV_FUNC_59 = 1 << 6,
+     AV_FUNC_60 = 1 << 7,
++    AV_FUNC_61 = 1 << 7,
+     AV_FUNC_AVUTIL_53 = AV_FUNC_53 | AV_FUNC_AVUTIL_MASK,
+     AV_FUNC_AVUTIL_54 = AV_FUNC_54 | AV_FUNC_AVUTIL_MASK,
+     AV_FUNC_AVUTIL_55 = AV_FUNC_55 | AV_FUNC_AVUTIL_MASK,
+     AV_FUNC_AVUTIL_56 = AV_FUNC_56 | AV_FUNC_AVUTIL_MASK,
+     AV_FUNC_AVUTIL_57 = AV_FUNC_57 | AV_FUNC_AVUTIL_MASK,
+     AV_FUNC_AVUTIL_58 = AV_FUNC_58 | AV_FUNC_AVUTIL_MASK,
+     AV_FUNC_AVUTIL_59 = AV_FUNC_59 | AV_FUNC_AVUTIL_MASK,
+     AV_FUNC_AVUTIL_60 = AV_FUNC_60 | AV_FUNC_AVUTIL_MASK,
++    AV_FUNC_AVUTIL_61 = AV_FUNC_61 | AV_FUNC_AVUTIL_MASK,
+     AV_FUNC_AVCODEC_ALL = AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | AV_FUNC_56 |
+-                          AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60,
++                          AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 |
++                          AV_FUNC_61,
+     AV_FUNC_AVUTIL_ALL = AV_FUNC_AVCODEC_ALL | AV_FUNC_AVUTIL_MASK
+   };
+ 
+   switch (macro) {
+     case 53:
+       version = AV_FUNC_53;
+       break;
+     case 54:
+@@ -102,16 +105,19 @@ FFmpegLibWrapper::LinkResult FFmpegLibWr
+       version = AV_FUNC_58;
+       break;
+     case 59:
+       version = AV_FUNC_59;
+       break;
+     case 60:
+       version = AV_FUNC_60;
+       break;
++    case 61:
++      version = AV_FUNC_61;
++      break;
+     default:
+       FFMPEGV_LOG("Unknown avcodec version: %d", macro);
+       Unlink();
+       return isFFMpeg ? ((macro > 57) ? LinkResult::UnknownFutureFFMpegVersion
+                                       : LinkResult::UnknownOlderFFMpegVersion)
+                       // All LibAV versions<54.35.1 are blocked, therefore we
+                       // must be dealing with a later one.
+                       : LinkResult::UnknownFutureLibAVVersion;
+@@ -148,116 +154,137 @@ FFmpegLibWrapper::LinkResult FFmpegLibWr
+                                    AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58)
+   AV_FUNC(avcodec_alloc_context3, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(avcodec_close, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(avcodec_decode_audio4, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 |
+                                      AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58)
+   AV_FUNC(avcodec_decode_video2, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 |
+                                      AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58)
+   AV_FUNC(avcodec_find_decoder, AV_FUNC_AVCODEC_ALL)
+-  AV_FUNC(avcodec_find_decoder_by_name, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++  AV_FUNC(avcodec_find_decoder_by_name,
++          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC(avcodec_find_encoder, AV_FUNC_AVCODEC_ALL)
+-  AV_FUNC(avcodec_find_encoder_by_name, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++  AV_FUNC(avcodec_find_encoder_by_name,
++          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC(avcodec_flush_buffers, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(avcodec_open2, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(avcodec_register_all, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 |
+                                     AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58)
+-  AV_FUNC(av_init_packet, AV_FUNC_AVCODEC_ALL)
++  AV_FUNC(av_init_packet, (AV_FUNC_55 | AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58 |
++                              AV_FUNC_59 | AV_FUNC_60))
+   AV_FUNC(av_parser_init, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(av_parser_close, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(av_parser_parse2, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(avcodec_align_dimensions, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(avcodec_alloc_frame, (AV_FUNC_53 | AV_FUNC_54))
+   AV_FUNC(avcodec_get_frame_defaults, (AV_FUNC_53 | AV_FUNC_54))
+   AV_FUNC(avcodec_free_frame, AV_FUNC_54)
+-  AV_FUNC(avcodec_send_packet, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC(avcodec_receive_packet, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC(avcodec_send_frame, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC(avcodec_receive_frame, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC(avcodec_default_get_buffer2, (AV_FUNC_55 | AV_FUNC_56 | AV_FUNC_57 |
+-                                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60))
+-  AV_FUNC(av_packet_alloc, (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60))
+-  AV_FUNC(av_packet_unref, (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60))
+-  AV_FUNC(av_packet_free, (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60))
++  AV_FUNC(avcodec_send_packet,
++          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
++  AV_FUNC(avcodec_receive_packet,
++          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
++  AV_FUNC(avcodec_send_frame, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
++  AV_FUNC(avcodec_receive_frame,
++          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
++  AV_FUNC(avcodec_default_get_buffer2,
++          (AV_FUNC_55 | AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 |
++           AV_FUNC_60 | AV_FUNC_61))
++  AV_FUNC(av_packet_alloc,
++          (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61))
++  AV_FUNC(av_packet_unref,
++          (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61))
++  AV_FUNC(av_packet_free,
++          (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61))
+   AV_FUNC(avcodec_descriptor_get, AV_FUNC_AVCODEC_ALL)
+   AV_FUNC(av_log_set_level, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_malloc, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_freep, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_frame_alloc,
+           (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
+-           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60))
++           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
++           AV_FUNC_AVUTIL_61))
+   AV_FUNC(av_frame_free,
+           (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
+-           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60))
++           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
++           AV_FUNC_AVUTIL_61))
+   AV_FUNC(av_frame_unref,
+           (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
+-           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60))
++           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
++           AV_FUNC_AVUTIL_61))
+   AV_FUNC(av_frame_get_buffer,
+           (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
+-           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60))
++           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
++           AV_FUNC_AVUTIL_61))
+   AV_FUNC(av_frame_make_writable,
+           (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
+-           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60))
++           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
++           AV_FUNC_AVUTIL_61))
+   AV_FUNC(av_image_check_size, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_image_get_buffer_size, AV_FUNC_AVUTIL_ALL)
+-  AV_FUNC_OPTION(av_channel_layout_default, AV_FUNC_AVUTIL_60)
+-  AV_FUNC_OPTION(av_channel_layout_from_mask, AV_FUNC_AVUTIL_60)
+-  AV_FUNC_OPTION(av_channel_layout_copy, AV_FUNC_AVUTIL_60)
++  AV_FUNC_OPTION(av_channel_layout_default,
++                 AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61)
++  AV_FUNC_OPTION(av_channel_layout_from_mask,
++                 AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61)
++  AV_FUNC_OPTION(av_channel_layout_copy, AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61)
+   AV_FUNC_OPTION(av_buffer_get_opaque,
+                  (AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 | AV_FUNC_AVUTIL_58 |
+-                  AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60))
+-  AV_FUNC(av_buffer_create,
+-          (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
+-           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60))
++                  AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61))
++  AV_FUNC(
++      av_buffer_create,
++      (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
++       AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 | AV_FUNC_61))
+   AV_FUNC_OPTION(av_frame_get_colorspace,
+                  AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
+                      AV_FUNC_AVUTIL_58)
+   AV_FUNC_OPTION(av_frame_get_color_range,
+                  AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
+                      AV_FUNC_AVUTIL_58)
+-  AV_FUNC(av_strerror,
+-          AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60)
++  AV_FUNC(av_strerror, AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
++                           AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61)
+   AV_FUNC(av_get_sample_fmt_name, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_dict_set, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_dict_free, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_opt_set, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_opt_set_double, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC(av_opt_set_int, AV_FUNC_AVUTIL_ALL)
+ 
+ #ifdef MOZ_WIDGET_GTK
+   AV_FUNC_OPTION_SILENT(avcodec_get_hw_config,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC_OPTION_SILENT(av_codec_iterate, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
++  AV_FUNC_OPTION_SILENT(av_codec_iterate,
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC_OPTION_SILENT(av_codec_is_decoder,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_init,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_alloc,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC_OPTION_SILENT(av_hwdevice_hwconfig_alloc,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC_OPTION_SILENT(av_hwdevice_get_hwframe_constraints,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC_OPTION_SILENT(av_hwframe_constraints_free,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC_OPTION_SILENT(av_buffer_ref,
+-                        AV_FUNC_AVUTIL_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC_OPTION_SILENT(av_buffer_unref,
+-                        AV_FUNC_AVUTIL_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
++  AV_FUNC_OPTION_SILENT(av_buffer_ref, AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
++                                           AV_FUNC_AVUTIL_60 |
++                                           AV_FUNC_AVUTIL_61)
++  AV_FUNC_OPTION_SILENT(av_buffer_unref, AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
++                                             AV_FUNC_AVUTIL_60 |
++                                             AV_FUNC_AVUTIL_61)
+   AV_FUNC_OPTION_SILENT(av_hwframe_transfer_get_formats,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_create_derived,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
+   AV_FUNC_OPTION_SILENT(av_hwframe_ctx_alloc,
+-                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC_OPTION_SILENT(avcodec_get_name,
+-                        AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60)
+-  AV_FUNC_OPTION_SILENT(av_get_pix_fmt_string, AV_FUNC_AVUTIL_58 |
+-                                                   AV_FUNC_AVUTIL_59 |
+-                                                   AV_FUNC_AVUTIL_60)
++                        AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61)
++  AV_FUNC_OPTION_SILENT(avcodec_get_name, AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 |
++                                              AV_FUNC_60 | AV_FUNC_61)
++  AV_FUNC_OPTION_SILENT(
++      av_get_pix_fmt_string,
++      AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61)
+ #endif
+ 
+   AV_FUNC_OPTION(av_tx_init, AV_FUNC_AVUTIL_ALL)
+   AV_FUNC_OPTION(av_tx_uninit, AV_FUNC_AVUTIL_ALL)
+ 
+ #undef AV_FUNC
+ #undef AV_FUNC_OPTION
+ 
+diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
+--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
++++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
+@@ -133,20 +133,22 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CON
+   // libavcodec v54 only
+   void (*avcodec_free_frame)(AVFrame** frame);
+ 
+   // libavcodec >= v55
+   int (*avcodec_default_get_buffer2)(AVCodecContext* s, AVFrame* frame,
+                                      int flags);
+ 
+   // libavcodec >= v57
+-  AVPacket* (*av_packet_alloc)(void);
+   void (*av_packet_unref)(AVPacket* pkt);
+   void (*av_packet_free)(AVPacket** pkt);
+ 
++  // libavcodec >= 61
++  AVPacket* (*av_packet_alloc)();
++
+   // libavcodec v58 and later only
+   int (*avcodec_send_packet)(AVCodecContext* avctx, const AVPacket* avpkt);
+   int (*avcodec_receive_packet)(AVCodecContext* avctx, AVPacket* avpkt);
+   int (*avcodec_send_frame)(AVCodecContext* avctx, const AVFrame* frame);
+   int (*avcodec_receive_frame)(AVCodecContext* avctx, AVFrame* frame);
+ 
+   // libavutil
+   void (*av_log_set_level)(int level);
+diff --git a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
+@@ -28,28 +28,30 @@ class FFmpegEncoderModule {
+   static already_AddRefed<PlatformEncoderModule> Create(FFmpegLibWrapper*);
+ };
+ 
+ static FFmpegLibWrapper sLibAV;
+ 
+ static const char* sLibs[] = {
+ // clang-format off
+ #if defined(XP_DARWIN)
++  "libavcodec.61.dylib",
+   "libavcodec.60.dylib",
+   "libavcodec.59.dylib",
+   "libavcodec.58.dylib",
+   "libavcodec.57.dylib",
+   "libavcodec.56.dylib",
+   "libavcodec.55.dylib",
+   "libavcodec.54.dylib",
+   "libavcodec.53.dylib",
+ #elif defined(XP_OPENBSD)
+   "libavcodec.so", // OpenBSD hardly controls the major/minor library version
+                    // of ffmpeg and update it regulary on ABI/API changes
+ #else
++  "libavcodec.so.61",
+   "libavcodec.so.60",
+   "libavcodec.so.59",
+   "libavcodec.so.58",
+   "libavcodec-ffmpeg.so.58",
+   "libavcodec-ffmpeg.so.57",
+   "libavcodec-ffmpeg.so.56",
+   "libavcodec.so.57",
+   "libavcodec.so.56",
+@@ -169,16 +171,19 @@ already_AddRefed<PlatformDecoderModule> 
+       module = FFmpegDecoderModule<58>::Create(&sLibAV);
+       break;
+     case 59:
+       module = FFmpegDecoderModule<59>::Create(&sLibAV);
+       break;
+     case 60:
+       module = FFmpegDecoderModule<60>::Create(&sLibAV);
+       break;
++    case 61:
++      module = FFmpegDecoderModule<61>::Create(&sLibAV);
++      break;
+     default:
+       module = nullptr;
+   }
+   return module.forget();
+ }
+ 
+ /* static */
+ already_AddRefed<PlatformEncoderModule> FFmpegRuntimeLinker::CreateEncoder() {
+@@ -204,16 +209,19 @@ already_AddRefed<PlatformEncoderModule> 
+       module = FFmpegEncoderModule<58>::Create(&sLibAV);
+       break;
+     case 59:
+       module = FFmpegEncoderModule<59>::Create(&sLibAV);
+       break;
+     case 60:
+       module = FFmpegEncoderModule<60>::Create(&sLibAV);
+       break;
++    case 61:
++      module = FFmpegEncoderModule<61>::Create(&sLibAV);
++      break;
+     default:
+       module = nullptr;
+   }
+   return module.forget();
+ }
+ 
+ /* static */ const char* FFmpegRuntimeLinker::LinkStatusString() {
+   switch (sLinkStatus) {
+diff --git a/dom/media/platforms/ffmpeg/FFmpegUtils.h b/dom/media/platforms/ffmpeg/FFmpegUtils.h
+--- a/dom/media/platforms/ffmpeg/FFmpegUtils.h
++++ b/dom/media/platforms/ffmpeg/FFmpegUtils.h
+@@ -46,11 +46,41 @@ inline bool IsVideoCodec(AVCodecID aCode
+     case AV_CODEC_ID_AV1:
+ #endif
+       return true;
+     default:
+       return false;
+   }
+ }
+ 
++// Access the correct location for the channel count, based on ffmpeg version.
++template<typename T>
++inline int& ChannelCount(T* aObject) {
++#if LIBAVCODEC_VERSION_MAJOR <= 59
++  return aObject->channels;
++#else
++  return aObject->ch_layout.nb_channels;
++#endif
++}
++
++// Access the correct location for the duration, based on ffmpeg version.
++template<typename T>
++inline int64_t& Duration(T* aObject) {
++#if LIBAVCODEC_VERSION_MAJOR < 61
++  return aObject->pkt_duration;
++#else
++  return aObject->duration;
++#endif
++}
++
++// Access the correct location for the duration, based on ffmpeg version.
++template<typename T>
++inline const int64_t& Duration(const T* aObject) {
++#if LIBAVCODEC_VERSION_MAJOR < 61
++  return aObject->pkt_duration;
++#else
++  return aObject->duration;
++#endif
++}
++
+ }  // namespace mozilla
+ 
+ #endif  // DOM_MEDIA_PLATFORMS_FFMPEG_FFMPEGUTILS_H_
+diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+@@ -2,16 +2,17 @@
+ /* vim:set ts=2 sw=2 sts=2 et cindent: */
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #include "FFmpegVideoDecoder.h"
+ 
+ #include "FFmpegLog.h"
++#include "FFmpegUtils.h"
+ #include "ImageContainer.h"
+ #include "MP4Decoder.h"
+ #include "MediaInfo.h"
+ #include "VideoUtils.h"
+ #include "VPXDecoder.h"
+ #include "mozilla/layers/KnowsCompositor.h"
+ #if LIBAVCODEC_VERSION_MAJOR >= 57
+ #  include "mozilla/layers/TextureClient.h"
+@@ -866,17 +867,19 @@ int FFmpegVideoDecoder<LIBAV_VER>::GetVi
+   aFrame->linesize[0] = mapped.y.stride;
+   aFrame->linesize[1] = mapped.cb.stride;
+   aFrame->linesize[2] = mapped.cr.stride;
+ 
+   aFrame->width = aCodecContext->coded_width;
+   aFrame->height = aCodecContext->coded_height;
+   aFrame->format = aCodecContext->pix_fmt;
+   aFrame->extended_data = aFrame->data;
++#  if LIBAVCODEC_VERSION_MAJOR < 61
+   aFrame->reordered_opaque = aCodecContext->reordered_opaque;
++#endif
+   MOZ_ASSERT(aFrame->data[0] && aFrame->data[1] && aFrame->data[2]);
+ 
+   // This will hold a reference to image, and the reference would be dropped
+   // when ffmpeg tells us that the buffer is no longer needed.
+   auto imageWrapper = MakeRefPtr<ImageBufferWrapper>(image.get(), this);
+   aFrame->buf[0] =
+       mLib->av_buffer_create(aFrame->data[0], dataSize.value(),
+                              ReleaseVideoBufferWrapper, imageWrapper.get(), 0);
+@@ -986,22 +989,17 @@ bool FFmpegVideoDecoder<LIBAV_VER>::Deco
+ }
+ 
+ void FFmpegVideoDecoder<LIBAV_VER>::DecodeStats::UpdateDecodeTimes(
+     const AVFrame* aFrame) {
+   TimeStamp now = TimeStamp::Now();
+   float decodeTime = (now - mDecodeStart).ToMilliseconds();
+   mDecodeStart = now;
+ 
+-  if (aFrame->pkt_duration <= 0) {
+-    FFMPEGV_LOG("Incorrect frame duration, skipping decode stats.");
+-    return;
+-  }
+-
+-  float frameDuration = aFrame->pkt_duration / 1000.0f;
++  const float frameDuration = Duration(aFrame) / 1000.0f;
+ 
+   mDecodedFrames++;
+   mAverageFrameDuration =
+       (mAverageFrameDuration * (mDecodedFrames - 1) + frameDuration) /
+       mDecodedFrames;
+   mAverageFrameDecodeTime =
+       (mAverageFrameDecodeTime * (mDecodedFrames - 1) + decodeTime) /
+       mDecodedFrames;
+@@ -1039,29 +1037,39 @@ void FFmpegVideoDecoder<LIBAV_VER>::Deco
+   }
+ }
+ #endif
+ 
+ MediaResult FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
+     MediaRawData* aSample, uint8_t* aData, int aSize, bool* aGotFrame,
+     MediaDataDecoder::DecodedData& aResults) {
+   MOZ_ASSERT(mTaskQueue->IsOnCurrentThread());
+-  AVPacket packet;
+-  mLib->av_init_packet(&packet);
++  AVPacket* packet;
++
++#if LIBAVCODEC_VERSION_MAJOR >= 61
++  packet = mLib->av_packet_alloc();
++  auto raii = MakeScopeExit([&]() {
++    mLib->av_packet_free(&packet);
++  });
++#else
++  AVPacket packet_mem;
++  packet = &packet_mem;
++  mLib->av_init_packet(packet);
++#endif
+ 
+ #if LIBAVCODEC_VERSION_MAJOR >= 58
+   mDecodeStats.DecodeStart();
+ #endif
+ 
+-  packet.data = aData;
+-  packet.size = aSize;
+-  packet.dts = aSample->mTimecode.ToMicroseconds();
+-  packet.pts = aSample->mTime.ToMicroseconds();
+-  packet.flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0;
+-  packet.pos = aSample->mOffset;
++  packet->data = aData;
++  packet->size = aSize;
++  packet->dts = aSample->mTimecode.ToMicroseconds();
++  packet->pts = aSample->mTime.ToMicroseconds();
++  packet->flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0;
++  packet->pos = aSample->mOffset;
+ 
+   mTrackingId.apply([&](const auto& aId) {
+     MediaInfoFlag flag = MediaInfoFlag::None;
+     flag |= (aSample->mKeyframe ? MediaInfoFlag::KeyFrame
+                                 : MediaInfoFlag::NonKeyFrame);
+     flag |= (IsHardwareAccelerated() ? MediaInfoFlag::HardwareDecoding
+                                      : MediaInfoFlag::SoftwareDecoding);
+     switch (mCodecID) {
+@@ -1082,24 +1090,24 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER
+       case AV_CODEC_ID_AV1:
+         flag |= MediaInfoFlag::VIDEO_AV1;
+         break;
+ #endif
+       default:
+         break;
+     }
+     mPerformanceRecorder.Start(
+-        packet.dts,
++        packet->dts,
+         nsPrintfCString("FFmpegVideoDecoder(%d)", LIBAVCODEC_VERSION_MAJOR),
+         aId, flag);
+   });
+ 
+ #if LIBAVCODEC_VERSION_MAJOR >= 58
+-  packet.duration = aSample->mDuration.ToMicroseconds();
+-  int res = mLib->avcodec_send_packet(mCodecContext, &packet);
++  packet->duration = aSample->mDuration.ToMicroseconds();
++  int res = mLib->avcodec_send_packet(mCodecContext, packet);
+   if (res < 0) {
+     // In theory, avcodec_send_packet could sent -EAGAIN should its internal
+     // buffers be full. In practice this can't happen as we only feed one frame
+     // at a time, and we immediately call avcodec_receive_frame right after.
+     char errStr[AV_ERROR_MAX_STRING_SIZE];
+     mLib->av_strerror(res, errStr, AV_ERROR_MAX_STRING_SIZE);
+     FFMPEG_LOG("avcodec_send_packet error: %s", errStr);
+     return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+@@ -1151,35 +1159,35 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER
+                              "Fallback to SW decode");
+         FFMPEG_LOG("  HW decoding is slow, switch back to SW decode");
+         return MediaResult(
+             NS_ERROR_DOM_MEDIA_DECODE_ERR,
+             RESULT_DETAIL("HW decoding is slow, switch back to SW decode"));
+       }
+       if (mUsingV4L2) {
+         rv = CreateImageV4L2(mFrame->pkt_pos, GetFramePts(mFrame),
+-                             mFrame->pkt_duration, aResults);
++                             Duration(mFrame), aResults);
+       } else {
+         rv = CreateImageVAAPI(mFrame->pkt_pos, GetFramePts(mFrame),
+-                              mFrame->pkt_duration, aResults);
++                              Duration(mFrame), aResults);
+       }
+ 
+       // If VA-API/V4L2 playback failed, just quit. Decoder is going to be
+       // restarted without hardware acceleration
+       if (NS_FAILED(rv)) {
+         // Explicitly remove dmabuf surface pool as it's configured
+         // for VA-API/V4L2 support.
+         mVideoFramePool = nullptr;
+         return rv;
+       }
+     } else
+ #  endif
+     {
+       rv = CreateImage(mFrame->pkt_pos, GetFramePts(mFrame),
+-                       mFrame->pkt_duration, aResults);
++                       Duration(mFrame), aResults);
+     }
+     if (NS_FAILED(rv)) {
+       return rv;
+     }
+ 
+     mPerformanceRecorder.Record(mFrame->pkt_dts, [&](auto& aStage) {
+       aStage.SetResolution(mFrame->width, mFrame->height);
+       auto format = [&]() -> Maybe<DecodeStage::ImageFormat> {
+@@ -1234,24 +1242,24 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER
+     return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
+   }
+ 
+   // Required with old version of FFmpeg/LibAV
+   mFrame->reordered_opaque = AV_NOPTS_VALUE;
+ 
+   int decoded;
+   int bytesConsumed =
+-      mLib->avcodec_decode_video2(mCodecContext, mFrame, &decoded, &packet);
++      mLib->avcodec_decode_video2(mCodecContext, mFrame, &decoded, packet);
+ 
+   FFMPEG_LOG(
+       "DoDecodeFrame:decode_video: rv=%d decoded=%d "
+       "(Input: pts(%" PRId64 ") dts(%" PRId64 ") Output: pts(%" PRId64
+       ") "
+       "opaque(%" PRId64 ") pts(%" PRId64 ") pkt_dts(%" PRId64 "))",
+-      bytesConsumed, decoded, packet.pts, packet.dts, mFrame->pts,
++      bytesConsumed, decoded, packet->pts, packet->dts, mFrame->pts,
+       mFrame->reordered_opaque, mFrame->pts, mFrame->pkt_dts);
+ 
+   if (bytesConsumed < 0) {
+     return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+                        RESULT_DETAIL("FFmpeg video error: %d", bytesConsumed));
+   }
+ 
+   if (!decoded) {
+@@ -1369,18 +1377,18 @@ gfx::ColorRange FFmpegVideoDecoder<LIBAV
+ #endif
+   return GetColorRange(range);
+ }
+ 
+ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImage(
+     int64_t aOffset, int64_t aPts, int64_t aDuration,
+     MediaDataDecoder::DecodedData& aResults) const {
+   FFMPEG_LOG("Got one frame output with pts=%" PRId64 " dts=%" PRId64
+-             " duration=%" PRId64 " opaque=%" PRId64,
+-             aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque);
++             " duration=%" PRId64,
++             aPts, mFrame->pkt_dts, aDuration);
+ 
+   VideoData::YCbCrBuffer b;
+   b.mPlanes[0].mData = mFrame->data[0];
+   b.mPlanes[1].mData = mFrame->data[1];
+   b.mPlanes[2].mData = mFrame->data[2];
+ 
+   b.mPlanes[0].mStride = mFrame->linesize[0];
+   b.mPlanes[1].mStride = mFrame->linesize[1];
+@@ -1498,18 +1506,18 @@ bool FFmpegVideoDecoder<LIBAV_VER>::GetV
+   }
+   return true;
+ }
+ 
+ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageVAAPI(
+     int64_t aOffset, int64_t aPts, int64_t aDuration,
+     MediaDataDecoder::DecodedData& aResults) {
+   FFMPEG_LOG("VA-API Got one frame output with pts=%" PRId64 " dts=%" PRId64
+-             " duration=%" PRId64 " opaque=%" PRId64,
+-             aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque);
++             " duration=%" PRId64,
++             aPts, mFrame->pkt_dts, aDuration);
+ 
+   VADRMPRIMESurfaceDescriptor vaDesc;
+   if (!GetVAAPISurfaceDescriptor(&vaDesc)) {
+     return MediaResult(
+         NS_ERROR_DOM_MEDIA_DECODE_ERR,
+         RESULT_DETAIL("Unable to get frame by vaExportSurfaceHandle()"));
+   }
+   auto releaseSurfaceDescriptor = MakeScopeExit(
+@@ -1544,18 +1552,18 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER
+   aResults.AppendElement(std::move(vp));
+   return NS_OK;
+ }
+ 
+ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImageV4L2(
+     int64_t aOffset, int64_t aPts, int64_t aDuration,
+     MediaDataDecoder::DecodedData& aResults) {
+   FFMPEG_LOG("V4L2 Got one frame output with pts=%" PRId64 " dts=%" PRId64
+-             " duration=%" PRId64 " opaque=%" PRId64,
+-             aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque);
++             " duration=%" PRId64,
++             aPts, mFrame->pkt_dts, aDuration);
+ 
+   AVDRMFrameDescriptor* desc = (AVDRMFrameDescriptor*)mFrame->data[0];
+   if (!desc) {
+     return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+                        RESULT_DETAIL("Missing DRM PRIME descriptor in frame"));
+   }
+ 
+   // Note that the FDs in desc are owned by FFmpeg and it will reuse them
+diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegVideoEncoder.cpp
+@@ -505,17 +505,17 @@ Result<MediaDataEncoder::EncodedData, ns
+ #  endif
+   mFrame->pts = aSample->mTime.ToMicroseconds();
+ #  if LIBAVCODEC_VERSION_MAJOR >= 60
+   mFrame->duration = aSample->mDuration.ToMicroseconds();
+ #  else
+   // Save duration in the time_base unit.
+   mDurationMap.Insert(mFrame->pts, aSample->mDuration.ToMicroseconds());
+ #  endif
+-  mFrame->pkt_duration = aSample->mDuration.ToMicroseconds();
++  Duration(mFrame) = aSample->mDuration.ToMicroseconds();
+ 
+   // Now send the AVFrame to ffmpeg for encoding, same code for audio and video.
+   return FFmpegDataEncoder<LIBAV_VER>::EncodeWithModernAPIs();
+ }
+ #endif  // if LIBAVCODEC_VERSION_MAJOR >= 58
+ 
+ RefPtr<MediaRawData> FFmpegVideoEncoder<LIBAV_VER>::ToMediaRawData(
+     AVPacket* aPacket) {
+
diff --git a/5759fe6ed8a5.patch b/5759fe6ed8a5.patch
new file mode 100644
index 0000000..8831401
--- /dev/null
+++ b/5759fe6ed8a5.patch
@@ -0,0 +1,20606 @@
+
+# HG changeset patch
+# User Paul Adenot <paul@paul.cx>
+# Date 1714486905 0
+# Node ID 5759fe6ed8a53b22ffac43c073687e127c07b0f7
+# Parent  5970587d9a7a05549c7e9f8bb5723c4e6866a3c8
+Bug 1889978 - Vendor ffmpeg master, after 7.0, update and reapply patch, remove old files, move bsf files into the bsf directory. r=media-playback-reviewers,alwu
+
+This stubs out `libavcodec/dovi_rpu.h`.
+
+Differential Revision: https://phabricator.services.mozilla.com/D206923
+
+diff --git a/config/system-headers.mozbuild b/config/system-headers.mozbuild
+--- a/config/system-headers.mozbuild
++++ b/config/system-headers.mozbuild
+@@ -407,16 +407,18 @@ system_headers = [
+     "LEditText.h",
+     "LEventDispatcher.h",
+     "LFile.h",
+     "LFileStream.h",
+     "LFileTypeList.h",
+     "LFocusBox.h",
+     "LGrafPortView.h",
+     "LHandleStream.h",
++    "libavutil/mem.h",
++    "libavutil/cpu.h",
+     "libc_r.h",
+     "libelf.h",
+     "libelf/libelf.h",
+     "libgen.h",
+     "libgnome/gnome-url.h",
+     "libgnome/libgnome.h",
+     "libgnomeui/gnome-icon-lookup.h",
+     "libgnomeui/gnome-icon-theme.h",
+diff --git a/media/ffvpx/README_MOZILLA b/media/ffvpx/README_MOZILLA
+--- a/media/ffvpx/README_MOZILLA
++++ b/media/ffvpx/README_MOZILLA
+@@ -31,16 +31,19 @@ Then, make sure the files:
+ 
+ - `libavcodec/codec_list.c`
+ - `libavcodec/bsf_list.c`
+ - `libavcodec/parser_list.c`
+ 
+ include conditional compilation directives, by probably reverting them (or
+ reverting and adjusting them if new codecs are added).
+ 
++Revert and adjust libavcodec `dovi_rpu.h` so that it contains just the necessary
++stubs to compile.
++
+ ## Add headers for a new major ffmpeg version
+ 
+ If a new major version of ffmpeg is being imported in the tree, it's necessary
+ to vendor the new ffmpeg headers in `dom/media/platforms/ffmpeg/ffmpegxx` where
+ xx is the new ffmpeg major version number, and to modify the dynamic linker
+ wrapper in
+ `dom/media/platforms/dom/media/platforms/ffmpeg/{FFmpegLibWrapper.cpp,FFmpegRungtimeLinker.cpp}` with the new version and the new API in this new version.
+ 
+diff --git a/media/ffvpx/changes.patch b/media/ffvpx/changes.patch
+--- a/media/ffvpx/changes.patch
++++ b/media/ffvpx/changes.patch
+@@ -1,82 +1,86 @@
+-diff --git a/media/ffvpx/libavutil/eval.c b/media/ffvpx/libavutil/eval.c
+-index 7642b91..e938bd5 100644
+---- a/media/ffvpx/libavutil/eval.c
+-+++ b/media/ffvpx/libavutil/eval.c
+-@@ -34,7 +34,7 @@
+- #include "internal.h"
+- #include "log.h"
+- #include "mathematics.h"
+--#include "time.h"
+-+#include "fftime.h"
+- #include "avstring.h"
+- #include "timer.h"
+- 
+-diff --git a/media/ffvpx/libavutil/time.c b/media/ffvpx/libavutil/time.c
+-index dbaee02..69419e6 100644
+---- a/media/ffvpx/libavutil/time.c
+-+++ b/media/ffvpx/libavutil/time.c
+-@@ -33,7 +33,7 @@
++--- a/libavutil/time.c	2024-02-14 14:57:10.389087159 +0100
+++++ b/libavutil/time.c	2024-04-05 14:43:19.097889433 +0200
++@@ -28,17 +28,17 @@
++ #endif
++ #if HAVE_UNISTD_H
++ #include <unistd.h>
++ #endif
++ #if HAVE_WINDOWS_H
+  #include <windows.h>
+  #endif
+  
+ -#include "time.h"
+ +#include "fftime.h"
+  #include "error.h"
+  
+  int64_t av_gettime(void)
+-diff --git a/media/ffvpx/libavutil/parseutils.c b/media/ffvpx/libavutil/parseutils.c
+-index 9fb8d0a..97ad3b9 100644
+---- a/media/ffvpx/libavutil/parseutils.c
+-+++ b/media/ffvpx/libavutil/parseutils.c
+-@@ -28,7 +28,7 @@
++ {
++ #if HAVE_GETTIMEOFDAY
++     struct timeval tv;
++     gettimeofday(&tv, NULL);
++     return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
++--- a/libavutil/parseutils.c	2024-03-26 14:03:12.080640731 +0100
+++++ b/libavutil/parseutils.c	2024-04-05 14:44:56.508766832 +0200
++@@ -23,20 +23,20 @@
++ 
++ #include <time.h>
++ 
++ #include "avstring.h"
++ #include "avutil.h"
+  #include "common.h"
+  #include "eval.h"
+  #include "log.h"
+ -#include "random_seed.h"
+ +/* #include "random_seed.h" */
+  #include "time_internal.h"
+  #include "parseutils.h"
++-#include "time.h"
+++#include "fftime.h"
+  
+-@@ -367,7 +367,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
++ #ifdef TEST
++ 
++ #define av_get_random_seed av_get_random_seed_deterministic
++ static uint32_t av_get_random_seed_deterministic(void);
++ 
++ #define av_gettime() 1331972053200000
++ 
++@@ -370,17 +370,17 @@
++     av_strlcpy(color_string2, color_string + hex_offset,
++                FFMIN(slen-hex_offset+1, sizeof(color_string2)));
++     if ((tail = strchr(color_string2, ALPHA_SEP)))
++         *tail++ = 0;
++     len = strlen(color_string2);
+      rgba_color[3] = 255;
+  
+      if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {
+ -        int rgba = av_get_random_seed();
+ +        int rgba = 0xffffffff; /* av_get_random_seed(); */
+          rgba_color[0] = rgba >> 24;
+          rgba_color[1] = rgba >> 16;
+          rgba_color[2] = rgba >> 8;
+-diff -up media/ffvpx/libavutil/fftime.h media/ffvpx/libavutil/fftime.h
+---- media/ffvpx/libavutil/fftime.h	2021-12-06 14:51:40.378642713 +0100
+-+++ media/ffvpx/libavutil/fftime.h	2021-12-06 14:51:54.618098212 +0100
+-@@ -22,6 +22,7 @@
+- #define AVUTIL_TIME_H
+- 
+- #include <stdint.h>
+-+#include <time.h>
++         rgba_color[3] = rgba;
++     } else if (hex_offset ||
++                strspn(color_string2, "0123456789ABCDEFabcdef") == len) {
++         char *tail;
++         unsigned int rgba = strtoul(color_string2, &tail, 16);
++--- a/libavutil/eval.c	2024-04-05 14:40:56.917791496 +0200
+++++ b/libavutil/eval.c	2024-04-05 17:39:45.061516936 +0200
++@@ -31,17 +31,17 @@
++ #include "avutil.h"
++ #include "common.h"
++ #include "eval.h"
++ #include "ffmath.h"
++ #include "log.h"
++ #include "mathematics.h"
++ #include "mem.h"
++ #include "sfc64.h"
++-#include "time.h"
+++#include "fftime.h"
++ #include "avstring.h"
++ #include "reverse.h"
+  
+- /**
+-  * Get the current time in microseconds.
+-  *
+-diff --git a/media/ffvpx/compat/w32pthreads.h b/media/ffvpx/compat/w32pthreads.h
+---- a/media/ffvpx/compat/w32pthreads.h
+-+++ b/media/ffvpx/compat/w32pthreads.h
+-@@ -39,17 +39,17 @@
+- #include <windows.h>
+- #include <process.h>
+- #include <time.h>
+- 
+- #include "libavutil/attributes.h"
+- #include "libavutil/common.h"
+- #include "libavutil/internal.h"
+- #include "libavutil/mem.h"
+--#include "libavutil/time.h"
+-+#include "libavutil/fftime.h"
+- 
+- typedef struct pthread_t {
+-     void *handle;
+-     void *(*func)(void* arg);
+-     void *arg;
+-     void *ret;
+- } pthread_t;
+- 
++ typedef struct Parser {
++     const AVClass *class;
++     int stack_index;
++     char *s;
++     const double *const_values;
+diff --git a/media/ffvpx/libavcodec/allcodecs.c b/media/ffvpx/libavcodec/allcodecs.c
+--- a/media/ffvpx/libavcodec/allcodecs.c
++++ b/media/ffvpx/libavcodec/allcodecs.c
+@@ -56,20 +56,16 @@ extern const FFCodec ff_asv2_decoder;
+ extern const FFCodec ff_aura_decoder;
+ extern const FFCodec ff_aura2_decoder;
+ extern const FFCodec ff_avrp_encoder;
+ extern const FFCodec ff_avrp_decoder;
+ extern const FFCodec ff_avrn_decoder;
+ extern const FFCodec ff_avs_decoder;
+ extern const FFCodec ff_avui_encoder;
+ extern const FFCodec ff_avui_decoder;
+-#if FF_API_AYUV_CODECID
+-extern const FFCodec ff_ayuv_encoder;
+-extern const FFCodec ff_ayuv_decoder;
+-#endif
+ extern const FFCodec ff_bethsoftvid_decoder;
+ extern const FFCodec ff_bfi_decoder;
+ extern const FFCodec ff_bink_decoder;
+ extern const FFCodec ff_bitpacked_decoder;
+ extern const FFCodec ff_bitpacked_encoder;
+ extern const FFCodec ff_bmp_encoder;
+ extern const FFCodec ff_bmp_decoder;
+ extern const FFCodec ff_bmv_video_decoder;
+@@ -147,17 +143,16 @@ extern const FFCodec ff_h261_encoder;
+ extern const FFCodec ff_h261_decoder;
+ extern const FFCodec ff_h263_encoder;
+ extern const FFCodec ff_h263_decoder;
+ extern const FFCodec ff_h263i_decoder;
+ extern const FFCodec ff_h263p_encoder;
+ extern const FFCodec ff_h263p_decoder;
+ extern const FFCodec ff_h263_v4l2m2m_decoder;
+ extern const FFCodec ff_h264_decoder;
+-extern const FFCodec ff_h264_crystalhd_decoder;
+ extern const FFCodec ff_h264_v4l2m2m_decoder;
+ extern const FFCodec ff_h264_mediacodec_decoder;
+ extern const FFCodec ff_h264_mediacodec_encoder;
+ extern const FFCodec ff_h264_mmal_decoder;
+ extern const FFCodec ff_h264_qsv_decoder;
+ extern const FFCodec ff_h264_rkmpp_decoder;
+ extern const FFCodec ff_hap_encoder;
+ extern const FFCodec ff_hap_decoder;
+@@ -206,34 +201,31 @@ extern const FFCodec ff_mmvideo_decoder;
+ extern const FFCodec ff_mobiclip_decoder;
+ extern const FFCodec ff_motionpixels_decoder;
+ extern const FFCodec ff_mpeg1video_encoder;
+ extern const FFCodec ff_mpeg1video_decoder;
+ extern const FFCodec ff_mpeg2video_encoder;
+ extern const FFCodec ff_mpeg2video_decoder;
+ extern const FFCodec ff_mpeg4_encoder;
+ extern const FFCodec ff_mpeg4_decoder;
+-extern const FFCodec ff_mpeg4_crystalhd_decoder;
+ extern const FFCodec ff_mpeg4_v4l2m2m_decoder;
+ extern const FFCodec ff_mpeg4_mmal_decoder;
+ extern const FFCodec ff_mpegvideo_decoder;
+ extern const FFCodec ff_mpeg1_v4l2m2m_decoder;
+ extern const FFCodec ff_mpeg2_mmal_decoder;
+-extern const FFCodec ff_mpeg2_crystalhd_decoder;
+ extern const FFCodec ff_mpeg2_v4l2m2m_decoder;
+ extern const FFCodec ff_mpeg2_qsv_decoder;
+ extern const FFCodec ff_mpeg2_mediacodec_decoder;
+ extern const FFCodec ff_msa1_decoder;
+ extern const FFCodec ff_mscc_decoder;
+ extern const FFCodec ff_msmpeg4v1_decoder;
+ extern const FFCodec ff_msmpeg4v2_encoder;
+ extern const FFCodec ff_msmpeg4v2_decoder;
+ extern const FFCodec ff_msmpeg4v3_encoder;
+ extern const FFCodec ff_msmpeg4v3_decoder;
+-extern const FFCodec ff_msmpeg4_crystalhd_decoder;
+ extern const FFCodec ff_msp2_decoder;
+ extern const FFCodec ff_msrle_encoder;
+ extern const FFCodec ff_msrle_decoder;
+ extern const FFCodec ff_mss1_decoder;
+ extern const FFCodec ff_mss2_decoder;
+ extern const FFCodec ff_msvideo1_encoder;
+ extern const FFCodec ff_msvideo1_decoder;
+ extern const FFCodec ff_mszh_decoder;
+@@ -360,17 +352,16 @@ extern const FFCodec ff_v408_encoder;
+ extern const FFCodec ff_v408_decoder;
+ extern const FFCodec ff_v410_encoder;
+ extern const FFCodec ff_v410_decoder;
+ extern const FFCodec ff_vb_decoder;
+ extern const FFCodec ff_vbn_encoder;
+ extern const FFCodec ff_vbn_decoder;
+ extern const FFCodec ff_vble_decoder;
+ extern const FFCodec ff_vc1_decoder;
+-extern const FFCodec ff_vc1_crystalhd_decoder;
+ extern const FFCodec ff_vc1image_decoder;
+ extern const FFCodec ff_vc1_mmal_decoder;
+ extern const FFCodec ff_vc1_qsv_decoder;
+ extern const FFCodec ff_vc1_v4l2m2m_decoder;
+ extern const FFCodec ff_vc2_encoder;
+ extern const FFCodec ff_vcr1_decoder;
+ extern const FFCodec ff_vmdvideo_decoder;
+ extern const FFCodec ff_vmix_decoder;
+@@ -397,17 +388,16 @@ extern const FFCodec ff_webp_decoder;
+ extern const FFCodec ff_wcmv_decoder;
+ extern const FFCodec ff_wrapped_avframe_encoder;
+ extern const FFCodec ff_wrapped_avframe_decoder;
+ extern const FFCodec ff_wmv1_encoder;
+ extern const FFCodec ff_wmv1_decoder;
+ extern const FFCodec ff_wmv2_encoder;
+ extern const FFCodec ff_wmv2_decoder;
+ extern const FFCodec ff_wmv3_decoder;
+-extern const FFCodec ff_wmv3_crystalhd_decoder;
+ extern const FFCodec ff_wmv3image_decoder;
+ extern const FFCodec ff_wnv1_decoder;
+ extern const FFCodec ff_xan_wc3_decoder;
+ extern const FFCodec ff_xan_wc4_decoder;
+ extern const FFCodec ff_xbm_encoder;
+ extern const FFCodec ff_xbm_decoder;
+ extern const FFCodec ff_xface_encoder;
+ extern const FFCodec ff_xface_decoder;
+@@ -781,16 +771,18 @@ extern const FFCodec ff_libfdk_aac_decod
+ extern const FFCodec ff_libgsm_encoder;
+ extern const FFCodec ff_libgsm_decoder;
+ extern const FFCodec ff_libgsm_ms_encoder;
+ extern const FFCodec ff_libgsm_ms_decoder;
+ extern const FFCodec ff_libilbc_encoder;
+ extern const FFCodec ff_libilbc_decoder;
+ extern const FFCodec ff_libjxl_decoder;
+ extern const FFCodec ff_libjxl_encoder;
++extern const FFCodec ff_liblc3_encoder;
++extern const FFCodec ff_liblc3_decoder;
+ extern const FFCodec ff_libmp3lame_encoder;
+ extern const FFCodec ff_libopencore_amrnb_encoder;
+ extern const FFCodec ff_libopencore_amrnb_decoder;
+ extern const FFCodec ff_libopencore_amrwb_decoder;
+ extern const FFCodec ff_libopenjpeg_encoder;
+ extern const FFCodec ff_libopus_encoder;
+ extern const FFCodec ff_libopus_decoder;
+ extern const FFCodec ff_librav1e_encoder;
+diff --git a/media/ffvpx/libavcodec/atsc_a53.c b/media/ffvpx/libavcodec/atsc_a53.c
+--- a/media/ffvpx/libavcodec/atsc_a53.c
++++ b/media/ffvpx/libavcodec/atsc_a53.c
+@@ -14,16 +14,17 @@
+  * 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
+  */
+ 
+ #include <stddef.h>
+ #include <stdint.h>
+ 
++#include "libavutil/mem.h"
+ #include "atsc_a53.h"
+ #include "get_bits.h"
+ 
+ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len,
+                      void **data, size_t *sei_size)
+ {
+     AVFrameSideData *side_data = NULL;
+     uint8_t *sei_data;
+diff --git a/media/ffvpx/libavcodec/audio_frame_queue.c b/media/ffvpx/libavcodec/audio_frame_queue.c
+--- a/media/ffvpx/libavcodec/audio_frame_queue.c
++++ b/media/ffvpx/libavcodec/audio_frame_queue.c
+@@ -15,17 +15,17 @@
+  * 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
+  */
+ 
+ #include "libavutil/attributes.h"
+-#include "libavutil/common.h"
++#include "libavutil/mem.h"
+ #include "audio_frame_queue.h"
+ #include "encode.h"
+ #include "libavutil/avassert.h"
+ 
+ av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
+ {
+     afq->avctx = avctx;
+     afq->remaining_delay   = avctx->initial_padding;
+diff --git a/media/ffvpx/libavcodec/av1.h b/media/ffvpx/libavcodec/av1.h
+--- a/media/ffvpx/libavcodec/av1.h
++++ b/media/ffvpx/libavcodec/av1.h
+@@ -53,16 +53,17 @@ enum {
+     AV1_FRAME_KEY        = 0,
+     AV1_FRAME_INTER      = 1,
+     AV1_FRAME_INTRA_ONLY = 2,
+     AV1_FRAME_SWITCH     = 3,
+ };
+ 
+ // Reference frames (section 6.10.24).
+ enum {
++    AV1_REF_FRAME_NONE    = -1,
+     AV1_REF_FRAME_INTRA   = 0,
+     AV1_REF_FRAME_LAST    = 1,
+     AV1_REF_FRAME_LAST2   = 2,
+     AV1_REF_FRAME_LAST3   = 3,
+     AV1_REF_FRAME_GOLDEN  = 4,
+     AV1_REF_FRAME_BWDREF  = 5,
+     AV1_REF_FRAME_ALTREF2 = 6,
+     AV1_REF_FRAME_ALTREF  = 7,
+diff --git a/media/ffvpx/libavcodec/av1_parse.h b/media/ffvpx/libavcodec/av1_parse.h
+--- a/media/ffvpx/libavcodec/av1_parse.h
++++ b/media/ffvpx/libavcodec/av1_parse.h
+@@ -25,16 +25,17 @@
+ #include <stdint.h>
+ 
+ #include "libavutil/error.h"
+ #include "libavutil/intmath.h"
+ #include "libavutil/macros.h"
+ 
+ #include "av1.h"
+ #include "get_bits.h"
++#include "leb.h"
+ 
+ // OBU header fields + max leb128 length
+ #define MAX_OBU_HEADER_SIZE (2 + 8)
+ 
+ typedef struct AV1OBU {
+     /** Size of payload */
+     int size;
+     const uint8_t *data;
+@@ -83,29 +84,16 @@ int ff_av1_extract_obu(AV1OBU *obu, cons
+ int ff_av1_packet_split(AV1Packet *pkt, const uint8_t *buf, int length,
+                         void *logctx);
+ 
+ /**
+  * Free all the allocated memory in the packet.
+  */
+ void ff_av1_packet_uninit(AV1Packet *pkt);
+ 
+-static inline int64_t leb128(GetBitContext *gb) {
+-    int64_t ret = 0;
+-    int i;
+-
+-    for (i = 0; i < 8; i++) {
+-        int byte = get_bits(gb, 8);
+-        ret |= (int64_t)(byte & 0x7f) << (i * 7);
+-        if (!(byte & 0x80))
+-            break;
+-    }
+-    return ret;
+-}
+-
+ static inline int parse_obu_header(const uint8_t *buf, int buf_size,
+                                    int64_t *obu_size, int *start_pos, int *type,
+                                    int *temporal_id, int *spatial_id)
+ {
+     GetBitContext gb;
+     int ret, extension_flag, has_size_flag;
+     int64_t size;
+ 
+@@ -124,17 +112,17 @@ static inline int parse_obu_header(const
+     if (extension_flag) {
+         *temporal_id = get_bits(&gb, 3);
+         *spatial_id  = get_bits(&gb, 2);
+         skip_bits(&gb, 3); // extension_header_reserved_3bits
+     } else {
+         *temporal_id = *spatial_id = 0;
+     }
+ 
+-    *obu_size  = has_size_flag ? leb128(&gb)
++    *obu_size  = has_size_flag ? get_leb128(&gb)
+                                : buf_size - 1 - extension_flag;
+ 
+     if (get_bits_left(&gb) < 0)
+         return AVERROR_INVALIDDATA;
+ 
+     *start_pos = get_bits_count(&gb) / 8;
+ 
+     size = *obu_size + *start_pos;
+diff --git a/media/ffvpx/libavcodec/av1dec.c b/media/ffvpx/libavcodec/av1dec.c
+--- a/media/ffvpx/libavcodec/av1dec.c
++++ b/media/ffvpx/libavcodec/av1dec.c
+@@ -18,27 +18,29 @@
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #include "config_components.h"
+ 
+ #include "libavutil/hdr_dynamic_metadata.h"
+ #include "libavutil/film_grain_params.h"
+ #include "libavutil/mastering_display_metadata.h"
++#include "libavutil/mem.h"
+ #include "libavutil/pixdesc.h"
+ #include "libavutil/opt.h"
+ #include "avcodec.h"
+ #include "av1_parse.h"
+ #include "av1dec.h"
+ #include "atsc_a53.h"
+ #include "bytestream.h"
+ #include "codec_internal.h"
+ #include "decode.h"
+ #include "hwaccel_internal.h"
+ #include "internal.h"
++#include "itut35.h"
+ #include "hwconfig.h"
+ #include "profiles.h"
+ #include "refstruct.h"
+ #include "thread.h"
+ 
+ /**< same with Div_Lut defined in spec 7.11.3.7 */
+ static const uint16_t div_lut[AV1_DIV_LUT_NUM] = {
+   16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 15768,
+@@ -615,16 +617,22 @@ static int get_pixel_format(AVCodecConte
+         *fmtp++ = AV_PIX_FMT_CUDA;
+ #endif
+         break;
+     }
+ 
+     *fmtp++ = pix_fmt;
+     *fmtp = AV_PIX_FMT_NONE;
+ 
++    for (int i = 0; pix_fmts[i] != pix_fmt; i++)
++        if (pix_fmts[i] == avctx->pix_fmt) {
++            s->pix_fmt = pix_fmt;
++            return 1;
++        }
++
+     ret = ff_get_format(avctx, pix_fmts);
+ 
+     /**
+      * check if the HW accel is inited correctly. If not, return un-implemented.
+      * Since now the av1 decoder doesn't support native decode, if it will be
+      * implemented in the future, need remove this check.
+      */
+     if (!avctx->hwaccel) {
+@@ -710,45 +718,47 @@ static av_cold int av1_decode_free(AVCod
+             av1_frame_unref(&s->ref[i]);
+             av_frame_free(&s->ref[i].f);
+         }
+     }
+     if (s->cur_frame.f) {
+         av1_frame_unref(&s->cur_frame);
+         av_frame_free(&s->cur_frame.f);
+     }
++    av_buffer_unref(&s->seq_data_ref);
+     ff_refstruct_unref(&s->seq_ref);
+     ff_refstruct_unref(&s->header_ref);
+     ff_refstruct_unref(&s->cll_ref);
+     ff_refstruct_unref(&s->mdcv_ref);
+     av_freep(&s->tile_group_info);
+ 
+     while (s->itut_t35_fifo && av_fifo_read(s->itut_t35_fifo, &itut_t35, 1) >= 0)
+         av_buffer_unref(&itut_t35.payload_ref);
+     av_fifo_freep2(&s->itut_t35_fifo);
+ 
+     ff_cbs_fragment_free(&s->current_obu);
+     ff_cbs_close(&s->cbc);
++    ff_dovi_ctx_unref(&s->dovi);
+ 
+     return 0;
+ }
+ 
+ static int set_context_with_sequence(AVCodecContext *avctx,
+                                      const AV1RawSequenceHeader *seq)
+ {
+     int width = seq->max_frame_width_minus_1 + 1;
+     int height = seq->max_frame_height_minus_1 + 1;
+ 
+     avctx->profile = seq->seq_profile;
+     avctx->level = seq->seq_level_idx[0];
+ 
+     avctx->color_range =
+         seq->color_config.color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
+     avctx->color_primaries = seq->color_config.color_primaries;
+-    avctx->colorspace = seq->color_config.color_primaries;
++    avctx->colorspace = seq->color_config.matrix_coefficients;
+     avctx->color_trc = seq->color_config.transfer_characteristics;
+ 
+     switch (seq->color_config.chroma_sample_position) {
+     case AV1_CSP_VERTICAL:
+         avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
+         break;
+     case AV1_CSP_COLOCATED:
+         avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
+@@ -766,16 +776,19 @@ static int set_context_with_sequence(AVC
+             return ret;
+     }
+ 
+     if (seq->timing_info_present_flag)
+         avctx->framerate = ff_av1_framerate(1LL + seq->timing_info.num_ticks_per_picture_minus_1,
+                                             seq->timing_info.num_units_in_display_tick,
+                                             seq->timing_info.time_scale);
+ 
++    if (avctx->pix_fmt == AV_PIX_FMT_NONE)
++        avctx->pix_fmt = get_sw_pixel_format(avctx, seq);
++
+     return 0;
+ }
+ 
+ static int update_context_with_frame_header(AVCodecContext *avctx,
+                                             const AV1RawFrameHeader *header)
+ {
+     AVRational aspect_ratio;
+     int width = header->frame_width_minus_1 + 1;
+@@ -813,16 +826,17 @@ static const CodedBitstreamUnitType deco
+     AV1_OBU_TEMPORAL_DELIMITER,
+     AV1_OBU_TILE_GROUP,
+ };
+ 
+ static av_cold int av1_decode_init(AVCodecContext *avctx)
+ {
+     AV1DecContext *s = avctx->priv_data;
+     AV1RawSequenceHeader *seq;
++    const AVPacketSideData *sd;
+     int ret;
+ 
+     s->avctx = avctx;
+     s->pkt = avctx->internal->in_pkt;
+     s->pix_fmt = AV_PIX_FMT_NONE;
+ 
+     for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
+         s->ref[i].f = av_frame_alloc();
+@@ -864,22 +878,26 @@ static av_cold int av1_decode_init(AVCod
+         }
+ 
+         ret = set_context_with_sequence(avctx, seq);
+         if (ret < 0) {
+             av_log(avctx, AV_LOG_WARNING, "Failed to set decoder context.\n");
+             goto end;
+         }
+ 
+-        avctx->pix_fmt = get_sw_pixel_format(avctx, seq);
+-
+         end:
+         ff_cbs_fragment_reset(&s->current_obu);
+     }
+ 
++    s->dovi.logctx = avctx;
++    s->dovi.dv_profile = 10; // default for AV1
++    sd = ff_get_coded_side_data(avctx, AV_PKT_DATA_DOVI_CONF);
++    if (sd && sd->size > 0)
++        ff_dovi_update_cfg(&s->dovi, (AVDOVIDecoderConfigurationRecord *) sd->data);
++
+     return ret;
+ }
+ 
+ static int av1_frame_alloc(AVCodecContext *avctx, AV1Frame *f)
+ {
+     AV1DecContext *s = avctx->priv_data;
+     AV1RawFrameHeader *header= s->raw_frame_header;
+     AVFrame *frame;
+@@ -923,130 +941,168 @@ fail:
+     av1_frame_unref(f);
+     return ret;
+ }
+ 
+ static int export_itut_t35(AVCodecContext *avctx, AVFrame *frame,
+                            const AV1RawMetadataITUTT35 *itut_t35)
+ {
+     GetByteContext gb;
++    AV1DecContext *s = avctx->priv_data;
+     int ret, provider_code;
+ 
+     bytestream2_init(&gb, itut_t35->payload, itut_t35->payload_size);
+ 
+     provider_code = bytestream2_get_be16(&gb);
+     switch (provider_code) {
+-    case 0x31: { // atsc_provider_code
++    case ITU_T_T35_PROVIDER_CODE_ATSC: {
+         uint32_t user_identifier = bytestream2_get_be32(&gb);
+         switch (user_identifier) {
+         case MKBETAG('G', 'A', '9', '4'): { // closed captions
+             AVBufferRef *buf = NULL;
+ 
+             ret = ff_parse_a53_cc(&buf, gb.buffer, bytestream2_get_bytes_left(&gb));
+             if (ret < 0)
+                 return ret;
+             if (!ret)
+                 break;
+ 
+-            if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_A53_CC, buf))
+-                av_buffer_unref(&buf);
++            ret = ff_frame_new_side_data_from_buf(avctx, frame, AV_FRAME_DATA_A53_CC, &buf, NULL);
++            if (ret < 0)
++                return ret;
+ 
+             avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+             break;
+         }
+         default: // ignore unsupported identifiers
+             break;
+         }
+         break;
+     }
+-    case 0x3C: { // smpte_provider_code
++    case ITU_T_T35_PROVIDER_CODE_SMTPE: {
+         AVDynamicHDRPlus *hdrplus;
+         int provider_oriented_code = bytestream2_get_be16(&gb);
+         int application_identifier = bytestream2_get_byte(&gb);
+ 
+-        if (itut_t35->itu_t_t35_country_code != 0xB5 ||
++        if (itut_t35->itu_t_t35_country_code != ITU_T_T35_COUNTRY_CODE_US ||
+             provider_oriented_code != 1 || application_identifier != 4)
+             break;
+ 
+         hdrplus = av_dynamic_hdr_plus_create_side_data(frame);
+         if (!hdrplus)
+             return AVERROR(ENOMEM);
+ 
+         ret = av_dynamic_hdr_plus_from_t35(hdrplus, gb.buffer,
+                                            bytestream2_get_bytes_left(&gb));
+         if (ret < 0)
+             return ret;
+         break;
+     }
++    case ITU_T_T35_PROVIDER_CODE_DOLBY: {
++        int provider_oriented_code = bytestream2_get_be32(&gb);
++        if (itut_t35->itu_t_t35_country_code != ITU_T_T35_COUNTRY_CODE_US ||
++            provider_oriented_code != 0x800)
++            break;
++
++        ret = ff_dovi_rpu_parse(&s->dovi, gb.buffer, gb.buffer_end - gb.buffer,
++                                avctx->err_recognition);
++        if (ret < 0) {
++            av_log(avctx, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");
++            break; // ignore
++        }
++
++        ret = ff_dovi_attach_side_data(&s->dovi, frame);
++        if (ret < 0)
++            return ret;
++        break;
++    }
+     default: // ignore unsupported provider codes
+         break;
+     }
+ 
+     return 0;
+ }
+ 
+ static int export_metadata(AVCodecContext *avctx, AVFrame *frame)
+ {
+     AV1DecContext *s = avctx->priv_data;
+     AV1RawMetadataITUTT35 itut_t35;
+     int ret = 0;
+ 
+     if (s->mdcv) {
+-        AVMasteringDisplayMetadata *mastering = av_mastering_display_metadata_create_side_data(frame);
+-        if (!mastering)
+-            return AVERROR(ENOMEM);
++        AVMasteringDisplayMetadata *mastering;
++
++        ret = ff_decode_mastering_display_new(avctx, frame, &mastering);
++        if (ret < 0)
++            return ret;
+ 
+-        for (int i = 0; i < 3; i++) {
+-            mastering->display_primaries[i][0] = av_make_q(s->mdcv->primary_chromaticity_x[i], 1 << 16);
+-            mastering->display_primaries[i][1] = av_make_q(s->mdcv->primary_chromaticity_y[i], 1 << 16);
++        if (mastering) {
++            for (int i = 0; i < 3; i++) {
++                mastering->display_primaries[i][0] = av_make_q(s->mdcv->primary_chromaticity_x[i], 1 << 16);
++                mastering->display_primaries[i][1] = av_make_q(s->mdcv->primary_chromaticity_y[i], 1 << 16);
++            }
++            mastering->white_point[0] = av_make_q(s->mdcv->white_point_chromaticity_x, 1 << 16);
++            mastering->white_point[1] = av_make_q(s->mdcv->white_point_chromaticity_y, 1 << 16);
++
++            mastering->max_luminance = av_make_q(s->mdcv->luminance_max, 1 << 8);
++            mastering->min_luminance = av_make_q(s->mdcv->luminance_min, 1 << 14);
++
++            mastering->has_primaries = 1;
++            mastering->has_luminance = 1;
+         }
+-        mastering->white_point[0] = av_make_q(s->mdcv->white_point_chromaticity_x, 1 << 16);
+-        mastering->white_point[1] = av_make_q(s->mdcv->white_point_chromaticity_y, 1 << 16);
+-
+-        mastering->max_luminance = av_make_q(s->mdcv->luminance_max, 1 << 8);
+-        mastering->min_luminance = av_make_q(s->mdcv->luminance_min, 1 << 14);
+-
+-        mastering->has_primaries = 1;
+-        mastering->has_luminance = 1;
+     }
+ 
+     if (s->cll) {
+-        AVContentLightMetadata *light = av_content_light_metadata_create_side_data(frame);
+-        if (!light)
+-            return AVERROR(ENOMEM);
++        AVContentLightMetadata *light;
+ 
+-        light->MaxCLL = s->cll->max_cll;
+-        light->MaxFALL = s->cll->max_fall;
++        ret = ff_decode_content_light_new(avctx, frame, &light);
++        if (ret < 0)
++            return ret;
++
++        if (light) {
++            light->MaxCLL = s->cll->max_cll;
++            light->MaxFALL = s->cll->max_fall;
++        }
+     }
+ 
+     while (av_fifo_read(s->itut_t35_fifo, &itut_t35, 1) >= 0) {
+         if (ret >= 0)
+             ret = export_itut_t35(avctx, frame, &itut_t35);
+         av_buffer_unref(&itut_t35.payload_ref);
+     }
+ 
+     return ret;
+ }
+ 
+ static int export_film_grain(AVCodecContext *avctx, AVFrame *frame)
+ {
+     AV1DecContext *s = avctx->priv_data;
+     const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain;
++    const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(frame->format);
+     AVFilmGrainParams *fgp;
+     AVFilmGrainAOMParams *aom;
+ 
++    av_assert0(pixdesc);
+     if (!film_grain->apply_grain)
+         return 0;
+ 
+     fgp = av_film_grain_params_create_side_data(frame);
+     if (!fgp)
+         return AVERROR(ENOMEM);
+ 
+     fgp->type = AV_FILM_GRAIN_PARAMS_AV1;
+     fgp->seed = film_grain->grain_seed;
++    fgp->width = frame->width;
++    fgp->height = frame->height;
++    fgp->color_range = frame->color_range;
++    fgp->color_primaries = frame->color_primaries;
++    fgp->color_trc = frame->color_trc;
++    fgp->color_space = frame->colorspace;
++    fgp->subsampling_x = pixdesc->log2_chroma_w;
++    fgp->subsampling_y = pixdesc->log2_chroma_h;
+ 
+     aom = &fgp->codec.aom;
+     aom->chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma;
+     aom->scaling_shift = film_grain->grain_scaling_minus_8 + 8;
+     aom->ar_coeff_lag = film_grain->ar_coeff_lag;
+     aom->ar_coeff_shift = film_grain->ar_coeff_shift_minus_6 + 6;
+     aom->grain_scale_shift = film_grain->grain_scale_shift;
+     aom->overlap_flag = film_grain->overlap_flag;
+@@ -1169,16 +1225,33 @@ static int get_current_frame(AVCodecCont
+     if ((avctx->skip_frame >= AVDISCARD_NONINTRA &&
+             (s->raw_frame_header->frame_type != AV1_FRAME_KEY &&
+              s->raw_frame_header->frame_type != AV1_FRAME_INTRA_ONLY)) ||
+         (avctx->skip_frame >= AVDISCARD_NONKEY   &&
+              s->raw_frame_header->frame_type != AV1_FRAME_KEY) ||
+         avctx->skip_frame >= AVDISCARD_ALL)
+         return 0;
+ 
++    if (s->pix_fmt == AV_PIX_FMT_NONE) {
++        ret = get_pixel_format(avctx);
++        if (ret < 0) {
++            av_log(avctx, AV_LOG_ERROR, "Failed to get pixel format.\n");
++            return ret;
++        }
++
++        if (!ret && FF_HW_HAS_CB(avctx, decode_params)) {
++            ret = FF_HW_CALL(avctx, decode_params, AV1_OBU_SEQUENCE_HEADER,
++                             s->seq_data_ref->data, s->seq_data_ref->size);
++            if (ret < 0) {
++                av_log(avctx, AV_LOG_ERROR, "HW accel decode params fail.\n");
++                return ret;
++            }
++        }
++    }
++
+     ret = av1_frame_alloc(avctx, &s->cur_frame);
+     if (ret < 0) {
+         av_log(avctx, AV_LOG_ERROR,
+                "Failed to allocate space for current frame.\n");
+         return ret;
+     }
+ 
+     global_motion_params(s);
+@@ -1195,56 +1268,52 @@ static int av1_receive_frame_internal(AV
+     AV1RawTileGroup *raw_tile_group = NULL;
+     int i = 0, ret;
+ 
+     for (i = s->nb_unit; i < s->current_obu.nb_units; i++) {
+         CodedBitstreamUnit *unit = &s->current_obu.units[i];
+         AV1RawOBU *obu = unit->content;
+         const AV1RawOBUHeader *header;
+ 
++        av_log(avctx, AV_LOG_DEBUG, "OBU idx:%d, type:%d, content available:%d.\n", i, unit->type, !!obu);
++
++        if (unit->type == AV1_OBU_TILE_LIST) {
++            av_log(avctx, AV_LOG_ERROR, "Large scale tile decoding is unsupported.\n");
++            ret = AVERROR_PATCHWELCOME;
++            goto end;
++        }
++
+         if (!obu)
+             continue;
+ 
+         header = &obu->header;
+-        av_log(avctx, AV_LOG_DEBUG, "Obu idx:%d, obu type:%d.\n", i, unit->type);
+ 
+         switch (unit->type) {
+         case AV1_OBU_SEQUENCE_HEADER:
++            ret = av_buffer_replace(&s->seq_data_ref, unit->data_ref);
++            if (ret < 0)
++                goto end;
++
++            s->seq_data_ref->data = unit->data;
++            s->seq_data_ref->size = unit->data_size;
+             ff_refstruct_replace(&s->seq_ref, unit->content_ref);
+ 
+             s->raw_seq = &obu->obu.sequence_header;
+ 
+             ret = set_context_with_sequence(avctx, s->raw_seq);
+             if (ret < 0) {
+                 av_log(avctx, AV_LOG_ERROR, "Failed to set context.\n");
+                 s->raw_seq = NULL;
+                 goto end;
+             }
+ 
+             s->operating_point_idc = s->raw_seq->operating_point_idc[s->operating_point];
+ 
+-            if (s->pix_fmt == AV_PIX_FMT_NONE) {
+-                ret = get_pixel_format(avctx);
+-                if (ret < 0) {
+-                    av_log(avctx, AV_LOG_ERROR,
+-                           "Failed to get pixel format.\n");
+-                    s->raw_seq = NULL;
+-                    goto end;
+-                }
+-            }
++            s->pix_fmt = AV_PIX_FMT_NONE;
+ 
+-            if (FF_HW_HAS_CB(avctx, decode_params)) {
+-                ret = FF_HW_CALL(avctx, decode_params, unit->type,
+-                                 unit->data, unit->data_size);
+-                if (ret < 0) {
+-                    av_log(avctx, AV_LOG_ERROR, "HW accel decode params fail.\n");
+-                    s->raw_seq = NULL;
+-                    goto end;
+-                }
+-            }
+             break;
+         case AV1_OBU_REDUNDANT_FRAME_HEADER:
+             if (s->raw_frame_header)
+                 break;
+         // fall-through
+         case AV1_OBU_FRAME:
+         case AV1_OBU_FRAME_HEADER:
+             if (!s->raw_seq) {
+@@ -1411,16 +1480,18 @@ end:
+ 
+     if ((ret < 0 && ret != AVERROR(EAGAIN)) || s->current_obu.nb_units == i) {
+         if (ret < 0)
+             s->raw_frame_header = NULL;
+         av_packet_unref(s->pkt);
+         ff_cbs_fragment_reset(&s->current_obu);
+         s->nb_unit = 0;
+     }
++    if (!ret && !frame->buf[0])
++        ret = AVERROR(EAGAIN);
+ 
+     return ret;
+ }
+ 
+ static int av1_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+ {
+     AV1DecContext *s = avctx->priv_data;
+     int ret;
+@@ -1495,17 +1566,17 @@ const FFCodec ff_av1_decoder = {
+     CODEC_LONG_NAME("Alliance for Open Media AV1"),
+     .p.type                = AVMEDIA_TYPE_VIDEO,
+     .p.id                  = AV_CODEC_ID_AV1,
+     .priv_data_size        = sizeof(AV1DecContext),
+     .init                  = av1_decode_init,
+     .close                 = av1_decode_free,
+     FF_CODEC_RECEIVE_FRAME_CB(av1_receive_frame),
+     .p.capabilities        = AV_CODEC_CAP_DR1,
+-    .caps_internal         = FF_CODEC_CAP_INIT_CLEANUP,
++    .caps_internal         = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+     .flush                 = av1_decode_flush,
+     .p.profiles            = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
+     .p.priv_class          = &av1_class,
+     .hw_configs            = (const AVCodecHWConfigInternal *const []) {
+ #if CONFIG_AV1_DXVA2_HWACCEL
+         HWACCEL_DXVA2(av1),
+ #endif
+ #if CONFIG_AV1_D3D11VA_HWACCEL
+diff --git a/media/ffvpx/libavcodec/av1dec.h b/media/ffvpx/libavcodec/av1dec.h
+--- a/media/ffvpx/libavcodec/av1dec.h
++++ b/media/ffvpx/libavcodec/av1dec.h
+@@ -18,23 +18,25 @@
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #ifndef AVCODEC_AV1DEC_H
+ #define AVCODEC_AV1DEC_H
+ 
+ #include <stdint.h>
+ 
++#include "libavutil/buffer.h"
+ #include "libavutil/fifo.h"
+ #include "libavutil/frame.h"
+ #include "libavutil/pixfmt.h"
+ #include "avcodec.h"
+ #include "packet.h"
+ #include "cbs.h"
+ #include "cbs_av1.h"
++#include "dovi_rpu.h"
+ 
+ typedef struct AV1Frame {
+     AVFrame *f;
+ 
+     void *hwaccel_picture_private; ///< RefStruct reference
+ 
+     AV1RawOBU *header_ref; ///< RefStruct reference backing raw_frame_header.
+     AV1RawFrameHeader *raw_frame_header;
+@@ -64,26 +66,28 @@ typedef struct AV1DecContext {
+     const AVClass *class;
+     AVCodecContext *avctx;
+ 
+     enum AVPixelFormat pix_fmt;
+     CodedBitstreamContext *cbc;
+     CodedBitstreamFragment current_obu;
+     AVPacket *pkt;
+ 
++    AVBufferRef *seq_data_ref;
+     AV1RawOBU *seq_ref;    ///< RefStruct reference backing raw_seq
+     AV1RawSequenceHeader *raw_seq;
+     AV1RawOBU *header_ref; ///< RefStruct reference backing raw_frame_header
+     AV1RawFrameHeader *raw_frame_header;
+     TileGroupInfo *tile_group_info;
+ 
+     AV1RawOBU *cll_ref;    ///< RefStruct reference backing cll
+     AV1RawMetadataHDRCLL *cll;
+     AV1RawOBU *mdcv_ref;   ///< RefStruct reference backing mdcv
+     AV1RawMetadataHDRMDCV *mdcv;
++    DOVIContext dovi;
+     AVFifo *itut_t35_fifo;
+ 
+     uint16_t tile_num;
+     uint16_t tg_start;
+     uint16_t tg_end;
+ 
+     int operating_point_idc;
+ 
+diff --git a/media/ffvpx/libavcodec/avcodec.c b/media/ffvpx/libavcodec/avcodec.c
+--- a/media/ffvpx/libavcodec/avcodec.c
++++ b/media/ffvpx/libavcodec/avcodec.c
+@@ -49,16 +49,30 @@
+ 
+ /**
+  * Maximum size in bytes of extradata.
+  * This value was chosen such that every bit of the buffer is
+  * addressable by a 32-bit signed integer as used by get_bits.
+  */
+ #define FF_MAX_EXTRADATA_SIZE ((1 << 28) - AV_INPUT_BUFFER_PADDING_SIZE)
+ 
++const SideDataMap ff_sd_global_map[] = {
++    { AV_PKT_DATA_REPLAYGAIN ,                AV_FRAME_DATA_REPLAYGAIN },
++    { AV_PKT_DATA_DISPLAYMATRIX,              AV_FRAME_DATA_DISPLAYMATRIX },
++    { AV_PKT_DATA_SPHERICAL,                  AV_FRAME_DATA_SPHERICAL },
++    { AV_PKT_DATA_STEREO3D,                   AV_FRAME_DATA_STEREO3D },
++    { AV_PKT_DATA_AUDIO_SERVICE_TYPE,         AV_FRAME_DATA_AUDIO_SERVICE_TYPE },
++    { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA },
++    { AV_PKT_DATA_CONTENT_LIGHT_LEVEL,        AV_FRAME_DATA_CONTENT_LIGHT_LEVEL },
++    { AV_PKT_DATA_ICC_PROFILE,                AV_FRAME_DATA_ICC_PROFILE },
++    { AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT,AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT },
++    { AV_PKT_DATA_NB },
++};
++
++
+ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size)
+ {
+     size_t i;
+ 
+     for (i = 0; i < count; i++) {
+         size_t offset = i * size;
+         int r = func(c, FF_PTR_ADD((char *)arg, offset));
+         if (ret)
+@@ -236,36 +250,16 @@ int attribute_align_arg avcodec_open2(AV
+         goto free_and_end;
+     }
+     if (avctx->block_align < 0) {
+         av_log(avctx, AV_LOG_ERROR, "Invalid block align: %d\n", avctx->block_align);
+         ret = AVERROR(EINVAL);
+         goto free_and_end;
+     }
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    /* compat wrapper for old-style callers */
+-    if (avctx->channel_layout && !avctx->channels)
+-        avctx->channels = av_popcount64(avctx->channel_layout);
+-
+-    if ((avctx->channels && avctx->ch_layout.nb_channels != avctx->channels) ||
+-        (avctx->channel_layout && (avctx->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
+-                                   avctx->ch_layout.u.mask != avctx->channel_layout))) {
+-        av_channel_layout_uninit(&avctx->ch_layout);
+-        if (avctx->channel_layout) {
+-            av_channel_layout_from_mask(&avctx->ch_layout, avctx->channel_layout);
+-        } else {
+-            avctx->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+-        }
+-        avctx->ch_layout.nb_channels = avctx->channels;
+-    }
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+     /* AV_CODEC_CAP_CHANNEL_CONF is a decoder-only flag; so the code below
+      * in particular checks that nb_channels is set for all audio encoders. */
+     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && !avctx->ch_layout.nb_channels
+         && !(codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)) {
+         av_log(avctx, AV_LOG_ERROR, "%s requires channel layout to be set\n",
+                av_codec_is_decoder(codec) ? "Decoder" : "Encoder");
+         ret = AVERROR(EINVAL);
+         goto free_and_end;
+@@ -277,21 +271,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
+     }
+     if (avctx->ch_layout.nb_channels > FF_SANE_NB_CHANNELS) {
+         av_log(avctx, AV_LOG_ERROR, "Too many channels: %d\n", avctx->ch_layout.nb_channels);
+         ret = AVERROR(EINVAL);
+         goto free_and_end;
+     }
+ 
+     avctx->frame_num = 0;
+-#if FF_API_AVCTX_FRAME_NUMBER
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    avctx->frame_number = avctx->frame_num;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     avctx->codec_descriptor = avcodec_descriptor_get(avctx->codec_id);
+ 
+     if ((avctx->codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) &&
+         avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+         const char *codec_string = av_codec_is_encoder(codec) ? "encoder" : "decoder";
+         const AVCodec *codec2;
+         av_log(avctx, AV_LOG_ERROR,
+                "The %s '%s' is experimental but experimental codecs are not enabled, "
+@@ -345,25 +334,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
+     }
+ 
+     ret=0;
+ 
+     if (av_codec_is_decoder(avctx->codec)) {
+         if (!avctx->bit_rate)
+             avctx->bit_rate = get_bit_rate(avctx);
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        /* update the deprecated fields for old-style callers */
+-        avctx->channels = avctx->ch_layout.nb_channels;
+-        avctx->channel_layout = avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
+-                                avctx->ch_layout.u.mask : 0;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+         /* validate channel layout from the decoder */
+         if ((avctx->ch_layout.nb_channels && !av_channel_layout_check(&avctx->ch_layout)) ||
+             avctx->ch_layout.nb_channels > FF_SANE_NB_CHANNELS) {
+             ret = AVERROR(EINVAL);
+             goto free_and_end;
+         }
+         if (avctx->bits_per_coded_sample < 0) {
+             ret = AVERROR(EINVAL);
+@@ -372,17 +352,17 @@ FF_ENABLE_DEPRECATION_WARNINGS
+     }
+     if (codec->priv_class)
+         av_assert0(*(const AVClass **)avctx->priv_data == codec->priv_class);
+ 
+ end:
+ 
+     return ret;
+ free_and_end:
+-    avcodec_close(avctx);
++    ff_codec_close(avctx);
+     goto end;
+ }
+ 
+ void avcodec_flush_buffers(AVCodecContext *avctx)
+ {
+     AVCodecInternal *avci = avctx->internal;
+ 
+     if (av_codec_is_encoder(avctx->codec)) {
+@@ -427,22 +407,22 @@ void avsubtitle_free(AVSubtitle *sub)
+         av_freep(&sub->rects[i]);
+     }
+ 
+     av_freep(&sub->rects);
+ 
+     memset(sub, 0, sizeof(*sub));
+ }
+ 
+-av_cold int avcodec_close(AVCodecContext *avctx)
++av_cold void ff_codec_close(AVCodecContext *avctx)
+ {
+     int i;
+ 
+     if (!avctx)
+-        return 0;
++        return;
+ 
+     if (avcodec_is_open(avctx)) {
+         AVCodecInternal *avci = avctx->internal;
+ 
+         if (CONFIG_FRAME_THREAD_ENCODER &&
+             avci->frame_thread_encoder && avctx->thread_count > 1) {
+             ff_frame_thread_encoder_free(avctx);
+         }
+@@ -492,19 +472,25 @@ av_cold int avcodec_close(AVCodecContext
+     if (av_codec_is_encoder(avctx->codec)) {
+         av_freep(&avctx->extradata);
+         avctx->extradata_size = 0;
+     } else if (av_codec_is_decoder(avctx->codec))
+         av_freep(&avctx->subtitle_header);
+ 
+     avctx->codec = NULL;
+     avctx->active_thread_type = 0;
++}
+ 
++#if FF_API_AVCODEC_CLOSE
++int avcodec_close(AVCodecContext *avctx)
++{
++    ff_codec_close(avctx);
+     return 0;
+ }
++#endif
+ 
+ static const char *unknown_if_null(const char *str)
+ {
+     return str ? str : "unknown";
+ }
+ 
+ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
+ {
+@@ -614,16 +600,17 @@ void avcodec_string(char *buf, int buf_s
+             }
+         }
+ 
+         if (enc->width) {
+             av_bprintf(&bprint, "%s%dx%d", new_line ? separator : ", ",
+                        enc->width, enc->height);
+ 
+             if (av_log_get_level() >= AV_LOG_VERBOSE &&
++                enc->coded_width && enc->coded_height &&
+                 (enc->width != enc->coded_width ||
+                  enc->height != enc->coded_height))
+                 av_bprintf(&bprint, " (%dx%d)",
+                            enc->coded_width, enc->coded_height);
+ 
+             if (enc->sample_aspect_ratio.num) {
+                 av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
+                           enc->width * (int64_t)enc->sample_aspect_ratio.num,
+diff --git a/media/ffvpx/libavcodec/avcodec.h b/media/ffvpx/libavcodec/avcodec.h
+--- a/media/ffvpx/libavcodec/avcodec.h
++++ b/media/ffvpx/libavcodec/avcodec.h
+@@ -182,22 +182,26 @@ struct AVCodecParameters;
+  * @defgroup lavc_core Core functions/structures.
+  * @ingroup libavc
+  *
+  * Basic definitions, functions for querying libavcodec capabilities,
+  * allocating core structures, etc.
+  * @{
+  */
+ 
++#if FF_API_BUFFER_MIN_SIZE
+ /**
+  * @ingroup lavc_encoding
+  * minimum encoding buffer size
+  * Used to avoid some checks during header writing.
++ * @deprecated Unused: avcodec_receive_packet() does not work
++ *             with preallocated packet buffers.
+  */
+ #define AV_INPUT_BUFFER_MIN_SIZE 16384
++#endif
+ 
+ /**
+  * @ingroup lavc_encoding
+  */
+ typedef struct RcOverride{
+     int start_frame;
+     int end_frame;
+     int qscale; // If this is 0 then quality_factor will be used instead.
+@@ -486,39 +490,16 @@ typedef struct AVCodecContext {
+      * the average bitrate
+      * - encoding: Set by user; unused for constant quantizer encoding.
+      * - decoding: Set by user, may be overwritten by libavcodec
+      *             if this info is available in the stream
+      */
+     int64_t bit_rate;
+ 
+     /**
+-     * number of bits the bitstream is allowed to diverge from the reference.
+-     *           the reference can be CBR (for CBR pass1) or VBR (for pass2)
+-     * - encoding: Set by user; unused for constant quantizer encoding.
+-     * - decoding: unused
+-     */
+-    int bit_rate_tolerance;
+-
+-    /**
+-     * Global quality for codecs which cannot change it per frame.
+-     * This should be proportional to MPEG-1/2/4 qscale.
+-     * - encoding: Set by user.
+-     * - decoding: unused
+-     */
+-    int global_quality;
+-
+-    /**
+-     * - encoding: Set by user.
+-     * - decoding: unused
+-     */
+-    int compression_level;
+-#define FF_COMPRESSION_DEFAULT -1
+-
+-    /**
+      * AV_CODEC_FLAG_*.
+      * - encoding: Set by user.
+      * - decoding: Set by user.
+      */
+     int flags;
+ 
+     /**
+      * AV_CODEC_FLAG2_*
+@@ -557,16 +538,32 @@ typedef struct AVCodecContext {
+      * vop_time_increment_resolution and fixed_vop_rate
+      * (fixed_vop_rate == 0 implies that it is different from the framerate)
+      *
+      * - encoding: MUST be set by user.
+      * - decoding: unused.
+      */
+     AVRational time_base;
+ 
++    /**
++     * Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
++     * - encoding: unused.
++     * - decoding: set by user.
++     */
++    AVRational pkt_timebase;
++
++    /**
++     * - decoding: For codecs that store a framerate value in the compressed
++     *             bitstream, the decoder may export it here. { 0, 1} when
++     *             unknown.
++     * - encoding: May be used to signal the framerate of CFR content to an
++     *             encoder.
++     */
++    AVRational framerate;
++
+ #if FF_API_TICKS_PER_FRAME
+     /**
+      * For some codecs, the time base is closer to the field rate than the frame rate.
+      * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration
+      * if no telecine is used ...
+      *
+      * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
+      *
+@@ -631,21 +628,23 @@ typedef struct AVCodecContext {
+      * - encoding: unused
+      * - decoding: May be set by the user before opening the decoder if known
+      *             e.g. from the container. During decoding, the decoder may
+      *             overwrite those values as required while parsing the data.
+      */
+     int coded_width, coded_height;
+ 
+     /**
+-     * the number of pictures in a group of pictures, or 0 for intra_only
++     * sample aspect ratio (0 if unknown)
++     * That is the width of a pixel divided by the height of the pixel.
++     * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
+      * - encoding: Set by user.
+-     * - decoding: unused
++     * - decoding: Set by libavcodec.
+      */
+-    int gop_size;
++    AVRational sample_aspect_ratio;
+ 
+     /**
+      * Pixel format, see AV_PIX_FMT_xxx.
+      * May be set by the demuxer if known from headers.
+      * May be overridden by the decoder if it knows better.
+      *
+      * @note This field may not match the value of the last
+      * AVFrame output by avcodec_receive_frame() due frame
+@@ -653,16 +652,92 @@ typedef struct AVCodecContext {
+      *
+      * - encoding: Set by user.
+      * - decoding: Set by user if known, overridden by libavcodec while
+      *             parsing the data.
+      */
+     enum AVPixelFormat pix_fmt;
+ 
+     /**
++     * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
++     * - encoding: unused.
++     * - decoding: Set by libavcodec before calling get_format()
++     */
++    enum AVPixelFormat sw_pix_fmt;
++
++    /**
++     * Chromaticity coordinates of the source primaries.
++     * - encoding: Set by user
++     * - decoding: Set by libavcodec
++     */
++    enum AVColorPrimaries color_primaries;
++
++    /**
++     * Color Transfer Characteristic.
++     * - encoding: Set by user
++     * - decoding: Set by libavcodec
++     */
++    enum AVColorTransferCharacteristic color_trc;
++
++    /**
++     * YUV colorspace type.
++     * - encoding: Set by user
++     * - decoding: Set by libavcodec
++     */
++    enum AVColorSpace colorspace;
++
++    /**
++     * MPEG vs JPEG YUV range.
++     * - encoding: Set by user to override the default output color range value,
++     *   If not specified, libavcodec sets the color range depending on the
++     *   output format.
++     * - decoding: Set by libavcodec, can be set by the user to propagate the
++     *   color range to components reading from the decoder context.
++     */
++    enum AVColorRange color_range;
++
++    /**
++     * This defines the location of chroma samples.
++     * - encoding: Set by user
++     * - decoding: Set by libavcodec
++     */
++    enum AVChromaLocation chroma_sample_location;
++
++    /** Field order
++     * - encoding: set by libavcodec
++     * - decoding: Set by user.
++     */
++    enum AVFieldOrder field_order;
++
++    /**
++     * number of reference frames
++     * - encoding: Set by user.
++     * - decoding: Set by lavc.
++     */
++    int refs;
++
++    /**
++     * Size of the frame reordering buffer in the decoder.
++     * For MPEG-2 it is 1 IPB or 0 low delay IP.
++     * - encoding: Set by libavcodec.
++     * - decoding: Set by libavcodec.
++     */
++    int has_b_frames;
++
++    /**
++     * slice flags
++     * - encoding: unused
++     * - decoding: Set by user.
++     */
++    int slice_flags;
++#define SLICE_FLAG_CODED_ORDER    0x0001 ///< draw_horiz_band() is called in coded order instead of display
++#define SLICE_FLAG_ALLOW_FIELD    0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics)
++#define SLICE_FLAG_ALLOW_PLANE    0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
++
++    /**
+      * If non NULL, 'draw_horiz_band' is called by the libavcodec
+      * decoder to draw a horizontal band. It improves cache usage. Not
+      * all codecs can do that. You must check the codec capabilities
+      * beforehand.
+      * When multithreading is used, it may be called from multiple threads
+      * at the same time; threads might draw different parts of the same AVFrame,
+      * or multiple AVFrames, and there is no guarantee that slices will be drawn
+      * in order.
+@@ -731,24 +806,16 @@ typedef struct AVCodecContext {
+     /**
+      * qscale offset between IP and B-frames
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     float b_quant_offset;
+ 
+     /**
+-     * Size of the frame reordering buffer in the decoder.
+-     * For MPEG-2 it is 1 IPB or 0 low delay IP.
+-     * - encoding: Set by libavcodec.
+-     * - decoding: Set by libavcodec.
+-     */
+-    int has_b_frames;
+-
+-    /**
+      * qscale factor between P- and I-frames
+      * If > 0 then the last P-frame quantizer will be used (q = lastp_q * factor + offset).
+      * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     float i_quant_factor;
+ 
+@@ -789,42 +856,22 @@ typedef struct AVCodecContext {
+ 
+     /**
+      * darkness masking (0-> disabled)
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     float dark_masking;
+ 
+-#if FF_API_SLICE_OFFSET
+     /**
+-     * slice count
+-     * - encoding: Set by libavcodec.
+-     * - decoding: Set by user (or 0).
++     * noise vs. sse weight for the nsse comparison function
++     * - encoding: Set by user.
++     * - decoding: unused
+      */
+-    attribute_deprecated
+-    int slice_count;
+-
+-    /**
+-     * slice offsets in the frame in bytes
+-     * - encoding: Set/allocated by libavcodec.
+-     * - decoding: Set/allocated by user (or NULL).
+-     */
+-    attribute_deprecated
+-    int *slice_offset;
+-#endif
+-
+-    /**
+-     * sample aspect ratio (0 if unknown)
+-     * That is the width of a pixel divided by the height of the pixel.
+-     * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
+-     * - encoding: Set by user.
+-     * - decoding: Set by libavcodec.
+-     */
+-    AVRational sample_aspect_ratio;
++     int nsse_weight;
+ 
+     /**
+      * motion estimation comparison function
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     int me_cmp;
+     /**
+@@ -903,26 +950,16 @@ typedef struct AVCodecContext {
+      * If 0 then no limit.
+      *
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     int me_range;
+ 
+     /**
+-     * slice flags
+-     * - encoding: unused
+-     * - decoding: Set by user.
+-     */
+-    int slice_flags;
+-#define SLICE_FLAG_CODED_ORDER    0x0001 ///< draw_horiz_band() is called in coded order instead of display
+-#define SLICE_FLAG_ALLOW_FIELD    0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics)
+-#define SLICE_FLAG_ALLOW_PLANE    0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
+-
+-    /**
+      * macroblock decision mode
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     int mb_decision;
+ #define FF_MB_DECISION_SIMPLE 0        ///< uses mb_cmp
+ #define FF_MB_DECISION_BITS   1        ///< chooses the one which needs the fewest bits
+ #define FF_MB_DECISION_RD     2        ///< rate distortion
+@@ -941,37 +978,30 @@ typedef struct AVCodecContext {
+      * Must be allocated with the av_malloc() family of functions, and will be freed in
+      * avcodec_free_context().
+      * - encoding: Set/allocated by user, freed by libavcodec. Can be NULL.
+      * - decoding: Set/allocated/freed by libavcodec.
+      */
+     uint16_t *inter_matrix;
+ 
+     /**
++     * custom intra quantization matrix
++     * - encoding: Set by user, can be NULL.
++     * - decoding: unused.
++     */
++    uint16_t *chroma_intra_matrix;
++
++    /**
+      * precision of the intra DC coefficient - 8
+      * - encoding: Set by user.
+      * - decoding: Set by libavcodec
+      */
+     int intra_dc_precision;
+ 
+     /**
+-     * Number of macroblock rows at the top which are skipped.
+-     * - encoding: unused
+-     * - decoding: Set by user.
+-     */
+-    int skip_top;
+-
+-    /**
+-     * Number of macroblock rows at the bottom which are skipped.
+-     * - encoding: unused
+-     * - decoding: Set by user.
+-     */
+-    int skip_bottom;
+-
+-    /**
+      * minimum MB Lagrange multiplier
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     int mb_lmin;
+ 
+     /**
+      * maximum MB Lagrange multiplier
+@@ -989,177 +1019,132 @@ typedef struct AVCodecContext {
+     /**
+      * minimum GOP size
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     int keyint_min;
+ 
+     /**
+-     * number of reference frames
++     * the number of pictures in a group of pictures, or 0 for intra_only
+      * - encoding: Set by user.
+-     * - decoding: Set by lavc.
++     * - decoding: unused
+      */
+-    int refs;
++    int gop_size;
+ 
+     /**
+      * Note: Value depends upon the compare function used for fullpel ME.
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     int mv0_threshold;
+ 
+     /**
+-     * Chromaticity coordinates of the source primaries.
+-     * - encoding: Set by user
+-     * - decoding: Set by libavcodec
+-     */
+-    enum AVColorPrimaries color_primaries;
+-
+-    /**
+-     * Color Transfer Characteristic.
+-     * - encoding: Set by user
+-     * - decoding: Set by libavcodec
+-     */
+-    enum AVColorTransferCharacteristic color_trc;
+-
+-    /**
+-     * YUV colorspace type.
+-     * - encoding: Set by user
+-     * - decoding: Set by libavcodec
+-     */
+-    enum AVColorSpace colorspace;
+-
+-    /**
+-     * MPEG vs JPEG YUV range.
+-     * - encoding: Set by user to override the default output color range value,
+-     *   If not specified, libavcodec sets the color range depending on the
+-     *   output format.
+-     * - decoding: Set by libavcodec, can be set by the user to propagate the
+-     *   color range to components reading from the decoder context.
+-     */
+-    enum AVColorRange color_range;
+-
+-    /**
+-     * This defines the location of chroma samples.
+-     * - encoding: Set by user
+-     * - decoding: Set by libavcodec
+-     */
+-    enum AVChromaLocation chroma_sample_location;
+-
+-    /**
+      * Number of slices.
+      * Indicates number of picture subdivisions. Used for parallelized
+      * decoding.
+      * - encoding: Set by user
+      * - decoding: unused
+      */
+     int slices;
+ 
+-    /** Field order
+-     * - encoding: set by libavcodec
+-     * - decoding: Set by user.
+-     */
+-    enum AVFieldOrder field_order;
+-
+     /* audio only */
+     int sample_rate; ///< samples per second
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-    /**
+-     * number of audio channels
+-     * @deprecated use ch_layout.nb_channels
+-     */
+-    attribute_deprecated
+-    int channels;
+-#endif
+-
+     /**
+      * audio sample format
+      * - encoding: Set by user.
+      * - decoding: Set by libavcodec.
+      */
+     enum AVSampleFormat sample_fmt;  ///< sample format
+ 
++    /**
++     * Audio channel layout.
++     * - encoding: must be set by the caller, to one of AVCodec.ch_layouts.
++     * - decoding: may be set by the caller if known e.g. from the container.
++     *             The decoder can then override during decoding as needed.
++     */
++    AVChannelLayout ch_layout;
++
+     /* The following data should not be initialized. */
+     /**
+      * Number of samples per channel in an audio frame.
+      *
+      * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame
+      *   except the last must contain exactly frame_size samples per channel.
+      *   May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the
+      *   frame size is not restricted.
+      * - decoding: may be set by some decoders to indicate constant frame size
+      */
+     int frame_size;
+ 
+-#if FF_API_AVCTX_FRAME_NUMBER
+-    /**
+-     * Frame counter, set by libavcodec.
+-     *
+-     * - decoding: total number of frames returned from the decoder so far.
+-     * - encoding: total number of frames passed to the encoder so far.
+-     *
+-     *   @note the counter is not incremented if encoding/decoding resulted in
+-     *   an error.
+-     *   @deprecated use frame_num instead
+-     */
+-    attribute_deprecated
+-    int frame_number;
+-#endif
+-
+     /**
+      * number of bytes per packet if constant and known or 0
+      * Used by some WAV based audio codecs.
+      */
+     int block_align;
+ 
+     /**
+      * Audio cutoff bandwidth (0 means "automatic")
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+     int cutoff;
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-    /**
+-     * Audio channel layout.
+-     * - encoding: set by user.
+-     * - decoding: set by user, may be overwritten by libavcodec.
+-     * @deprecated use ch_layout
+-     */
+-    attribute_deprecated
+-    uint64_t channel_layout;
+-
+-    /**
+-     * Request decoder to use this channel layout if it can (0 for default)
+-     * - encoding: unused
+-     * - decoding: Set by user.
+-     * @deprecated use "downmix" codec private option
+-     */
+-    attribute_deprecated
+-    uint64_t request_channel_layout;
+-#endif
+-
+     /**
+      * Type of service that the audio stream conveys.
+      * - encoding: Set by user.
+      * - decoding: Set by libavcodec.
+      */
+     enum AVAudioServiceType audio_service_type;
+ 
+     /**
+      * desired sample format
+      * - encoding: Not used.
+      * - decoding: Set by user.
+      * Decoder will decode to this format if it can.
+      */
+     enum AVSampleFormat request_sample_fmt;
+ 
+     /**
++     * Audio only. The number of "priming" samples (padding) inserted by the
++     * encoder at the beginning of the audio. I.e. this number of leading
++     * decoded samples must be discarded by the caller to get the original audio
++     * without leading padding.
++     *
++     * - decoding: unused
++     * - encoding: Set by libavcodec. The timestamps on the output packets are
++     *             adjusted by the encoder so that they always refer to the
++     *             first sample of the data actually contained in the packet,
++     *             including any added padding.  E.g. if the timebase is
++     *             1/samplerate and the timestamp of the first input sample is
++     *             0, the timestamp of the first output packet will be
++     *             -initial_padding.
++     */
++    int initial_padding;
++
++    /**
++     * Audio only. The amount of padding (in samples) appended by the encoder to
++     * the end of the audio. I.e. this number of decoded samples must be
++     * discarded by the caller from the end of the stream to get the original
++     * audio without any trailing padding.
++     *
++     * - decoding: unused
++     * - encoding: unused
++     */
++    int trailing_padding;
++
++    /**
++     * Number of samples to skip after a discontinuity
++     * - decoding: unused
++     * - encoding: set by libavcodec
++     */
++    int seek_preroll;
++
++    /**
+      * This callback is called at the beginning of each frame to get data
+      * buffer(s) for it. There may be one contiguous buffer for all the data or
+      * there may be a buffer per each data plane or anything in between. What
+      * this means is, you may set however many entries in buf[] you feel necessary.
+      * Each buffer must be reference-counted using the AVBuffer API (see description
+      * of buf[] below).
+      *
+      * The following fields will be set in the frame before this callback is
+@@ -1232,16 +1217,39 @@ typedef struct AVCodecContext {
+      * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
+      *
+      * - encoding: unused
+      * - decoding: Set by libavcodec, user can override.
+      */
+     int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
+ 
+     /* - encoding parameters */
++    /**
++     * number of bits the bitstream is allowed to diverge from the reference.
++     *           the reference can be CBR (for CBR pass1) or VBR (for pass2)
++     * - encoding: Set by user; unused for constant quantizer encoding.
++     * - decoding: unused
++     */
++    int bit_rate_tolerance;
++
++    /**
++     * Global quality for codecs which cannot change it per frame.
++     * This should be proportional to MPEG-1/2/4 qscale.
++     * - encoding: Set by user.
++     * - decoding: unused
++     */
++    int global_quality;
++
++    /**
++     * - encoding: Set by user.
++     * - decoding: unused
++     */
++    int compression_level;
++#define FF_COMPRESSION_DEFAULT -1
++
+     float qcompress;  ///< amount of qscale change between easy & hard scenes (0.0-1.0)
+     float qblur;      ///< amount of qscale smoothing over time (0.0-1.0)
+ 
+     /**
+      * minimum quantizer
+      * - encoding: Set by user.
+      * - decoding: unused
+      */
+@@ -1406,32 +1414,16 @@ typedef struct AVCodecContext {
+      * Error recognition; may misdetect some more or less valid parts as errors.
+      * This is a bitfield of the AV_EF_* values defined in defs.h.
+      *
+      * - encoding: Set by user.
+      * - decoding: Set by user.
+      */
+     int err_recognition;
+ 
+-#if FF_API_REORDERED_OPAQUE
+-    /**
+-     * opaque 64-bit number (generally a PTS) that will be reordered and
+-     * output in AVFrame.reordered_opaque
+-     * - encoding: Set by libavcodec to the reordered_opaque of the input
+-     *             frame corresponding to the last returned packet. Only
+-     *             supported by encoders with the
+-     *             AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability.
+-     * - decoding: Set by user.
+-     *
+-     * @deprecated Use AV_CODEC_FLAG_COPY_OPAQUE instead
+-     */
+-    attribute_deprecated
+-    int64_t reordered_opaque;
+-#endif
+-
+     /**
+      * Hardware accelerator in use
+      * - encoding: unused.
+      * - decoding: Set by libavcodec
+      */
+     const struct AVHWAccel *hwaccel;
+ 
+     /**
+@@ -1454,16 +1446,85 @@ typedef struct AVCodecContext {
+      *             valid until avcodec_free_context().
+      * - decoding: May be set by the caller in the get_format() callback.
+      *             Must remain valid until the next get_format() call,
+      *             or avcodec_free_context() (whichever comes first).
+      */
+     void *hwaccel_context;
+ 
+     /**
++     * A reference to the AVHWFramesContext describing the input (for encoding)
++     * or output (decoding) frames. The reference is set by the caller and
++     * afterwards owned (and freed) by libavcodec - it should never be read by
++     * the caller after being set.
++     *
++     * - decoding: This field should be set by the caller from the get_format()
++     *             callback. The previous reference (if any) will always be
++     *             unreffed by libavcodec before the get_format() call.
++     *
++     *             If the default get_buffer2() is used with a hwaccel pixel
++     *             format, then this AVHWFramesContext will be used for
++     *             allocating the frame buffers.
++     *
++     * - encoding: For hardware encoders configured to use a hwaccel pixel
++     *             format, this field should be set by the caller to a reference
++     *             to the AVHWFramesContext describing input frames.
++     *             AVHWFramesContext.format must be equal to
++     *             AVCodecContext.pix_fmt.
++     *
++     *             This field should be set before avcodec_open2() is called.
++     */
++    AVBufferRef *hw_frames_ctx;
++
++    /**
++     * A reference to the AVHWDeviceContext describing the device which will
++     * be used by a hardware encoder/decoder.  The reference is set by the
++     * caller and afterwards owned (and freed) by libavcodec.
++     *
++     * This should be used if either the codec device does not require
++     * hardware frames or any that are used are to be allocated internally by
++     * libavcodec.  If the user wishes to supply any of the frames used as
++     * encoder input or decoder output then hw_frames_ctx should be used
++     * instead.  When hw_frames_ctx is set in get_format() for a decoder, this
++     * field will be ignored while decoding the associated stream segment, but
++     * may again be used on a following one after another get_format() call.
++     *
++     * For both encoders and decoders this field should be set before
++     * avcodec_open2() is called and must not be written to thereafter.
++     *
++     * Note that some decoders may require this field to be set initially in
++     * order to support hw_frames_ctx at all - in that case, all frames
++     * contexts used must be created on the same device.
++     */
++    AVBufferRef *hw_device_ctx;
++
++    /**
++     * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated
++     * decoding (if active).
++     * - encoding: unused
++     * - decoding: Set by user (either before avcodec_open2(), or in the
++     *             AVCodecContext.get_format callback)
++     */
++    int hwaccel_flags;
++
++    /**
++     * Video decoding only.  Sets the number of extra hardware frames which
++     * the decoder will allocate for use by the caller.  This must be set
++     * before avcodec_open2() is called.
++     *
++     * Some hardware decoders require all frames that they will use for
++     * output to be defined in advance before decoding starts.  For such
++     * decoders, the hardware frame pool must therefore be of a fixed size.
++     * The extra frames set here are on top of any number that the decoder
++     * needs internally in order to operate normally (for example, frames
++     * used as reference pictures).
++     */
++    int extra_hw_frames;
++
++    /**
+      * error
+      * - encoding: Set by libavcodec if flags & AV_CODEC_FLAG_PSNR.
+      * - decoding: unused
+      */
+     uint64_t error[AV_NUM_DATA_POINTERS];
+ 
+     /**
+      * DCT algorithm, see FF_DCT_* below
+@@ -1491,20 +1552,16 @@ typedef struct AVCodecContext {
+ #define FF_IDCT_ARM           7
+ #define FF_IDCT_ALTIVEC       8
+ #define FF_IDCT_SIMPLEARM     10
+ #define FF_IDCT_XVID          14
+ #define FF_IDCT_SIMPLEARMV5TE 16
+ #define FF_IDCT_SIMPLEARMV6   17
+ #define FF_IDCT_FAAN          20
+ #define FF_IDCT_SIMPLENEON    22
+-#if FF_API_IDCT_NONE
+-// formerly used by xvmc
+-#define FF_IDCT_NONE          24
+-#endif
+ #define FF_IDCT_SIMPLEAUTO    128
+ 
+     /**
+      * bits per sample/pixel from the demuxer (needed for huffyuv).
+      * - encoding: Set by libavcodec.
+      * - decoding: Set by user.
+      */
+      int bits_per_coded_sample;
+@@ -1512,23 +1569,16 @@ typedef struct AVCodecContext {
+     /**
+      * Bits per sample/pixel of internal libavcodec pixel/sample format.
+      * - encoding: set by user.
+      * - decoding: set by libavcodec.
+      */
+     int bits_per_raw_sample;
+ 
+     /**
+-     * low resolution decoding, 1-> 1/2 size, 2->1/4 size
+-     * - encoding: unused
+-     * - decoding: Set by user.
+-     */
+-     int lowres;
+-
+-    /**
+      * thread count
+      * is used to decide how many independent tasks should be passed to execute()
+      * - encoding: Set by user.
+      * - decoding: Set by user.
+      */
+     int thread_count;
+ 
+     /**
+@@ -1576,23 +1626,16 @@ typedef struct AVCodecContext {
+      * @return always 0 currently, but code should handle a future improvement where when any call to func
+      *         returns < 0 no further calls to func may be done and < 0 is returned.
+      * - encoding: Set by libavcodec, user can override.
+      * - decoding: Set by libavcodec, user can override.
+      */
+     int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
+ 
+     /**
+-     * noise vs. sse weight for the nsse comparison function
+-     * - encoding: Set by user.
+-     * - decoding: unused
+-     */
+-     int nsse_weight;
+-
+-    /**
+      * profile
+      * - encoding: Set by user.
+      * - decoding: Set by libavcodec.
+      * See the AV_PROFILE_* defines in defs.h.
+      */
+      int profile;
+ #if FF_API_FF_PROFILE_LEVEL
+     /** @deprecated The following defines are deprecated; use AV_PROFILE_*
+@@ -1740,16 +1783,26 @@ typedef struct AVCodecContext {
+      int level;
+ #if FF_API_FF_PROFILE_LEVEL
+     /** @deprecated The following define is deprecated; use AV_LEVEL_UNKOWN
+      * in defs.h instead. */
+ #define FF_LEVEL_UNKNOWN -99
+ #endif
+ 
+     /**
++     * Properties of the stream that gets decoded
++     * - encoding: unused
++     * - decoding: set by libavcodec
++     */
++    unsigned properties;
++#define FF_CODEC_PROPERTY_LOSSLESS        0x00000001
++#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002
++#define FF_CODEC_PROPERTY_FILM_GRAIN      0x00000004
++
++    /**
+      * Skip loop filtering for selected frames.
+      * - encoding: unused
+      * - decoding: Set by user.
+      */
+     enum AVDiscard skip_loop_filter;
+ 
+     /**
+      * Skip IDCT/dequantization for selected frames.
+@@ -1761,84 +1814,58 @@ typedef struct AVCodecContext {
+     /**
+      * Skip decoding for selected frames.
+      * - encoding: unused
+      * - decoding: Set by user.
+      */
+     enum AVDiscard skip_frame;
+ 
+     /**
+-     * Header containing style information for text subtitles.
+-     * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
+-     * [Script Info] and [V4+ Styles] section, plus the [Events] line and
+-     * the Format line following. It shouldn't include any Dialogue line.
+-     * - encoding: Set/allocated/freed by user (before avcodec_open2())
+-     * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2())
++     * Skip processing alpha if supported by codec.
++     * Note that if the format uses pre-multiplied alpha (common with VP6,
++     * and recommended due to better video quality/compression)
++     * the image will look as if alpha-blended onto a black background.
++     * However for formats that do not use pre-multiplied alpha
++     * there might be serious artefacts (though e.g. libswscale currently
++     * assumes pre-multiplied alpha anyway).
++     *
++     * - decoding: set by user
++     * - encoding: unused
+      */
+-    uint8_t *subtitle_header;
+-    int subtitle_header_size;
++    int skip_alpha;
+ 
+     /**
+-     * Audio only. The number of "priming" samples (padding) inserted by the
+-     * encoder at the beginning of the audio. I.e. this number of leading
+-     * decoded samples must be discarded by the caller to get the original audio
+-     * without leading padding.
+-     *
+-     * - decoding: unused
+-     * - encoding: Set by libavcodec. The timestamps on the output packets are
+-     *             adjusted by the encoder so that they always refer to the
+-     *             first sample of the data actually contained in the packet,
+-     *             including any added padding.  E.g. if the timebase is
+-     *             1/samplerate and the timestamp of the first input sample is
+-     *             0, the timestamp of the first output packet will be
+-     *             -initial_padding.
++     * Number of macroblock rows at the top which are skipped.
++     * - encoding: unused
++     * - decoding: Set by user.
+      */
+-    int initial_padding;
++    int skip_top;
+ 
+     /**
+-     * - decoding: For codecs that store a framerate value in the compressed
+-     *             bitstream, the decoder may export it here. { 0, 1} when
+-     *             unknown.
+-     * - encoding: May be used to signal the framerate of CFR content to an
+-     *             encoder.
++     * Number of macroblock rows at the bottom which are skipped.
++     * - encoding: unused
++     * - decoding: Set by user.
+      */
+-    AVRational framerate;
++    int skip_bottom;
+ 
+     /**
+-     * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
+-     * - encoding: unused.
+-     * - decoding: Set by libavcodec before calling get_format()
++     * low resolution decoding, 1-> 1/2 size, 2->1/4 size
++     * - encoding: unused
++     * - decoding: Set by user.
+      */
+-    enum AVPixelFormat sw_pix_fmt;
+-
+-    /**
+-     * Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
+-     * - encoding: unused.
+-     * - decoding: set by user.
+-     */
+-    AVRational pkt_timebase;
++     int lowres;
+ 
+     /**
+      * AVCodecDescriptor
+      * - encoding: unused.
+      * - decoding: set by libavcodec.
+      */
+     const struct AVCodecDescriptor *codec_descriptor;
+ 
+     /**
+-     * Current statistics for PTS correction.
+-     * - decoding: maintained and used by libavcodec, not intended to be used by user apps
+-     * - encoding: unused
+-     */
+-    int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far
+-    int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
+-    int64_t pts_correction_last_pts;       /// PTS of the last frame
+-    int64_t pts_correction_last_dts;       /// DTS of the last frame
+-
+-    /**
+      * Character encoding of the input subtitles file.
+      * - decoding: set by user
+      * - encoding: unused
+      */
+     char *sub_charenc;
+ 
+     /**
+      * Subtitles character encoding mode. Formats or codecs might be adjusting
+@@ -1848,42 +1875,25 @@ typedef struct AVCodecContext {
+      */
+     int sub_charenc_mode;
+ #define FF_SUB_CHARENC_MODE_DO_NOTHING  -1  ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance)
+ #define FF_SUB_CHARENC_MODE_AUTOMATIC    0  ///< libavcodec will select the mode itself
+ #define FF_SUB_CHARENC_MODE_PRE_DECODER  1  ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv
+ #define FF_SUB_CHARENC_MODE_IGNORE       2  ///< neither convert the subtitles, nor check them for valid UTF-8
+ 
+     /**
+-     * Skip processing alpha if supported by codec.
+-     * Note that if the format uses pre-multiplied alpha (common with VP6,
+-     * and recommended due to better video quality/compression)
+-     * the image will look as if alpha-blended onto a black background.
+-     * However for formats that do not use pre-multiplied alpha
+-     * there might be serious artefacts (though e.g. libswscale currently
+-     * assumes pre-multiplied alpha anyway).
+-     *
+-     * - decoding: set by user
+-     * - encoding: unused
++     * Header containing style information for text subtitles.
++     * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
++     * [Script Info] and [V4+ Styles] section, plus the [Events] line and
++     * the Format line following. It shouldn't include any Dialogue line.
++     * - encoding: Set/allocated/freed by user (before avcodec_open2())
++     * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2())
+      */
+-    int skip_alpha;
+-
+-    /**
+-     * Number of samples to skip after a discontinuity
+-     * - decoding: unused
+-     * - encoding: set by libavcodec
+-     */
+-    int seek_preroll;
+-
+-    /**
+-     * custom intra quantization matrix
+-     * - encoding: Set by user, can be NULL.
+-     * - decoding: unused.
+-     */
+-    uint16_t *chroma_intra_matrix;
++    int subtitle_header_size;
++    uint8_t *subtitle_header;
+ 
+     /**
+      * dump format separator.
+      * can be ", " or "\n      " or anything else
+      * - encoding: Set by user.
+      * - decoding: Set by user.
+      */
+     uint8_t *dump_separator;
+@@ -1892,109 +1902,43 @@ typedef struct AVCodecContext {
+      * ',' separated list of allowed decoders.
+      * If NULL then all are allowed
+      * - encoding: unused
+      * - decoding: set by user
+      */
+     char *codec_whitelist;
+ 
+     /**
+-     * Properties of the stream that gets decoded
+-     * - encoding: unused
+-     * - decoding: set by libavcodec
+-     */
+-    unsigned properties;
+-#define FF_CODEC_PROPERTY_LOSSLESS        0x00000001
+-#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002
+-#define FF_CODEC_PROPERTY_FILM_GRAIN      0x00000004
+-
+-    /**
+      * Additional data associated with the entire coded stream.
+      *
+      * - decoding: may be set by user before calling avcodec_open2().
+      * - encoding: may be set by libavcodec after avcodec_open2().
+      */
+     AVPacketSideData *coded_side_data;
+     int            nb_coded_side_data;
+ 
+     /**
+-     * A reference to the AVHWFramesContext describing the input (for encoding)
+-     * or output (decoding) frames. The reference is set by the caller and
+-     * afterwards owned (and freed) by libavcodec - it should never be read by
+-     * the caller after being set.
+-     *
+-     * - decoding: This field should be set by the caller from the get_format()
+-     *             callback. The previous reference (if any) will always be
+-     *             unreffed by libavcodec before the get_format() call.
+-     *
+-     *             If the default get_buffer2() is used with a hwaccel pixel
+-     *             format, then this AVHWFramesContext will be used for
+-     *             allocating the frame buffers.
++     * Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of
++     * metadata exported in frame, packet, or coded stream side data by
++     * decoders and encoders.
+      *
+-     * - encoding: For hardware encoders configured to use a hwaccel pixel
+-     *             format, this field should be set by the caller to a reference
+-     *             to the AVHWFramesContext describing input frames.
+-     *             AVHWFramesContext.format must be equal to
+-     *             AVCodecContext.pix_fmt.
+-     *
+-     *             This field should be set before avcodec_open2() is called.
++     * - decoding: set by user
++     * - encoding: set by user
+      */
+-    AVBufferRef *hw_frames_ctx;
+-
+-    /**
+-     * Audio only. The amount of padding (in samples) appended by the encoder to
+-     * the end of the audio. I.e. this number of decoded samples must be
+-     * discarded by the caller from the end of the stream to get the original
+-     * audio without any trailing padding.
+-     *
+-     * - decoding: unused
+-     * - encoding: unused
+-     */
+-    int trailing_padding;
++    int export_side_data;
+ 
+     /**
+      * The number of pixels per image to maximally accept.
+      *
+      * - decoding: set by user
+      * - encoding: set by user
+      */
+     int64_t max_pixels;
+ 
+     /**
+-     * A reference to the AVHWDeviceContext describing the device which will
+-     * be used by a hardware encoder/decoder.  The reference is set by the
+-     * caller and afterwards owned (and freed) by libavcodec.
+-     *
+-     * This should be used if either the codec device does not require
+-     * hardware frames or any that are used are to be allocated internally by
+-     * libavcodec.  If the user wishes to supply any of the frames used as
+-     * encoder input or decoder output then hw_frames_ctx should be used
+-     * instead.  When hw_frames_ctx is set in get_format() for a decoder, this
+-     * field will be ignored while decoding the associated stream segment, but
+-     * may again be used on a following one after another get_format() call.
+-     *
+-     * For both encoders and decoders this field should be set before
+-     * avcodec_open2() is called and must not be written to thereafter.
+-     *
+-     * Note that some decoders may require this field to be set initially in
+-     * order to support hw_frames_ctx at all - in that case, all frames
+-     * contexts used must be created on the same device.
+-     */
+-    AVBufferRef *hw_device_ctx;
+-
+-    /**
+-     * Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated
+-     * decoding (if active).
+-     * - encoding: unused
+-     * - decoding: Set by user (either before avcodec_open2(), or in the
+-     *             AVCodecContext.get_format callback)
+-     */
+-    int hwaccel_flags;
+-
+-    /**
+      * Video decoding only. Certain video codecs support cropping, meaning that
+      * only a sub-rectangle of the decoded frame is intended for display.  This
+      * option controls how cropping is handled by libavcodec.
+      *
+      * When set to 1 (the default), libavcodec will apply cropping internally.
+      * I.e. it will modify the output frame width/height fields and offset the
+      * data pointers (only by as much as possible while preserving alignment, or
+      * by the full amount if the AV_CODEC_FLAG_UNALIGNED flag is set) so that
+@@ -2011,30 +1955,16 @@ typedef struct AVCodecContext {
+      * @note when this option is set to zero, the width/height fields of the
+      * AVCodecContext and output AVFrames have different meanings. The codec
+      * context fields store display dimensions (with the coded dimensions in
+      * coded_width/height), while the frame fields store the coded dimensions
+      * (with the display dimensions being determined by the crop_* fields).
+      */
+     int apply_cropping;
+ 
+-    /*
+-     * Video decoding only.  Sets the number of extra hardware frames which
+-     * the decoder will allocate for use by the caller.  This must be set
+-     * before avcodec_open2() is called.
+-     *
+-     * Some hardware decoders require all frames that they will use for
+-     * output to be defined in advance before decoding starts.  For such
+-     * decoders, the hardware frame pool must therefore be of a fixed size.
+-     * The extra frames set here are on top of any number that the decoder
+-     * needs internally in order to operate normally (for example, frames
+-     * used as reference pictures).
+-     */
+-    int extra_hw_frames;
+-
+     /**
+      * The percentage of damaged samples to discard a frame.
+      *
+      * - decoding: set by user
+      * - encoding: unused
+      */
+     int discard_damaged_percentage;
+ 
+@@ -2042,26 +1972,16 @@ typedef struct AVCodecContext {
+      * The number of samples per frame to maximally accept.
+      *
+      * - decoding: set by user
+      * - encoding: set by user
+      */
+     int64_t max_samples;
+ 
+     /**
+-     * Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of
+-     * metadata exported in frame, packet, or coded stream side data by
+-     * decoders and encoders.
+-     *
+-     * - decoding: set by user
+-     * - encoding: set by user
+-     */
+-    int export_side_data;
+-
+-    /**
+      * This callback is called at the beginning of each packet to get a data
+      * buffer for it.
+      *
+      * The following field will be set in the packet before this callback is
+      * called:
+      * - size
+      * This callback must use the above value to calculate the required buffer size,
+      * which must padded by at least AV_INPUT_BUFFER_PADDING_SIZE bytes.
+@@ -2094,33 +2014,72 @@ typedef struct AVCodecContext {
+      * @see avcodec_default_get_encode_buffer()
+      *
+      * - encoding: Set by libavcodec, user can override.
+      * - decoding: unused
+      */
+     int (*get_encode_buffer)(struct AVCodecContext *s, AVPacket *pkt, int flags);
+ 
+     /**
+-     * Audio channel layout.
+-     * - encoding: must be set by the caller, to one of AVCodec.ch_layouts.
+-     * - decoding: may be set by the caller if known e.g. from the container.
+-     *             The decoder can then override during decoding as needed.
+-     */
+-    AVChannelLayout ch_layout;
+-
+-    /**
+      * Frame counter, set by libavcodec.
+      *
+      * - decoding: total number of frames returned from the decoder so far.
+      * - encoding: total number of frames passed to the encoder so far.
+      *
+      *   @note the counter is not incremented if encoding/decoding resulted in
+      *   an error.
+      */
+     int64_t frame_num;
++
++    /**
++     * Decoding only. May be set by the caller before avcodec_open2() to an
++     * av_malloc()'ed array (or via AVOptions). Owned and freed by the decoder
++     * afterwards.
++     *
++     * Side data attached to decoded frames may come from several sources:
++     * 1. coded_side_data, which the decoder will for certain types translate
++     *    from packet-type to frame-type and attach to frames;
++     * 2. side data attached to an AVPacket sent for decoding (same
++     *    considerations as above);
++     * 3. extracted from the coded bytestream.
++     * The first two cases are supplied by the caller and typically come from a
++     * container.
++     *
++     * This array configures decoder behaviour in cases when side data of the
++     * same type is present both in the coded bytestream and in the
++     * user-supplied side data (items 1. and 2. above). In all cases, at most
++     * one instance of each side data type will be attached to output frames. By
++     * default it will be the bytestream side data. Adding an
++     * AVPacketSideDataType value to this array will flip the preference for
++     * this type, thus making the decoder prefer user-supplied side data over
++     * bytestream. In case side data of the same type is present both in
++     * coded_data and attacked to a packet, the packet instance always has
++     * priority.
++     *
++     * The array may also contain a single -1, in which case the preference is
++     * switched for all side data types.
++     */
++    int        *side_data_prefer_packet;
++    /**
++     * Number of entries in side_data_prefer_packet.
++     */
++    unsigned nb_side_data_prefer_packet;
++
++    /**
++     * Array containing static side data, such as HDR10 CLL / MDCV structures.
++     * Side data entries should be allocated by usage of helpers defined in
++     * libavutil/frame.h.
++     *
++     * - encoding: may be set by user before calling avcodec_open2() for
++     *             encoder configuration. Afterwards owned and freed by the
++     *             encoder.
++     * - decoding: unused
++     */
++    AVFrameSideData  **decoded_side_data;
++    int             nb_decoded_side_data;
+ } AVCodecContext;
+ 
+ /**
+  * @defgroup lavc_hwaccel AVHWAccel
+  *
+  * @note  Nothing in this structure should be accessed by the user.  At some
+  *        point in future it will not be externally visible at all.
+  *
+@@ -2247,28 +2206,27 @@ typedef struct AVSubtitleRect {
+ 
+     /**
+      * data+linesize for the bitmap of this subtitle.
+      * Can be set for text/ass as well once they are rendered.
+      */
+     uint8_t *data[4];
+     int linesize[4];
+ 
++    int flags;
+     enum AVSubtitleType type;
+ 
+     char *text;                     ///< 0 terminated plain UTF-8 text
+ 
+     /**
+      * 0 terminated ASS/SSA compatible event line.
+      * The presentation of this is unaffected by the other values in this
+      * struct.
+      */
+     char *ass;
+-
+-    int flags;
+ } AVSubtitleRect;
+ 
+ typedef struct AVSubtitle {
+     uint16_t format; /* 0 = graphics */
+     uint32_t start_display_time; /* relative to packet pts, in ms */
+     uint32_t end_display_time; /* relative to packet pts, in ms */
+     unsigned num_rects;
+     AVSubtitleRect **rects;
+@@ -2406,30 +2364,33 @@ int avcodec_parameters_to_context(AVCode
+  *                options that were not found in the avctx codec context.
+  *
+  * @return zero on success, a negative value on error
+  * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),
+  *      av_dict_set(), av_opt_set(), av_opt_find(), avcodec_parameters_to_context()
+  */
+ int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
+ 
++#if FF_API_AVCODEC_CLOSE
+ /**
+  * Close a given AVCodecContext and free all the data associated with it
+  * (but not the AVCodecContext itself).
+  *
+  * Calling this function on an AVCodecContext that hasn't been opened will free
+  * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL
+  * codec. Subsequent calls will do nothing.
+  *
+- * @note Do not use this function. Use avcodec_free_context() to destroy a
++ * @deprecated Do not use this function. Use avcodec_free_context() to destroy a
+  * codec context (either open or closed). Opening and closing a codec context
+  * multiple times is not supported anymore -- use multiple codec contexts
+  * instead.
+  */
++attribute_deprecated
+ int avcodec_close(AVCodecContext *avctx);
++#endif
+ 
+ /**
+  * Free all allocated data in the given subtitle struct.
+  *
+  * @param sub AVSubtitle to free.
+  */
+ void avsubtitle_free(AVSubtitle *sub);
+ 
+@@ -2470,44 +2431,16 @@ void avcodec_align_dimensions(AVCodecCon
+  * buffer that is acceptable for the codec if you also ensure that all
+  * line sizes are a multiple of the respective linesize_align[i].
+  *
+  * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened.
+  */
+ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
+                                int linesize_align[AV_NUM_DATA_POINTERS]);
+ 
+-#ifdef FF_API_AVCODEC_CHROMA_POS
+-/**
+- * Converts AVChromaLocation to swscale x/y chroma position.
+- *
+- * The positions represent the chroma (0,0) position in a coordinates system
+- * with luma (0,0) representing the origin and luma(1,1) representing 256,256
+- *
+- * @param xpos  horizontal chroma sample position
+- * @param ypos  vertical   chroma sample position
+- * @deprecated Use av_chroma_location_enum_to_pos() instead.
+- */
+- attribute_deprecated
+-int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos);
+-
+-/**
+- * Converts swscale x/y chroma position to AVChromaLocation.
+- *
+- * The positions represent the chroma (0,0) position in a coordinates system
+- * with luma (0,0) representing the origin and luma(1,1) representing 256,256
+- *
+- * @param xpos  horizontal chroma sample position
+- * @param ypos  vertical   chroma sample position
+- * @deprecated Use av_chroma_location_pos_to_enum() instead.
+- */
+- attribute_deprecated
+-enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos);
+-#endif
+-
+ /**
+  * Decode a subtitle message.
+  * Return a negative value on error, otherwise return the number of bytes used.
+  * If no subtitle could be decompressed, got_sub_ptr is zero.
+  * Otherwise, the subtitle is stored in *sub.
+  * Note that AV_CODEC_CAP_DR1 is not available for subtitle codecs. This is for
+  * simplicity, because the performance difference is expected to be negligible
+  * and reusing a get_buffer written for video codecs would probably perform badly
+diff --git a/media/ffvpx/libavcodec/avcodec.symbols b/media/ffvpx/libavcodec/avcodec.symbols
+--- a/media/ffvpx/libavcodec/avcodec.symbols
++++ b/media/ffvpx/libavcodec/avcodec.symbols
+@@ -4,62 +4,42 @@ av_codec_is_encoder
+ av_codec_iterate
+ av_fast_padded_malloc
+ av_fast_padded_mallocz
+ av_get_audio_frame_duration
+ av_get_bits_per_sample
+ av_get_exact_bits_per_sample
+ av_get_pcm_codec
+ av_get_profile_name
+-av_grow_packet
+-av_init_packet
+-av_new_packet
+ av_packet_alloc
+-av_packet_copy_props
+-av_packet_free_side_data
+-av_packet_from_data
+-av_packet_get_side_data
+-av_packet_move_ref
+-av_packet_new_side_data
+-av_packet_pack_dictionary
+-av_packet_ref
+-av_packet_rescale_ts
+-av_packet_shrink_side_data
+-av_packet_side_data_name
+-av_packet_unpack_dictionary
+ av_packet_unref
+ av_packet_free
++av_init_packet
+ av_parser_close
+ av_parser_init
+ av_parser_parse2
+-av_rdft_calc
+-av_rdft_end
+-av_rdft_init
+-av_shrink_packet
+ av_vorbis_parse_frame
+ av_vorbis_parse_frame_flags
+ av_vorbis_parse_free
+ av_vorbis_parse_init
+ av_vorbis_parse_reset
+ av_xiphlacing
+ avcodec_align_dimensions
+ avcodec_align_dimensions2
+ avcodec_alloc_context3
+-avcodec_chroma_pos_to_enum
+ avcodec_close
+ avcodec_configuration
+ avcodec_decode_subtitle2
+ avcodec_default_execute
+ avcodec_default_execute2
+ avcodec_default_get_buffer2
+ avcodec_default_get_format
+ avcodec_descriptor_get
+ avcodec_descriptor_get_by_name
+ avcodec_descriptor_next
+-avcodec_enum_to_chroma_pos
+ avcodec_fill_audio_frame
+ avcodec_find_decoder
+ avcodec_find_decoder_by_name
+ avcodec_find_encoder
+ avcodec_find_encoder_by_name
+ avcodec_flush_buffers
+ avcodec_free_context
+ avcodec_get_class
+diff --git a/media/ffvpx/libavcodec/avcodec_internal.h b/media/ffvpx/libavcodec/avcodec_internal.h
+--- a/media/ffvpx/libavcodec/avcodec_internal.h
++++ b/media/ffvpx/libavcodec/avcodec_internal.h
+@@ -20,18 +20,32 @@
+  * APIs internal to the generic codec layer.
+  *
+  * MUST NOT be included by individual encoders or decoders.
+  */
+ 
+ #ifndef AVCODEC_AVCODEC_INTERNAL_H
+ #define AVCODEC_AVCODEC_INTERNAL_H
+ 
++#include "libavutil/frame.h"
++
++#include "packet.h"
++
+ struct AVCodecContext;
+-struct AVFrame;
++
++typedef struct SideDataMap {
++    enum AVPacketSideDataType packet;
++    enum AVFrameSideDataType frame;
++} SideDataMap;
++
++/**
++ * A map between packet and frame side data types.
++ * Terminated with an entry where packet=AV_PKT_DATA_NB.
++ */
++extern const SideDataMap ff_sd_global_map[];
+ 
+ /**
+  * avcodec_receive_frame() implementation for decoders.
+  */
+ int ff_decode_receive_frame(struct AVCodecContext *avctx, struct AVFrame *frame);
+ 
+ /**
+  * avcodec_receive_frame() implementation for encoders.
+@@ -51,9 +65,11 @@ int ff_encode_preinit(struct AVCodecCont
+ int ff_decode_preinit(struct AVCodecContext *avctx);
+ 
+ void ff_decode_flush_buffers(struct AVCodecContext *avctx);
+ void ff_encode_flush_buffers(struct AVCodecContext *avctx);
+ 
+ struct AVCodecInternal *ff_decode_internal_alloc(void);
+ struct AVCodecInternal *ff_encode_internal_alloc(void);
+ 
++void ff_codec_close(struct AVCodecContext *avctx);
++
+ #endif // AVCODEC_AVCODEC_INTERNAL_H
+diff --git a/media/ffvpx/libavcodec/avdct.c b/media/ffvpx/libavcodec/avdct.c
+--- a/media/ffvpx/libavcodec/avdct.c
++++ b/media/ffvpx/libavcodec/avdct.c
+@@ -13,54 +13,55 @@
+  * 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
+  */
+ 
++#include "libavutil/mem.h"
+ #include "avcodec.h"
+ #include "idctdsp.h"
+ #include "fdctdsp.h"
+ #include "pixblockdsp.h"
+ #include "avdct.h"
+ 
+ #define OFFSET(x) offsetof(AVDCT,x)
+ #define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
+ //these names are too long to be readable
+ #define V AV_OPT_FLAG_VIDEO_PARAM
+ #define A AV_OPT_FLAG_AUDIO_PARAM
+ #define E AV_OPT_FLAG_ENCODING_PARAM
+ #define D AV_OPT_FLAG_DECODING_PARAM
+ 
+ static const AVOption avdct_options[] = {
+-{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"},
+-{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"fastint", "fast integer (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"mmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"faan", "floating point AAN DCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"},
++{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, .unit = "dct"},
++{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"fastint", "fast integer (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"mmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"faan", "floating point AAN DCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
+ 
+-{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"},
+-{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"int", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simple", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simplemmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"arm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simplearm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simplearmv5te", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simplearmv6", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simpleneon", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"xvid", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"xvidmmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"faani", "floating point AAN IDCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
+-{"simpleauto", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
++{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, .unit = "idct"},
++{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"int", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simple", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simplemmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"arm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simplearm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simplearmv5te", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simplearmv6", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simpleneon", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"xvid", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"xvidmmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"faani", "floating point AAN IDCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, .unit = "idct"},
++{"simpleauto", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
+ 
+ {"bits_per_sample", "", OFFSET(bits_per_sample), AV_OPT_TYPE_INT, {.i64 = 8 }, 0, 14, 0,},
+ {NULL},
+ };
+ 
+ static const AVClass avdct_class = {
+     .class_name              = "AVDCT",
+     .option                  = avdct_options,
+diff --git a/media/ffvpx/libavcodec/avpicture.c b/media/ffvpx/libavcodec/avpicture.c
+deleted file mode 100644
+--- a/media/ffvpx/libavcodec/avpicture.c
++++ /dev/null
+@@ -1,82 +0,0 @@
+-/*
+- * AVPicture management routines
+- * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
+- *
+- * 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
+- */
+-
+-/**
+- * @file
+- * AVPicture management routines
+- */
+-
+-#include "avcodec.h"
+-#include "internal.h"
+-#include "libavutil/common.h"
+-#include "libavutil/pixdesc.h"
+-#include "libavutil/imgutils.h"
+-#include "libavutil/internal.h"
+-#include "libavutil/colorspace.h"
+-
+-#if FF_API_AVPICTURE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
+-                   enum AVPixelFormat pix_fmt, int width, int height)
+-{
+-    return av_image_fill_arrays(picture->data, picture->linesize,
+-                                ptr, pix_fmt, width, height, 1);
+-}
+-
+-int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt, int width, int height,
+-                     unsigned char *dest, int dest_size)
+-{
+-    return av_image_copy_to_buffer(dest, dest_size,
+-                                   (const uint8_t * const*)src->data, src->linesize,
+-                                   pix_fmt, width, height, 1);
+-}
+-
+-int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
+-{
+-    return av_image_get_buffer_size(pix_fmt, width, height, 1);
+-}
+-
+-int avpicture_alloc(AVPicture *picture,
+-                    enum AVPixelFormat pix_fmt, int width, int height)
+-{
+-    int ret = av_image_alloc(picture->data, picture->linesize,
+-                             width, height, pix_fmt, 1);
+-    if (ret < 0) {
+-        memset(picture, 0, sizeof(AVPicture));
+-        return ret;
+-    }
+-
+-    return 0;
+-}
+-
+-void avpicture_free(AVPicture *picture)
+-{
+-    av_freep(&picture->data[0]);
+-}
+-
+-void av_picture_copy(AVPicture *dst, const AVPicture *src,
+-                     enum AVPixelFormat pix_fmt, int width, int height)
+-{
+-    av_image_copy(dst->data, dst->linesize, (const uint8_t **)src->data,
+-                  src->linesize, pix_fmt, width, height);
+-}
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif /* FF_API_AVPICTURE */
+diff --git a/media/ffvpx/libavcodec/bitstream_filters.c b/media/ffvpx/libavcodec/bitstream_filters.c
+--- a/media/ffvpx/libavcodec/bitstream_filters.c
++++ b/media/ffvpx/libavcodec/bitstream_filters.c
+@@ -41,28 +41,28 @@ extern const FFBitStreamFilter ff_h264_m
+ extern const FFBitStreamFilter ff_h264_redundant_pps_bsf;
+ extern const FFBitStreamFilter ff_hapqa_extract_bsf;
+ extern const FFBitStreamFilter ff_hevc_metadata_bsf;
+ extern const FFBitStreamFilter ff_hevc_mp4toannexb_bsf;
+ extern const FFBitStreamFilter ff_imx_dump_header_bsf;
+ extern const FFBitStreamFilter ff_media100_to_mjpegb_bsf;
+ extern const FFBitStreamFilter ff_mjpeg2jpeg_bsf;
+ extern const FFBitStreamFilter ff_mjpega_dump_header_bsf;
+-extern const FFBitStreamFilter ff_mp3_header_decompress_bsf;
+ extern const FFBitStreamFilter ff_mpeg2_metadata_bsf;
+ extern const FFBitStreamFilter ff_mpeg4_unpack_bframes_bsf;
+ extern const FFBitStreamFilter ff_mov2textsub_bsf;
+ extern const FFBitStreamFilter ff_noise_bsf;
+ extern const FFBitStreamFilter ff_null_bsf;
+ extern const FFBitStreamFilter ff_opus_metadata_bsf;
+ extern const FFBitStreamFilter ff_pcm_rechunk_bsf;
+ extern const FFBitStreamFilter ff_pgs_frame_merge_bsf;
+ extern const FFBitStreamFilter ff_prores_metadata_bsf;
+ extern const FFBitStreamFilter ff_remove_extradata_bsf;
+ extern const FFBitStreamFilter ff_setts_bsf;
++extern const FFBitStreamFilter ff_showinfo_bsf;
+ extern const FFBitStreamFilter ff_text2movsub_bsf;
+ extern const FFBitStreamFilter ff_trace_headers_bsf;
+ extern const FFBitStreamFilter ff_truehd_core_bsf;
+ extern const FFBitStreamFilter ff_vp9_metadata_bsf;
+ extern const FFBitStreamFilter ff_vp9_raw_reorder_bsf;
+ extern const FFBitStreamFilter ff_vp9_superframe_bsf;
+ extern const FFBitStreamFilter ff_vp9_superframe_split_bsf;
+ extern const FFBitStreamFilter ff_vvc_metadata_bsf;
+diff --git a/media/ffvpx/libavcodec/blockdsp.h b/media/ffvpx/libavcodec/blockdsp.h
+--- a/media/ffvpx/libavcodec/blockdsp.h
++++ b/media/ffvpx/libavcodec/blockdsp.h
+@@ -36,12 +36,13 @@ typedef struct BlockDSPContext {
+     op_fill_func fill_block_tab[2];
+ } BlockDSPContext;
+ 
+ void ff_blockdsp_init(BlockDSPContext *c);
+ 
+ void ff_blockdsp_init_alpha(BlockDSPContext *c);
+ void ff_blockdsp_init_arm(BlockDSPContext *c);
+ void ff_blockdsp_init_ppc(BlockDSPContext *c);
++void ff_blockdsp_init_riscv(BlockDSPContext *c);
+ void ff_blockdsp_init_x86(BlockDSPContext *c);
+ void ff_blockdsp_init_mips(BlockDSPContext *c);
+ 
+ #endif /* AVCODEC_BLOCKDSP_H */
+diff --git a/media/ffvpx/libavcodec/av1_frame_split_bsf.c b/media/ffvpx/libavcodec/bsf/av1_frame_split.c
+rename from media/ffvpx/libavcodec/av1_frame_split_bsf.c
+rename to media/ffvpx/libavcodec/bsf/av1_frame_split.c
+diff --git a/media/ffvpx/libavcodec/bsf/moz.build b/media/ffvpx/libavcodec/bsf/moz.build
+new file mode 100644
+--- /dev/null
++++ b/media/ffvpx/libavcodec/bsf/moz.build
+@@ -0,0 +1,21 @@
++# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
++# vim: set filetype=python:
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++#
++if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
++    SOURCES += [
++      'av1_frame_split.c',
++      'vp9_superframe_split.c',
++    ]
++
++SOURCES += [
++    'null.c',
++]
++
++LOCAL_INCLUDES += [ "../" ]
++
++FINAL_LIBRARY = 'mozavcodec'
++
++include('/media/ffvpx/ffvpxcommon.mozbuild')
+diff --git a/media/ffvpx/libavcodec/null_bsf.c b/media/ffvpx/libavcodec/bsf/null.c
+rename from media/ffvpx/libavcodec/null_bsf.c
+rename to media/ffvpx/libavcodec/bsf/null.c
+diff --git a/media/ffvpx/libavcodec/vp9_superframe_split_bsf.c b/media/ffvpx/libavcodec/bsf/vp9_superframe_split.c
+rename from media/ffvpx/libavcodec/vp9_superframe_split_bsf.c
+rename to media/ffvpx/libavcodec/bsf/vp9_superframe_split.c
+diff --git a/media/ffvpx/libavcodec/cbs.c b/media/ffvpx/libavcodec/cbs.c
+--- a/media/ffvpx/libavcodec/cbs.c
++++ b/media/ffvpx/libavcodec/cbs.c
+@@ -18,16 +18,17 @@
+ 
+ #include <string.h>
+ 
+ #include "config.h"
+ 
+ #include "libavutil/avassert.h"
+ #include "libavutil/buffer.h"
+ #include "libavutil/common.h"
++#include "libavutil/mem.h"
+ #include "libavutil/opt.h"
+ 
+ #include "avcodec.h"
+ #include "cbs.h"
+ #include "cbs_internal.h"
+ #include "refstruct.h"
+ 
+ 
+diff --git a/media/ffvpx/libavcodec/cbs_av1.h b/media/ffvpx/libavcodec/cbs_av1.h
+--- a/media/ffvpx/libavcodec/cbs_av1.h
++++ b/media/ffvpx/libavcodec/cbs_av1.h
+@@ -422,16 +422,18 @@ typedef struct AV1ReferenceFrameState {
+     int render_width;   // RefRenderWidth
+     int render_height;  // RefRenderHeight
+     int frame_type;     // RefFrameType
+     int subsampling_x;  // RefSubsamplingX
+     int subsampling_y;  // RefSubsamplingY
+     int bit_depth;      // RefBitDepth
+     int order_hint;     // RefOrderHint
+ 
++    int saved_order_hints[AV1_TOTAL_REFS_PER_FRAME]; // SavedOrderHints[ref]
++
+     int8_t  loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME];
+     int8_t  loop_filter_mode_deltas[2];
+     uint8_t feature_enabled[AV1_MAX_SEGMENTS][AV1_SEG_LVL_MAX];
+     int16_t feature_value[AV1_MAX_SEGMENTS][AV1_SEG_LVL_MAX];
+ } AV1ReferenceFrameState;
+ 
+ typedef struct CodedBitstreamAV1Context {
+     const AVClass *class;
+@@ -459,16 +461,19 @@ typedef struct CodedBitstreamAV1Context 
+ 
+     int num_planes;
+     int coded_lossless;
+     int all_lossless;
+     int tile_cols;
+     int tile_rows;
+     int tile_num;
+ 
++    int order_hints[AV1_TOTAL_REFS_PER_FRAME];         // OrderHints
++    int ref_frame_sign_bias[AV1_TOTAL_REFS_PER_FRAME]; // RefFrameSignBias
++
+     AV1ReferenceFrameState ref[AV1_NUM_REF_FRAMES];
+ 
+     // AVOptions
+     int operating_point;
+     // When writing, fix the length in bytes of the obu_size field.
+     // Writing will fail with an error if an OBU larger than can be
+     // represented by the fixed size is encountered.
+     int fixed_obu_size_length;
+diff --git a/media/ffvpx/libavcodec/cbs_av1_syntax_template.c b/media/ffvpx/libavcodec/cbs_av1_syntax_template.c
+--- a/media/ffvpx/libavcodec/cbs_av1_syntax_template.c
++++ b/media/ffvpx/libavcodec/cbs_av1_syntax_template.c
+@@ -355,17 +355,17 @@ static int FUNC(set_frame_refs)(CodedBit
+         AV1_REF_FRAME_ALTREF2, AV1_REF_FRAME_ALTREF
+     };
+     int8_t ref_frame_idx[AV1_REFS_PER_FRAME], used_frame[AV1_NUM_REF_FRAMES];
+     int16_t shifted_order_hints[AV1_NUM_REF_FRAMES];
+     int cur_frame_hint, latest_order_hint, earliest_order_hint, ref;
+     int i, j;
+ 
+     for (i = 0; i < AV1_REFS_PER_FRAME; i++)
+-        ref_frame_idx[i] = -1;
++        ref_frame_idx[i] = AV1_REF_FRAME_NONE;
+     ref_frame_idx[AV1_REF_FRAME_LAST - AV1_REF_FRAME_LAST] = current->last_frame_idx;
+     ref_frame_idx[AV1_REF_FRAME_GOLDEN - AV1_REF_FRAME_LAST] = current->golden_frame_idx;
+ 
+     for (i = 0; i < AV1_NUM_REF_FRAMES; i++)
+         used_frame[i] = 0;
+     used_frame[current->last_frame_idx] = 1;
+     used_frame[current->golden_frame_idx] = 1;
+ 
+@@ -373,78 +373,78 @@ static int FUNC(set_frame_refs)(CodedBit
+     for (i = 0; i < AV1_NUM_REF_FRAMES; i++)
+         shifted_order_hints[i] = cur_frame_hint +
+                                  cbs_av1_get_relative_dist(seq, priv->ref[i].order_hint,
+                                                            priv->order_hint);
+ 
+     latest_order_hint = shifted_order_hints[current->last_frame_idx];
+     earliest_order_hint = shifted_order_hints[current->golden_frame_idx];
+ 
+-    ref = -1;
++    ref = AV1_REF_FRAME_NONE;
+     for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+         int hint = shifted_order_hints[i];
+         if (!used_frame[i] && hint >= cur_frame_hint &&
+             (ref < 0 || hint >= latest_order_hint)) {
+             ref = i;
+             latest_order_hint = hint;
+         }
+     }
+     if (ref >= 0) {
+         ref_frame_idx[AV1_REF_FRAME_ALTREF - AV1_REF_FRAME_LAST] = ref;
+         used_frame[ref] = 1;
+     }
+ 
+-    ref = -1;
++    ref = AV1_REF_FRAME_NONE;
+     for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+         int hint = shifted_order_hints[i];
+         if (!used_frame[i] && hint >= cur_frame_hint &&
+             (ref < 0 || hint < earliest_order_hint)) {
+             ref = i;
+             earliest_order_hint = hint;
+         }
+     }
+     if (ref >= 0) {
+         ref_frame_idx[AV1_REF_FRAME_BWDREF - AV1_REF_FRAME_LAST] = ref;
+         used_frame[ref] = 1;
+     }
+ 
+-    ref = -1;
++    ref = AV1_REF_FRAME_NONE;
+     for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+         int hint = shifted_order_hints[i];
+         if (!used_frame[i] && hint >= cur_frame_hint &&
+             (ref < 0 || hint < earliest_order_hint)) {
+             ref = i;
+             earliest_order_hint = hint;
+         }
+     }
+     if (ref >= 0) {
+         ref_frame_idx[AV1_REF_FRAME_ALTREF2 - AV1_REF_FRAME_LAST] = ref;
+         used_frame[ref] = 1;
+     }
+ 
+     for (i = 0; i < AV1_REFS_PER_FRAME - 2; i++) {
+         int ref_frame = ref_frame_list[i];
+         if (ref_frame_idx[ref_frame - AV1_REF_FRAME_LAST] < 0 ) {
+-            ref = -1;
++            ref = AV1_REF_FRAME_NONE;
+             for (j = 0; j < AV1_NUM_REF_FRAMES; j++) {
+                 int hint = shifted_order_hints[j];
+                 if (!used_frame[j] && hint < cur_frame_hint &&
+                     (ref < 0 || hint >= latest_order_hint)) {
+                     ref = j;
+                     latest_order_hint = hint;
+                 }
+             }
+             if (ref >= 0) {
+                 ref_frame_idx[ref_frame - AV1_REF_FRAME_LAST] = ref;
+                 used_frame[ref] = 1;
+             }
+         }
+     }
+ 
+-    ref = -1;
++    ref = AV1_REF_FRAME_NONE;
+     for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+         int hint = shifted_order_hints[i];
+         if (ref < 0 || hint < earliest_order_hint) {
+             ref = i;
+             earliest_order_hint = hint;
+         }
+     }
+     for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
+@@ -1409,16 +1409,18 @@ static int FUNC(uncompressed_header)(Cod
+             flag(error_resilient_mode);
+     }
+ 
+     if (current->frame_type == AV1_FRAME_KEY && current->show_frame) {
+         for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
+             priv->ref[i].valid = 0;
+             priv->ref[i].order_hint = 0;
+         }
++        for (i = 0; i < AV1_REFS_PER_FRAME; i++)
++            priv->order_hints[i + AV1_REF_FRAME_LAST] = 0;
+     }
+ 
+     flag(disable_cdf_update);
+ 
+     if (seq->seq_force_screen_content_tools ==
+         AV1_SELECT_SCREEN_CONTENT_TOOLS) {
+         flag(allow_screen_content_tools);
+     } else {
+@@ -1563,21 +1565,30 @@ static int FUNC(uncompressed_header)(Cod
+         flag(is_motion_mode_switchable);
+ 
+         if (current->error_resilient_mode ||
+             !seq->enable_ref_frame_mvs)
+             infer(use_ref_frame_mvs, 0);
+         else
+             flag(use_ref_frame_mvs);
+ 
+-        infer(allow_intrabc, 0);
+-    }
++        for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
++            int ref_frame = AV1_REF_FRAME_LAST + i;
++            int hint = priv->ref[current->ref_frame_idx[i]].order_hint;
++            priv->order_hints[ref_frame] = hint;
++            if (!seq->enable_order_hint) {
++                priv->ref_frame_sign_bias[ref_frame] = 0;
++            } else {
++                priv->ref_frame_sign_bias[ref_frame] =
++                    cbs_av1_get_relative_dist(seq, hint,
++                                              current->order_hint) > 0;
++            }
++        }
+ 
+-    if (!frame_is_intra) {
+-        // Derive reference frame sign biases.
++        infer(allow_intrabc, 0);
+     }
+ 
+     if (seq->reduced_still_picture_header || current->disable_cdf_update)
+         infer(disable_frame_end_update_cdf, 1);
+     else
+         flag(disable_frame_end_update_cdf);
+ 
+     if (current->primary_ref_frame == AV1_PRIMARY_REF_NONE) {
+@@ -1669,16 +1680,22 @@ update_refs:
+                 .render_width   = priv->render_width,
+                 .render_height  = priv->render_height,
+                 .frame_type     = current->frame_type,
+                 .subsampling_x  = seq->color_config.subsampling_x,
+                 .subsampling_y  = seq->color_config.subsampling_y,
+                 .bit_depth      = priv->bit_depth,
+                 .order_hint     = priv->order_hint,
+             };
++
++            for (int j = 0; j < AV1_REFS_PER_FRAME; j++) {
++                priv->ref[i].saved_order_hints[j + AV1_REF_FRAME_LAST] =
++                    priv->order_hints[j + AV1_REF_FRAME_LAST];
++            }
++
+             memcpy(priv->ref[i].loop_filter_ref_deltas, current->loop_filter_ref_deltas,
+                    sizeof(current->loop_filter_ref_deltas));
+             memcpy(priv->ref[i].loop_filter_mode_deltas, current->loop_filter_mode_deltas,
+                    sizeof(current->loop_filter_mode_deltas));
+             memcpy(priv->ref[i].feature_enabled, current->feature_enabled,
+                    sizeof(current->feature_enabled));
+             memcpy(priv->ref[i].feature_value, current->feature_value,
+                    sizeof(current->feature_value));
+diff --git a/media/ffvpx/libavcodec/codec.h b/media/ffvpx/libavcodec/codec.h
+--- a/media/ffvpx/libavcodec/codec.h
++++ b/media/ffvpx/libavcodec/codec.h
+@@ -204,23 +204,16 @@ typedef struct AVCodec {
+      * see AV_CODEC_CAP_*
+      */
+     int capabilities;
+     uint8_t max_lowres;                     ///< maximum value for lowres supported by the decoder
+     const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
+     const enum AVPixelFormat *pix_fmts;     ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
+     const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
+     const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-    /**
+-     * @deprecated use ch_layouts instead
+-     */
+-    attribute_deprecated
+-    const uint64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
+-#endif
+     const AVClass *priv_class;              ///< AVClass for the private context
+     const AVProfile *profiles;              ///< array of recognized profiles, or NULL if unknown, array is terminated by {AV_PROFILE_UNKNOWN}
+ 
+     /**
+      * Group name of the codec implementation.
+      * This is a short symbolic name of the wrapper backing this codec. A
+      * wrapper uses some kind of external implementation for the codec, such
+      * as an external library, or a codec implementation provided by the OS or
+diff --git a/media/ffvpx/libavcodec/codec_desc.c b/media/ffvpx/libavcodec/codec_desc.c
+--- a/media/ffvpx/libavcodec/codec_desc.c
++++ b/media/ffvpx/libavcodec/codec_desc.c
+@@ -1465,25 +1465,16 @@ static const AVCodecDescriptor codec_des
+     },
+     {
+         .id        = AV_CODEC_ID_AVUI,
+         .type      = AVMEDIA_TYPE_VIDEO,
+         .name      = "avui",
+         .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"),
+         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+     },
+-#if FF_API_AYUV_CODECID
+-    {
+-        .id        = AV_CODEC_ID_AYUV,
+-        .type      = AVMEDIA_TYPE_VIDEO,
+-        .name      = "ayuv",
+-        .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"),
+-        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+-    },
+-#endif
+     {
+         .id        = AV_CODEC_ID_TARGA_Y216,
+         .type      = AVMEDIA_TYPE_VIDEO,
+         .name      = "targa_y216",
+         .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"),
+         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
+     },
+     {
+@@ -3429,16 +3420,23 @@ static const AVCodecDescriptor codec_des
+     },
+     {
+         .id        = AV_CODEC_ID_QOA,
+         .type      = AVMEDIA_TYPE_AUDIO,
+         .name      = "qoa",
+         .long_name = NULL_IF_CONFIG_SMALL("QOA (Quite OK Audio)"),
+         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+     },
++    {
++        .id        = AV_CODEC_ID_LC3,
++        .type      = AVMEDIA_TYPE_AUDIO,
++        .name      = "lc3",
++        .long_name = NULL_IF_CONFIG_SMALL("LC3 (Low Complexity Communication Codec)"),
++        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
++    },
+ 
+     /* subtitle codecs */
+     {
+         .id        = AV_CODEC_ID_DVD_SUBTITLE,
+         .type      = AVMEDIA_TYPE_SUBTITLE,
+         .name      = "dvd_subtitle",
+         .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
+         .props     = AV_CODEC_PROP_BITMAP_SUB,
+diff --git a/media/ffvpx/libavcodec/codec_id.h b/media/ffvpx/libavcodec/codec_id.h
+--- a/media/ffvpx/libavcodec/codec_id.h
++++ b/media/ffvpx/libavcodec/codec_id.h
+@@ -248,19 +248,16 @@ enum AVCodecID {
+     AV_CODEC_ID_AVS3,
+     AV_CODEC_ID_MSP2,
+     AV_CODEC_ID_VVC,
+ #define AV_CODEC_ID_H266 AV_CODEC_ID_VVC
+     AV_CODEC_ID_Y41P,
+     AV_CODEC_ID_AVRP,
+     AV_CODEC_ID_012V,
+     AV_CODEC_ID_AVUI,
+-#if FF_API_AYUV_CODECID
+-    AV_CODEC_ID_AYUV,
+-#endif
+     AV_CODEC_ID_TARGA_Y216,
+     AV_CODEC_ID_V308,
+     AV_CODEC_ID_V408,
+     AV_CODEC_ID_YUV4,
+     AV_CODEC_ID_AVRN,
+     AV_CODEC_ID_CPIA,
+     AV_CODEC_ID_XFACE,
+     AV_CODEC_ID_SNOW,
+@@ -541,16 +538,17 @@ enum AVCodecID {
+     AV_CODEC_ID_MISC4,
+     AV_CODEC_ID_APAC,
+     AV_CODEC_ID_FTR,
+     AV_CODEC_ID_WAVARC,
+     AV_CODEC_ID_RKA,
+     AV_CODEC_ID_AC4,
+     AV_CODEC_ID_OSQ,
+     AV_CODEC_ID_QOA,
++    AV_CODEC_ID_LC3,
+ 
+     /* subtitle codecs */
+     AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
+     AV_CODEC_ID_DVD_SUBTITLE = 0x17000,
+     AV_CODEC_ID_DVB_SUBTITLE,
+     AV_CODEC_ID_TEXT,  ///< raw UTF-8 text
+     AV_CODEC_ID_XSUB,
+     AV_CODEC_ID_SSA,
+diff --git a/media/ffvpx/libavcodec/codec_internal.h b/media/ffvpx/libavcodec/codec_internal.h
+--- a/media/ffvpx/libavcodec/codec_internal.h
++++ b/media/ffvpx/libavcodec/codec_internal.h
+@@ -279,35 +279,16 @@ typedef struct FFCodec {
+         .update_thread_context_for_user = (func)
+ #else
+ #define UPDATE_THREAD_CONTEXT(func) \
+         .update_thread_context          = NULL
+ #define UPDATE_THREAD_CONTEXT_FOR_USER(func) \
+         .update_thread_context_for_user = NULL
+ #endif
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-#define CODEC_OLD_CHANNEL_LAYOUTS(...) CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(((const uint64_t[]) { __VA_ARGS__, 0 }))
+-#if defined(__clang__)
+-#define CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(array) \
+-        FF_DISABLE_DEPRECATION_WARNINGS \
+-        .p.channel_layouts = (array), \
+-        FF_ENABLE_DEPRECATION_WARNINGS
+-#else
+-#define CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(array) .p.channel_layouts = (array),
+-#endif
+-#else
+-/* This is only provided to allow to test disabling FF_API_OLD_CHANNEL_LAYOUT
+- * without removing all the FF_API_OLD_CHANNEL_LAYOUT codeblocks.
+- * It is of course still expected to be removed when FF_API_OLD_CHANNEL_LAYOUT
+- * will be finally removed (along with all usages of these macros). */
+-#define CODEC_OLD_CHANNEL_LAYOUTS(...)
+-#define CODEC_OLD_CHANNEL_LAYOUTS_ARRAY(array)
+-#endif
+-
+ #define FF_CODEC_DECODE_CB(func)                          \
+     .cb_type           = FF_CODEC_CB_TYPE_DECODE,         \
+     .cb.decode         = (func)
+ #define FF_CODEC_DECODE_SUB_CB(func)                      \
+     .cb_type           = FF_CODEC_CB_TYPE_DECODE_SUB,     \
+     .cb.decode_sub     = (func)
+ #define FF_CODEC_RECEIVE_FRAME_CB(func)                   \
+     .cb_type           = FF_CODEC_CB_TYPE_RECEIVE_FRAME,  \
+diff --git a/media/ffvpx/libavcodec/codec_par.c b/media/ffvpx/libavcodec/codec_par.c
+--- a/media/ffvpx/libavcodec/codec_par.c
++++ b/media/ffvpx/libavcodec/codec_par.c
+@@ -163,42 +163,19 @@ int avcodec_parameters_from_context(AVCo
+         par->color_space         = codec->colorspace;
+         par->chroma_location     = codec->chroma_sample_location;
+         par->sample_aspect_ratio = codec->sample_aspect_ratio;
+         par->video_delay         = codec->has_b_frames;
+         par->framerate           = codec->framerate;
+         break;
+     case AVMEDIA_TYPE_AUDIO:
+         par->format           = codec->sample_fmt;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        // if the old/new fields are set inconsistently, prefer the old ones
+-        if ((codec->channels && codec->channels != codec->ch_layout.nb_channels) ||
+-            (codec->channel_layout && (codec->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
+-                                       codec->ch_layout.u.mask != codec->channel_layout))) {
+-            if (codec->channel_layout)
+-                av_channel_layout_from_mask(&par->ch_layout, codec->channel_layout);
+-            else {
+-                par->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+-                par->ch_layout.nb_channels = codec->channels;
+-            }
+-FF_ENABLE_DEPRECATION_WARNINGS
+-        } else {
+-#endif
+         ret = av_channel_layout_copy(&par->ch_layout, &codec->ch_layout);
+         if (ret < 0)
+             return ret;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        }
+-        par->channel_layout  = par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
+-                               par->ch_layout.u.mask : 0;
+-        par->channels        = par->ch_layout.nb_channels;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+         par->sample_rate      = codec->sample_rate;
+         par->block_align      = codec->block_align;
+         par->frame_size       = codec->frame_size;
+         par->initial_padding  = codec->initial_padding;
+         par->trailing_padding = codec->trailing_padding;
+         par->seek_preroll     = codec->seek_preroll;
+         break;
+     case AVMEDIA_TYPE_SUBTITLE:
+@@ -250,42 +227,19 @@ int avcodec_parameters_to_context(AVCode
+         codec->colorspace             = par->color_space;
+         codec->chroma_sample_location = par->chroma_location;
+         codec->sample_aspect_ratio    = par->sample_aspect_ratio;
+         codec->has_b_frames           = par->video_delay;
+         codec->framerate              = par->framerate;
+         break;
+     case AVMEDIA_TYPE_AUDIO:
+         codec->sample_fmt       = par->format;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        // if the old/new fields are set inconsistently, prefer the old ones
+-        if ((par->channels && par->channels != par->ch_layout.nb_channels) ||
+-            (par->channel_layout && (par->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
+-                                     par->ch_layout.u.mask != par->channel_layout))) {
+-            if (par->channel_layout)
+-                av_channel_layout_from_mask(&codec->ch_layout, par->channel_layout);
+-            else {
+-                codec->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+-                codec->ch_layout.nb_channels = par->channels;
+-            }
+-FF_ENABLE_DEPRECATION_WARNINGS
+-        } else {
+-#endif
+         ret = av_channel_layout_copy(&codec->ch_layout, &par->ch_layout);
+         if (ret < 0)
+             return ret;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        }
+-        codec->channel_layout = codec->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
+-                                codec->ch_layout.u.mask : 0;
+-        codec->channels       = codec->ch_layout.nb_channels;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+         codec->sample_rate      = par->sample_rate;
+         codec->block_align      = par->block_align;
+         codec->frame_size       = par->frame_size;
+         codec->delay            =
+         codec->initial_padding  = par->initial_padding;
+         codec->trailing_padding = par->trailing_padding;
+         codec->seek_preroll     = par->seek_preroll;
+         break;
+diff --git a/media/ffvpx/libavcodec/codec_par.h b/media/ffvpx/libavcodec/codec_par.h
+--- a/media/ffvpx/libavcodec/codec_par.h
++++ b/media/ffvpx/libavcodec/codec_par.h
+@@ -68,16 +68,29 @@ typedef struct AVCodecParameters {
+      */
+     uint8_t *extradata;
+     /**
+      * Size of the extradata content in bytes.
+      */
+     int      extradata_size;
+ 
+     /**
++     * Additional data associated with the entire stream.
++     *
++     * Should be allocated with av_packet_side_data_new() or
++     * av_packet_side_data_add(), and will be freed by avcodec_parameters_free().
++     */
++    AVPacketSideData *coded_side_data;
++
++    /**
++     * Amount of entries in @ref coded_side_data.
++     */
++    int nb_coded_side_data;
++
++    /**
+      * - video: the pixel format, the value corresponds to enum AVPixelFormat.
+      * - audio: the sample format, the value corresponds to enum AVSampleFormat.
+      */
+     int format;
+ 
+     /**
+      * The average bitrate of the encoded data (in bits per second).
+      */
+@@ -126,16 +139,28 @@ typedef struct AVCodecParameters {
+      * should have when displayed.
+      *
+      * When the aspect ratio is unknown / undefined, the numerator should be
+      * set to 0 (the denominator may have any value).
+      */
+     AVRational sample_aspect_ratio;
+ 
+     /**
++     * Video only. Number of frames per second, for streams with constant frame
++     * durations. Should be set to { 0, 1 } when some frames have differing
++     * durations or if the value is not known.
++     *
++     * @note This field correponds to values that are stored in codec-level
++     * headers and is typically overridden by container/transport-layer
++     * timestamps, when available. It should thus be used only as a last resort,
++     * when no higher-level timing information is available.
++     */
++    AVRational framerate;
++
++    /**
+      * Video only. The order of the fields in interlaced video.
+      */
+     enum AVFieldOrder                  field_order;
+ 
+     /**
+      * Video only. Additional colorspace characteristics.
+      */
+     enum AVColorRange                  color_range;
+@@ -144,32 +169,20 @@ typedef struct AVCodecParameters {
+     enum AVColorSpace                  color_space;
+     enum AVChromaLocation              chroma_location;
+ 
+     /**
+      * Video only. Number of delayed frames.
+      */
+     int video_delay;
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+     /**
+-     * Audio only. The channel layout bitmask. May be 0 if the channel layout is
+-     * unknown or unspecified, otherwise the number of bits set must be equal to
+-     * the channels field.
+-     * @deprecated use ch_layout
++     * Audio only. The channel layout and number of channels.
+      */
+-    attribute_deprecated
+-    uint64_t channel_layout;
+-    /**
+-     * Audio only. The number of audio channels.
+-     * @deprecated use ch_layout.nb_channels
+-     */
+-    attribute_deprecated
+-    int      channels;
+-#endif
++    AVChannelLayout ch_layout;
+     /**
+      * Audio only. The number of audio samples per second.
+      */
+     int      sample_rate;
+     /**
+      * Audio only. The number of bytes per coded audio frame, required by some
+      * formats.
+      *
+@@ -194,46 +207,16 @@ typedef struct AVCodecParameters {
+      * discarded by the caller from the end of the stream to get the original
+      * audio without any trailing padding.
+      */
+     int trailing_padding;
+     /**
+      * Audio only. Number of samples to skip after a discontinuity.
+      */
+     int seek_preroll;
+-
+-    /**
+-     * Audio only. The channel layout and number of channels.
+-     */
+-    AVChannelLayout ch_layout;
+-
+-    /**
+-     * Video only. Number of frames per second, for streams with constant frame
+-     * durations. Should be set to { 0, 1 } when some frames have differing
+-     * durations or if the value is not known.
+-     *
+-     * @note This field correponds to values that are stored in codec-level
+-     * headers and is typically overridden by container/transport-layer
+-     * timestamps, when available. It should thus be used only as a last resort,
+-     * when no higher-level timing information is available.
+-     */
+-    AVRational framerate;
+-
+-    /**
+-     * Additional data associated with the entire stream.
+-     *
+-     * Should be allocated with av_packet_side_data_new() or
+-     * av_packet_side_data_add(), and will be freed by avcodec_parameters_free().
+-     */
+-    AVPacketSideData *coded_side_data;
+-
+-    /**
+-     * Amount of entries in @ref coded_side_data.
+-     */
+-    int nb_coded_side_data;
+ } AVCodecParameters;
+ 
+ /**
+  * Allocate a new AVCodecParameters and set its fields to default values
+  * (unknown/invalid/0). The returned struct must be freed with
+  * avcodec_parameters_free().
+  */
+ AVCodecParameters *avcodec_parameters_alloc(void);
+diff --git a/media/ffvpx/libavcodec/decode.c b/media/ffvpx/libavcodec/decode.c
+--- a/media/ffvpx/libavcodec/decode.c
++++ b/media/ffvpx/libavcodec/decode.c
+@@ -30,16 +30,18 @@
+ #include "libavutil/avassert.h"
+ #include "libavutil/channel_layout.h"
+ #include "libavutil/common.h"
+ #include "libavutil/emms.h"
+ #include "libavutil/frame.h"
+ #include "libavutil/hwcontext.h"
+ #include "libavutil/imgutils.h"
+ #include "libavutil/internal.h"
++#include "libavutil/mastering_display_metadata.h"
++#include "libavutil/mem.h"
+ 
+ #include "avcodec.h"
+ #include "avcodec_internal.h"
+ #include "bytestream.h"
+ #include "bsf.h"
+ #include "codec_desc.h"
+ #include "codec_internal.h"
+ #include "decode.h"
+@@ -55,16 +57,27 @@ typedef struct DecodeContext {
+ 
+     /* to prevent infinite loop on errors when draining */
+     int nb_draining_errors;
+ 
+     /**
+      * The caller has submitted a NULL packet on input.
+      */
+     int draining_started;
++
++    int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far
++    int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
++    int64_t pts_correction_last_pts;       /// PTS of the last frame
++    int64_t pts_correction_last_dts;       /// DTS of the last frame
++
++    /**
++     * Bitmask indicating for which side data types we prefer user-supplied
++     * (global or attached to packets) side data over bytestream.
++     */
++    uint64_t side_data_pref_mask;
+ } DecodeContext;
+ 
+ static DecodeContext *decode_ctx(AVCodecInternal *avci)
+ {
+     return (DecodeContext *)avci;
+ }
+ 
+ static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt)
+@@ -87,49 +100,16 @@ static int apply_param_change(AVCodecCon
+     }
+ 
+     if (size < 4)
+         goto fail;
+ 
+     flags = bytestream_get_le32(&data);
+     size -= 4;
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) {
+-        if (size < 4)
+-            goto fail;
+-        val = bytestream_get_le32(&data);
+-        if (val <= 0 || val > INT_MAX) {
+-            av_log(avctx, AV_LOG_ERROR, "Invalid channel count");
+-            ret = AVERROR_INVALIDDATA;
+-            goto fail2;
+-        }
+-        av_channel_layout_uninit(&avctx->ch_layout);
+-        avctx->ch_layout.nb_channels = val;
+-        avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+-        size -= 4;
+-    }
+-    if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) {
+-        if (size < 8)
+-            goto fail;
+-        av_channel_layout_uninit(&avctx->ch_layout);
+-        ret = av_channel_layout_from_mask(&avctx->ch_layout, bytestream_get_le64(&data));
+-        if (ret < 0)
+-            goto fail2;
+-        size -= 8;
+-    }
+-    if (flags & (AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT |
+-                 AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT)) {
+-        avctx->channels = avctx->ch_layout.nb_channels;
+-        avctx->channel_layout = (avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) ?
+-                                avctx->ch_layout.u.mask : 0;
+-    }
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) {
+         if (size < 4)
+             goto fail;
+         val = bytestream_get_le32(&data);
+         if (val <= 0 || val > INT_MAX) {
+             av_log(avctx, AV_LOG_ERROR, "Invalid sample rate");
+             ret = AVERROR_INVALIDDATA;
+             goto fail2;
+@@ -268,34 +248,34 @@ int ff_decode_get_packet(AVCodecContext 
+  * which might have incorrect times. Input timestamps may wrap around, in
+  * which case the output will as well.
+  *
+  * @param pts the pts field of the decoded AVPacket, as passed through
+  * AVFrame.pts
+  * @param dts the dts field of the decoded AVPacket
+  * @return one of the input values, may be AV_NOPTS_VALUE
+  */
+-static int64_t guess_correct_pts(AVCodecContext *ctx,
++static int64_t guess_correct_pts(DecodeContext *dc,
+                                  int64_t reordered_pts, int64_t dts)
+ {
+     int64_t pts = AV_NOPTS_VALUE;
+ 
+     if (dts != AV_NOPTS_VALUE) {
+-        ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts;
+-        ctx->pts_correction_last_dts = dts;
++        dc->pts_correction_num_faulty_dts += dts <= dc->pts_correction_last_dts;
++        dc->pts_correction_last_dts = dts;
+     } else if (reordered_pts != AV_NOPTS_VALUE)
+-        ctx->pts_correction_last_dts = reordered_pts;
++        dc->pts_correction_last_dts = reordered_pts;
+ 
+     if (reordered_pts != AV_NOPTS_VALUE) {
+-        ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts;
+-        ctx->pts_correction_last_pts = reordered_pts;
++        dc->pts_correction_num_faulty_pts += reordered_pts <= dc->pts_correction_last_pts;
++        dc->pts_correction_last_pts = reordered_pts;
+     } else if(dts != AV_NOPTS_VALUE)
+-        ctx->pts_correction_last_pts = dts;
++        dc->pts_correction_last_pts = dts;
+ 
+-    if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE)
++    if ((dc->pts_correction_num_faulty_pts<=dc->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE)
+        && reordered_pts != AV_NOPTS_VALUE)
+         pts = reordered_pts;
+     else
+         pts = dts;
+ 
+     return pts;
+ }
+ 
+@@ -577,25 +557,16 @@ static int fill_frame_props(const AVCode
+     } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
+         if (frame->format == AV_SAMPLE_FMT_NONE)
+             frame->format = avctx->sample_fmt;
+         if (!frame->ch_layout.nb_channels) {
+             ret = av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout);
+             if (ret < 0)
+                 return ret;
+         }
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        if (!frame->channel_layout)
+-            frame->channel_layout = avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
+-                                    avctx->ch_layout.u.mask : 0;
+-        if (!frame->channels)
+-            frame->channels = avctx->ch_layout.nb_channels;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+         if (!frame->sample_rate)
+             frame->sample_rate = avctx->sample_rate;
+     }
+ 
+     return 0;
+ }
+ 
+ static int decode_simple_receive_frame(AVCodecContext *avctx, AVFrame *frame)
+@@ -612,16 +583,17 @@ static int decode_simple_receive_frame(A
+     }
+ 
+     return 0;
+ }
+ 
+ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
+ {
+     AVCodecInternal *avci = avctx->internal;
++    DecodeContext     *dc = decode_ctx(avci);
+     const FFCodec *const codec = ffcodec(avctx->codec);
+     int ret, ok;
+ 
+     av_assert0(!frame->buf[0]);
+ 
+     if (codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME) {
+         ret = codec->cb.receive_frame(avctx, frame);
+         emms_c();
+@@ -667,26 +639,20 @@ FF_DISABLE_DEPRECATION_WARNINGS
+ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+ #if FF_API_INTERLACED_FRAME
+ FF_DISABLE_DEPRECATION_WARNINGS
+         frame->interlaced_frame = !!(frame->flags & AV_FRAME_FLAG_INTERLACED);
+         frame->top_field_first =  !!(frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
+ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+-        frame->best_effort_timestamp = guess_correct_pts(avctx,
++        frame->best_effort_timestamp = guess_correct_pts(dc,
+                                                          frame->pts,
+                                                          frame->pkt_dts);
+ 
+-#if FF_API_PKT_DURATION
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        frame->pkt_duration = frame->duration;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+         /* the only case where decode data is not set should be decoders
+          * that do not call ff_get_buffer() */
+         av_assert0((frame->private_ref && frame->private_ref->size == sizeof(FrameDecodeData)) ||
+                    !(avctx->codec->capabilities & AV_CODEC_CAP_DR1));
+ 
+         if (frame->private_ref) {
+             FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data;
+ 
+@@ -815,21 +781,16 @@ int ff_decode_receive_frame(AVCodecConte
+ 
+     if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+         ret = apply_cropping(avctx, frame);
+         if (ret < 0)
+             goto fail;
+     }
+ 
+     avctx->frame_num++;
+-#if FF_API_AVCTX_FRAME_NUMBER
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    avctx->frame_number = avctx->frame_num;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+ 
+ #if FF_API_DROPCHANGED
+     if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) {
+ 
+         if (avctx->frame_num == 1) {
+             avci->initial_format = frame->format;
+             switch(avctx->codec_type) {
+             case AVMEDIA_TYPE_VIDEO:
+@@ -972,18 +933,18 @@ int avcodec_decode_subtitle2(AVCodecCont
+     int ret = 0;
+ 
+     if (!avpkt->data && avpkt->size) {
+         av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
+         return AVERROR(EINVAL);
+     }
+     if (!avctx->codec)
+         return AVERROR(EINVAL);
+-    if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) {
+-        av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n");
++    if (ffcodec(avctx->codec)->cb_type != FF_CODEC_CB_TYPE_DECODE_SUB) {
++        av_log(avctx, AV_LOG_ERROR, "Codec not subtitle decoder\n");
+         return AVERROR(EINVAL);
+     }
+ 
+     *got_sub_ptr = 0;
+     get_subtitle_defaults(sub);
+ 
+     if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) {
+         AVCodecInternal *avci = avctx->internal;
+@@ -1027,21 +988,16 @@ int avcodec_decode_subtitle2(AVCodecCont
+                 avsubtitle_free(sub);
+                 *got_sub_ptr = 0;
+                 return AVERROR_INVALIDDATA;
+             }
+         }
+ 
+         if (*got_sub_ptr)
+             avctx->frame_num++;
+-#if FF_API_AVCTX_FRAME_NUMBER
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        avctx->frame_number = avctx->frame_num;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     }
+ 
+     return ret;
+ }
+ 
+ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *avctx,
+                                               const enum AVPixelFormat *fmt)
+ {
+@@ -1366,18 +1322,18 @@ int ff_get_format(AVCodecContext *avctx,
+                    AV_CODEC_HW_CONFIG_METHOD_AD_HOC) {
+             // Some ad-hoc configuration we can't see and can't check.
+         } else {
+             av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: "
+                    "missing configuration.\n", desc->name);
+             goto try_again;
+         }
+         if (hw_config->hwaccel) {
+-            av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel "
+-                   "initialisation.\n", desc->name);
++            av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel %s "
++                   "initialisation.\n", desc->name, hw_config->hwaccel->p.name);
+             err = hwaccel_init(avctx, hw_config->hwaccel);
+             if (err < 0)
+                 goto try_again;
+         }
+         ret = user_choice;
+         break;
+ 
+     try_again:
+@@ -1416,60 +1372,46 @@ static int add_metadata_from_side_data(c
+ 
+     AVDictionary **frame_md = &frame->metadata;
+ 
+     side_metadata = av_packet_get_side_data(avpkt,
+                                             AV_PKT_DATA_STRINGS_METADATA, &size);
+     return av_packet_unpack_dictionary(side_metadata, size, frame_md);
+ }
+ 
+-static const struct {
+-    enum AVPacketSideDataType packet;
+-    enum AVFrameSideDataType frame;
+-} sd_global_map[] = {
+-    { AV_PKT_DATA_REPLAYGAIN ,                AV_FRAME_DATA_REPLAYGAIN },
+-    { AV_PKT_DATA_DISPLAYMATRIX,              AV_FRAME_DATA_DISPLAYMATRIX },
+-    { AV_PKT_DATA_SPHERICAL,                  AV_FRAME_DATA_SPHERICAL },
+-    { AV_PKT_DATA_STEREO3D,                   AV_FRAME_DATA_STEREO3D },
+-    { AV_PKT_DATA_AUDIO_SERVICE_TYPE,         AV_FRAME_DATA_AUDIO_SERVICE_TYPE },
+-    { AV_PKT_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA },
+-    { AV_PKT_DATA_CONTENT_LIGHT_LEVEL,        AV_FRAME_DATA_CONTENT_LIGHT_LEVEL },
+-    { AV_PKT_DATA_ICC_PROFILE,                AV_FRAME_DATA_ICC_PROFILE },
+-    { AV_PKT_DATA_DYNAMIC_HDR10_PLUS,         AV_FRAME_DATA_DYNAMIC_HDR_PLUS },
+-};
+-
+ int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx,
+                                    AVFrame *frame, const AVPacket *pkt)
+ {
+     static const struct {
+         enum AVPacketSideDataType packet;
+         enum AVFrameSideDataType frame;
+     } sd[] = {
+         { AV_PKT_DATA_A53_CC,                     AV_FRAME_DATA_A53_CC },
+         { AV_PKT_DATA_AFD,                        AV_FRAME_DATA_AFD },
++        { AV_PKT_DATA_DYNAMIC_HDR10_PLUS,         AV_FRAME_DATA_DYNAMIC_HDR_PLUS },
+         { AV_PKT_DATA_S12M_TIMECODE,              AV_FRAME_DATA_S12M_TIMECODE },
+         { AV_PKT_DATA_SKIP_SAMPLES,               AV_FRAME_DATA_SKIP_SAMPLES },
+     };
+ 
+     frame->pts          = pkt->pts;
+     frame->duration     = pkt->duration;
+ #if FF_API_FRAME_PKT
+ FF_DISABLE_DEPRECATION_WARNINGS
+     frame->pkt_pos      = pkt->pos;
+     frame->pkt_size     = pkt->size;
+ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+ 
+-    for (int i = 0; i < FF_ARRAY_ELEMS(sd_global_map); i++) {
++    for (int i = 0; ff_sd_global_map[i].packet < AV_PKT_DATA_NB; i++) {
+         size_t size;
+-        const uint8_t *packet_sd = av_packet_get_side_data(pkt, sd_global_map[i].packet, &size);
++        const uint8_t *packet_sd = av_packet_get_side_data(pkt, ff_sd_global_map[i].packet, &size);
+         if (packet_sd) {
+             AVFrameSideData *frame_sd;
+ 
+-            frame_sd = av_frame_new_side_data(frame, sd_global_map[i].frame, size);
++            frame_sd = av_frame_new_side_data(frame, ff_sd_global_map[i].frame, size);
+             if (!frame_sd)
+                 return AVERROR(ENOMEM);
+             memcpy(frame_sd->data, packet_sd, size);
+         }
+     }
+     for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) {
+         size_t size;
+         uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size);
+@@ -1500,22 +1442,22 @@ FF_ENABLE_DEPRECATION_WARNINGS
+ 
+     return 0;
+ }
+ 
+ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
+ {
+     int ret;
+ 
+-    for (int i = 0; i < FF_ARRAY_ELEMS(sd_global_map); i++) {
++    for (int i = 0; ff_sd_global_map[i].packet < AV_PKT_DATA_NB; i++) {
+         const AVPacketSideData *packet_sd = ff_get_coded_side_data(avctx,
+-                                                                   sd_global_map[i].packet);
++                                                                   ff_sd_global_map[i].packet);
+         if (packet_sd) {
+             AVFrameSideData *frame_sd = av_frame_new_side_data(frame,
+-                                                               sd_global_map[i].frame,
++                                                               ff_sd_global_map[i].frame,
+                                                                packet_sd->size);
+             if (!frame_sd)
+                 return AVERROR(ENOMEM);
+ 
+             memcpy(frame_sd->data, packet_sd->data, packet_sd->size);
+         }
+     }
+ 
+@@ -1526,21 +1468,16 @@ int ff_decode_frame_props(AVCodecContext
+         if (ret < 0)
+             return ret;
+ #if FF_API_FRAME_PKT
+ FF_DISABLE_DEPRECATION_WARNINGS
+         frame->pkt_size = pkt->stream_index;
+ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+     }
+-#if FF_API_REORDERED_OPAQUE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    frame->reordered_opaque = avctx->reordered_opaque;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+ 
+     ret = fill_frame_props(avctx, frame);
+     if (ret < 0)
+         return ret;
+ 
+     switch (avctx->codec->type) {
+     case AVMEDIA_TYPE_VIDEO:
+         if (frame->width && frame->height &&
+@@ -1637,25 +1574,16 @@ int ff_get_buffer(AVCodecContext *avctx,
+         }
+ 
+         if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) {
+             av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n");
+             ret = AVERROR(EINVAL);
+             goto fail;
+         }
+     } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        /* compat layer for old-style get_buffer() implementations */
+-        avctx->channels = avctx->ch_layout.nb_channels;
+-        avctx->channel_layout = (avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) ?
+-                                avctx->ch_layout.u.mask : 0;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+         if (frame->nb_samples * (int64_t)avctx->ch_layout.nb_channels > avctx->max_samples) {
+             av_log(avctx, AV_LOG_ERROR, "samples per frame %d, exceeds max_samples %"PRId64"\n", frame->nb_samples, avctx->max_samples);
+             ret = AVERROR(EINVAL);
+             goto fail;
+         }
+     }
+     ret = ff_decode_frame_props(avctx, frame);
+     if (ret < 0)
+@@ -1738,16 +1666,17 @@ int ff_reget_buffer(AVCodecContext *avct
+     if (ret < 0)
+         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+     return ret;
+ }
+ 
+ int ff_decode_preinit(AVCodecContext *avctx)
+ {
+     AVCodecInternal *avci = avctx->internal;
++    DecodeContext     *dc = decode_ctx(avci);
+     int ret = 0;
+ 
+     /* if the decoder init function was already called previously,
+      * free the already allocated subtitle_header before overwriting it */
+     av_freep(&avctx->subtitle_header);
+ 
+     if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) {
+         av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
+@@ -1785,29 +1714,58 @@ int ff_decode_preinit(AVCodecContext *av
+                        "conversion needs a libavcodec built with iconv support "
+                        "for this codec\n");
+                 return AVERROR(ENOSYS);
+ #endif
+             }
+         }
+     }
+ 
+-    avctx->pts_correction_num_faulty_pts =
+-    avctx->pts_correction_num_faulty_dts = 0;
+-    avctx->pts_correction_last_pts =
+-    avctx->pts_correction_last_dts = INT64_MIN;
++    dc->pts_correction_num_faulty_pts =
++    dc->pts_correction_num_faulty_dts = 0;
++    dc->pts_correction_last_pts =
++    dc->pts_correction_last_dts = INT64_MIN;
+ 
+     if (   !CONFIG_GRAY && avctx->flags & AV_CODEC_FLAG_GRAY
+         && avctx->codec_descriptor->type == AVMEDIA_TYPE_VIDEO)
+         av_log(avctx, AV_LOG_WARNING,
+                "gray decoding requested but not enabled at configuration time\n");
+     if (avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) {
+         avctx->export_side_data |= AV_CODEC_EXPORT_DATA_MVS;
+     }
+ 
++    if (avctx->nb_side_data_prefer_packet == 1 &&
++        avctx->side_data_prefer_packet[0] == -1)
++        dc->side_data_pref_mask = ~0ULL;
++    else {
++        for (unsigned i = 0; i < avctx->nb_side_data_prefer_packet; i++) {
++            int val = avctx->side_data_prefer_packet[i];
++
++            if (val < 0 || val >= AV_PKT_DATA_NB) {
++                av_log(avctx, AV_LOG_ERROR, "Invalid side data type: %d\n", val);
++                return AVERROR(EINVAL);
++            }
++
++            for (unsigned j = 0; ff_sd_global_map[j].packet < AV_PKT_DATA_NB; j++) {
++                if (ff_sd_global_map[j].packet == val) {
++                    val = ff_sd_global_map[j].frame;
++
++                    // this code will need to be changed when we have more than
++                    // 64 frame side data types
++                    if (val >= 64) {
++                        av_log(avctx, AV_LOG_ERROR, "Side data type too big\n");
++                        return AVERROR_BUG;
++                    }
++
++                    dc->side_data_pref_mask |= 1ULL << val;
++                }
++            }
++        }
++    }
++
+     avci->in_pkt         = av_packet_alloc();
+     avci->last_pkt_props = av_packet_alloc();
+     if (!avci->in_pkt || !avci->last_pkt_props)
+         return AVERROR(ENOMEM);
+ 
+     ret = decode_bsfs_init(avctx);
+     if (ret < 0)
+         return ret;
+@@ -1815,16 +1773,106 @@ int ff_decode_preinit(AVCodecContext *av
+ #if FF_API_DROPCHANGED
+     if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED)
+         av_log(avctx, AV_LOG_WARNING, "The dropchanged flag is deprecated.\n");
+ #endif
+ 
+     return 0;
+ }
+ 
++/**
++ * Check side data preference and clear existing side data from frame
++ * if needed.
++ *
++ * @retval 0 side data of this type can be added to frame
++ * @retval 1 side data of this type should not be added to frame
++ */
++static int side_data_pref(const AVCodecContext *avctx, AVFrame *frame,
++                          enum AVFrameSideDataType type)
++{
++    DecodeContext *dc = decode_ctx(avctx->internal);
++
++    // Note: could be skipped for `type` without corresponding packet sd
++    if (av_frame_get_side_data(frame, type)) {
++        if (dc->side_data_pref_mask & (1ULL << type))
++            return 1;
++        av_frame_remove_side_data(frame, type);
++    }
++
++    return 0;
++}
++
++
++int ff_frame_new_side_data(const AVCodecContext *avctx, AVFrame *frame,
++                           enum AVFrameSideDataType type, size_t size,
++                           AVFrameSideData **psd)
++{
++    AVFrameSideData *sd;
++
++    if (side_data_pref(avctx, frame, type)) {
++        if (psd)
++            *psd = NULL;
++        return 0;
++    }
++
++    sd = av_frame_new_side_data(frame, type, size);
++    if (psd)
++        *psd = sd;
++
++    return sd ? 0 : AVERROR(ENOMEM);
++}
++
++int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx,
++                                    AVFrame *frame, enum AVFrameSideDataType type,
++                                    AVBufferRef **buf, AVFrameSideData **psd)
++{
++    AVFrameSideData *sd = NULL;
++    int ret = 0;
++
++    if (side_data_pref(avctx, frame, type))
++        goto finish;
++
++    sd = av_frame_new_side_data_from_buf(frame, type, *buf);
++    if (sd)
++        *buf = NULL;
++    else
++        ret = AVERROR(ENOMEM);
++
++finish:
++    av_buffer_unref(buf);
++    if (psd)
++        *psd = sd;
++
++    return ret;
++}
++
++int ff_decode_mastering_display_new(const AVCodecContext *avctx, AVFrame *frame,
++                                    AVMasteringDisplayMetadata **mdm)
++{
++    if (side_data_pref(avctx, frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA)) {
++        *mdm = NULL;
++        return 0;
++    }
++
++    *mdm = av_mastering_display_metadata_create_side_data(frame);
++    return *mdm ? 0 : AVERROR(ENOMEM);
++}
++
++int ff_decode_content_light_new(const AVCodecContext *avctx, AVFrame *frame,
++                                AVContentLightMetadata **clm)
++{
++    if (side_data_pref(avctx, frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL)) {
++        *clm = NULL;
++        return 0;
++    }
++
++    *clm = av_content_light_metadata_create_side_data(frame);
++    return *clm ? 0 : AVERROR(ENOMEM);
++}
++
+ int ff_copy_palette(void *dst, const AVPacket *src, void *logctx)
+ {
+     size_t size;
+     const void *pal = av_packet_get_side_data(src, AV_PKT_DATA_PALETTE, &size);
+ 
+     if (pal && size == AVPALETTE_SIZE) {
+         memcpy(dst, pal, AVPALETTE_SIZE);
+         return 1;
+@@ -1867,18 +1915,18 @@ int ff_hwaccel_frame_priv_alloc(AVCodecC
+ void ff_decode_flush_buffers(AVCodecContext *avctx)
+ {
+     AVCodecInternal *avci = avctx->internal;
+     DecodeContext     *dc = decode_ctx(avci);
+ 
+     av_packet_unref(avci->last_pkt_props);
+     av_packet_unref(avci->in_pkt);
+ 
+-    avctx->pts_correction_last_pts =
+-    avctx->pts_correction_last_dts = INT64_MIN;
++    dc->pts_correction_last_pts =
++    dc->pts_correction_last_dts = INT64_MIN;
+ 
+     av_bsf_flush(avci->bsf);
+ 
+     dc->nb_draining_errors = 0;
+     dc->draining_started   = 0;
+ }
+ 
+ AVCodecInternal *ff_decode_internal_alloc(void)
+diff --git a/media/ffvpx/libavcodec/decode.h b/media/ffvpx/libavcodec/decode.h
+--- a/media/ffvpx/libavcodec/decode.h
++++ b/media/ffvpx/libavcodec/decode.h
+@@ -150,9 +150,50 @@ int ff_side_data_update_matrix_encoding(
+ int ff_hwaccel_frame_priv_alloc(AVCodecContext *avctx, void **hwaccel_picture_private);
+ 
+ /**
+  * Get side data of the given type from a decoding context.
+  */
+ const AVPacketSideData *ff_get_coded_side_data(const AVCodecContext *avctx,
+                                                enum AVPacketSideDataType type);
+ 
++/**
++ * Wrapper around av_frame_new_side_data, which rejects side data overridden by
++ * the demuxer. Returns 0 on success, and a negative error code otherwise.
++ * If successful and sd is not NULL, *sd may either contain a pointer to the new
++ * side data, or NULL in case the side data was already present.
++ */
++int ff_frame_new_side_data(const AVCodecContext *avctx, AVFrame *frame,
++                           enum AVFrameSideDataType type, size_t size,
++                           AVFrameSideData **sd);
++
++/**
++ * Similar to `ff_frame_new_side_data`, but using an existing buffer ref.
++ *
++ * *buf is ALWAYS consumed by this function and NULL written in its place, even
++ * on failure.
++ */
++int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx,
++                                    AVFrame *frame, enum AVFrameSideDataType type,
++                                    AVBufferRef **buf, AVFrameSideData **sd);
++
++struct AVMasteringDisplayMetadata;
++struct AVContentLightMetadata;
++
++/**
++ * Wrapper around av_mastering_display_metadata_create_side_data(), which
++ * rejects side data overridden by the demuxer. Returns 0 on success, and a
++ * negative error code otherwise. If successful, *mdm may either be a pointer to
++ * the new side data, or NULL in case the side data was already present.
++ */
++int ff_decode_mastering_display_new(const AVCodecContext *avctx, AVFrame *frame,
++                                    struct AVMasteringDisplayMetadata **mdm);
++
++/**
++ * Wrapper around av_content_light_metadata_create_side_data(), which
++ * rejects side data overridden by the demuxer. Returns 0 on success, and a
++ * negative error code otherwise. If successful, *clm may either be a pointer to
++ * the new side data, or NULL in case the side data was already present.
++ */
++int ff_decode_content_light_new(const AVCodecContext *avctx, AVFrame *frame,
++                                struct AVContentLightMetadata **clm);
++
+ #endif /* AVCODEC_DECODE_H */
+diff --git a/media/ffvpx/libavcodec/dovi_rpu.h b/media/ffvpx/libavcodec/dovi_rpu.h
+new file mode 100644
+--- /dev/null
++++ b/media/ffvpx/libavcodec/dovi_rpu.h
+@@ -0,0 +1,29 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim:set ts=2 sw=2 sts=2 et cindent: */
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++/* Stubs for dovi_rpu.{c,h} */
++
++typedef struct AVCtx AVContext;
++
++typedef struct DOVICtx {
++  int dv_profile;
++  AVContext* logctx;
++  int operating_point;
++} DOVIContext;
++
++typedef struct AVDOVICConfRecord {
++} AVDOVIDecoderConfigurationRecord;
++
++inline void ff_dovi_ctx_unref(DOVIContext* ctx) {}
++inline void ff_dovi_update_cfg(DOVIContext* ctx,
++                               AVDOVIDecoderConfigurationRecord* record) {}
++inline int ff_dovi_rpu_parse(DOVIContext* ctx, uint8_t* buf, size_t len,
++                             int err_recognition) {
++  return 0;
++}
++inline int ff_dovi_attach_side_data(DOVIContext* ctx, AVFrame* frame) {
++  return 0;
++}
+diff --git a/media/ffvpx/libavcodec/encode.c b/media/ffvpx/libavcodec/encode.c
+--- a/media/ffvpx/libavcodec/encode.c
++++ b/media/ffvpx/libavcodec/encode.c
+@@ -20,16 +20,17 @@
+ 
+ #include "libavutil/attributes.h"
+ #include "libavutil/avassert.h"
+ #include "libavutil/channel_layout.h"
+ #include "libavutil/emms.h"
+ #include "libavutil/frame.h"
+ #include "libavutil/imgutils.h"
+ #include "libavutil/internal.h"
++#include "libavutil/mem.h"
+ #include "libavutil/pixdesc.h"
+ #include "libavutil/samplefmt.h"
+ 
+ #include "avcodec.h"
+ #include "avcodec_internal.h"
+ #include "codec_desc.h"
+ #include "codec_internal.h"
+ #include "encode.h"
+@@ -193,21 +194,16 @@ int avcodec_encode_subtitle(AVCodecConte
+     int ret;
+     if (sub->start_display_time) {
+         av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n");
+         return -1;
+     }
+ 
+     ret = ffcodec(avctx->codec)->cb.encode_sub(avctx, buf, buf_size, sub);
+     avctx->frame_num++;
+-#if FF_API_AVCTX_FRAME_NUMBER
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    avctx->frame_number = avctx->frame_num;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     return ret;
+ }
+ 
+ int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
+ {
+     AVCodecInternal *avci = avctx->internal;
+ 
+     if (avci->draining)
+@@ -234,22 +230,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+ 
+     return 0;
+ }
+ 
+ int ff_encode_reordered_opaque(AVCodecContext *avctx,
+                                AVPacket *pkt, const AVFrame *frame)
+ {
+-#if FF_API_REORDERED_OPAQUE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    avctx->reordered_opaque = frame->reordered_opaque;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+     if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+         int ret = av_buffer_replace(&pkt->opaque_ref, frame->opaque_ref);
+         if (ret < 0)
+             return ret;
+         pkt->opaque = frame->opaque;
+     }
+ 
+     return 0;
+@@ -539,21 +529,16 @@ int attribute_align_arg avcodec_send_fra
+ 
+     if (!avci->buffer_pkt->data && !avci->buffer_pkt->side_data) {
+         ret = encode_receive_packet_internal(avctx, avci->buffer_pkt);
+         if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
+             return ret;
+     }
+ 
+     avctx->frame_num++;
+-#if FF_API_AVCTX_FRAME_NUMBER
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    avctx->frame_number = avctx->frame_num;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+ 
+     return 0;
+ }
+ 
+ int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
+ {
+     AVCodecInternal *avci = avctx->internal;
+     int ret;
+@@ -732,16 +717,18 @@ static int encode_preinit_audio(AVCodecC
+                 ret = av_channel_layout_describe(&c->ch_layouts[p], buf, sizeof(buf));
+                 av_log(avctx, AV_LOG_ERROR, "  %s\n", ret > 0 ? buf : "?");
+             }
+             return AVERROR(EINVAL);
+         }
+     }
+ 
+     if (!avctx->bits_per_raw_sample)
++        avctx->bits_per_raw_sample = av_get_exact_bits_per_sample(avctx->codec_id);
++    if (!avctx->bits_per_raw_sample)
+         avctx->bits_per_raw_sample = 8 * av_get_bytes_per_sample(avctx->sample_fmt);
+ 
+     return 0;
+ }
+ 
+ int ff_encode_preinit(AVCodecContext *avctx)
+ {
+     AVCodecInternal *avci = avctx->internal;
+@@ -791,16 +778,39 @@ int ff_encode_preinit(AVCodecContext *av
+             return AVERROR(ENOSYS);
+         }
+ 
+         avci->recon_frame = av_frame_alloc();
+         if (!avci->recon_frame)
+             return AVERROR(ENOMEM);
+     }
+ 
++    for (int i = 0; ff_sd_global_map[i].packet < AV_PKT_DATA_NB; i++) {
++        const enum AVPacketSideDataType type_packet = ff_sd_global_map[i].packet;
++        const enum AVFrameSideDataType  type_frame  = ff_sd_global_map[i].frame;
++        const AVFrameSideData *sd_frame;
++        AVPacketSideData      *sd_packet;
++
++        sd_frame = av_frame_side_data_get(avctx->decoded_side_data,
++                                          avctx->nb_decoded_side_data,
++                                          type_frame);
++        if (!sd_frame ||
++            av_packet_side_data_get(avctx->coded_side_data, avctx->nb_coded_side_data,
++                                    type_packet))
++
++            continue;
++
++        sd_packet = av_packet_side_data_new(&avctx->coded_side_data, &avctx->nb_coded_side_data,
++                                            type_packet, sd_frame->size, 0);
++        if (!sd_packet)
++            return AVERROR(ENOMEM);
++
++        memcpy(sd_packet->data, sd_frame->data, sd_frame->size);
++    }
++
+     if (CONFIG_FRAME_THREAD_ENCODER) {
+         ret = ff_frame_thread_encoder_init(avctx);
+         if (ret < 0)
+             return ret;
+     }
+ 
+     return 0;
+ }
+diff --git a/media/ffvpx/libavcodec/encode.h b/media/ffvpx/libavcodec/encode.h
+--- a/media/ffvpx/libavcodec/encode.h
++++ b/media/ffvpx/libavcodec/encode.h
+@@ -22,16 +22,22 @@
+ #define AVCODEC_ENCODE_H
+ 
+ #include "libavutil/frame.h"
+ 
+ #include "avcodec.h"
+ #include "packet.h"
+ 
+ /**
++ * Used by some encoders as upper bound for the length of headers.
++ * TODO: Use proper codec-specific upper bounds.
++ */
++#define FF_INPUT_BUFFER_MIN_SIZE 16384
++
++/**
+  * Called by encoders to get the next frame for encoding.
+  *
+  * @param frame An empty frame to be filled with data.
+  * @return 0 if a new reference has been successfully written to frame
+  *         AVERROR(EAGAIN) if no data is currently available
+  *         AVERROR_EOF if end of stream has been reached, so no more data
+  *                     will be available
+  */
+diff --git a/media/ffvpx/libavcodec/fdctdsp_init.c b/media/ffvpx/libavcodec/fdctdsp_init.c
+deleted file mode 100644
+--- a/media/ffvpx/libavcodec/fdctdsp_init.c
++++ /dev/null
+@@ -1,44 +0,0 @@
+-/*
+- * 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
+- */
+-
+-#include "libavutil/attributes.h"
+-#include "libavutil/cpu.h"
+-#include "libavutil/x86/cpu.h"
+-#include "libavcodec/avcodec.h"
+-#include "libavcodec/fdctdsp.h"
+-#include "fdct.h"
+-
+-av_cold void ff_fdctdsp_init_x86(FDCTDSPContext *c, AVCodecContext *avctx,
+-                                 unsigned high_bit_depth)
+-{
+-    int cpu_flags = av_get_cpu_flags();
+-    const int dct_algo = avctx->dct_algo;
+-
+-    if (!high_bit_depth) {
+-        if ((dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX)) {
+-            if (INLINE_MMX(cpu_flags))
+-                c->fdct = ff_fdct_mmx;
+-
+-            if (INLINE_MMXEXT(cpu_flags))
+-                c->fdct = ff_fdct_mmxext;
+-
+-            if (INLINE_SSE2(cpu_flags))
+-                c->fdct = ff_fdct_sse2;
+-        }
+-    }
+-}
+diff --git a/media/ffvpx/libavcodec/flacdec.c b/media/ffvpx/libavcodec/flacdec.c
+--- a/media/ffvpx/libavcodec/flacdec.c
++++ b/media/ffvpx/libavcodec/flacdec.c
+@@ -30,24 +30,23 @@
+  * 34-byte streaminfo structure through avctx->extradata[_size] followed
+  * by data starting with the 0xFFF8 marker.
+  */
+ 
+ #include <limits.h>
+ 
+ #include "libavutil/avassert.h"
+ #include "libavutil/crc.h"
++#include "libavutil/mem.h"
+ #include "libavutil/opt.h"
+ #include "avcodec.h"
+ #include "codec_internal.h"
+ #include "get_bits.h"
+-#include "bytestream.h"
+ #include "golomb.h"
+ #include "flac.h"
+-#include "flacdata.h"
+ #include "flacdsp.h"
+ #include "flac_parse.h"
+ #include "thread.h"
+ #include "unary.h"
+ 
+ 
+ typedef struct FLACContext {
+     AVClass *class;
+diff --git a/media/ffvpx/libavcodec/get_bits.h b/media/ffvpx/libavcodec/get_bits.h
+--- a/media/ffvpx/libavcodec/get_bits.h
++++ b/media/ffvpx/libavcodec/get_bits.h
+@@ -89,17 +89,16 @@ typedef BitstreamContext GetBitContext;
+ #define get_sbits_long      bits_read_signed
+ #define show_bits           bits_peek
+ #define show_bits_long      bits_peek
+ #define init_get_bits       bits_init
+ #define init_get_bits8      bits_init8
+ #define align_get_bits      bits_align
+ #define get_vlc2            bits_read_vlc
+ #define get_vlc_multi       bits_read_vlc_multi
+-#define get_leb             bits_read_leb
+ 
+ #define init_get_bits8_le(s, buffer, byte_size) bits_init8_le((BitstreamContextLE*)s, buffer, byte_size)
+ #define get_bits_le(s, n)                       bits_read_le((BitstreamContextLE*)s, n)
+ 
+ #define show_bits1(s)       bits_peek(s, 1)
+ #define skip_bits1(s)       bits_skip(s, 1)
+ 
+ #define skip_1stop_8data_bits bits_skip_1stop_8data
+@@ -663,17 +662,18 @@ static av_always_inline int get_vlc2(Get
+     CLOSE_READER(re, s);
+ 
+     return code;
+ }
+ 
+ static inline int get_vlc_multi(GetBitContext *s, uint8_t *dst,
+                                 const VLC_MULTI_ELEM *const Jtable,
+                                 const VLCElem *const table,
+-                                const int bits, const int max_depth)
++                                const int bits, const int max_depth,
++                                const int symbols_size)
+ {
+     dst[0] = get_vlc2(s, table, bits, max_depth);
+     return 1;
+ }
+ 
+ static inline int decode012(GetBitContext *gb)
+ {
+     int n;
+@@ -706,34 +706,11 @@ static inline int skip_1stop_8data_bits(
+         skip_bits(gb, 8);
+         if (get_bits_left(gb) <= 0)
+             return AVERROR_INVALIDDATA;
+     }
+ 
+     return 0;
+ }
+ 
+-/**
+- * Read a unsigned integer coded as a variable number of up to eight
+- * little-endian bytes, where the MSB in a byte signals another byte
+- * must be read.
+- * All coded bits are read, but values > UINT_MAX are truncated.
+- */
+-static inline unsigned get_leb(GetBitContext *s) {
+-    int more, i = 0;
+-    unsigned leb = 0;
+-
+-    do {
+-        int byte = get_bits(s, 8);
+-        unsigned bits = byte & 0x7f;
+-        more = byte & 0x80;
+-        if (i <= 4)
+-            leb |= bits << (i * 7);
+-        if (++i == 8)
+-            break;
+-    } while (more);
+-
+-    return leb;
+-}
+-
+ #endif // CACHED_BITSTREAM_READER
+ 
+ #endif /* AVCODEC_GET_BITS_H */
+diff --git a/media/ffvpx/libavcodec/get_buffer.c b/media/ffvpx/libavcodec/get_buffer.c
+--- a/media/ffvpx/libavcodec/get_buffer.c
++++ b/media/ffvpx/libavcodec/get_buffer.c
+@@ -65,22 +65,16 @@ static void frame_pool_free(FFRefStructO
+ static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame)
+ {
+     FramePool *pool = avctx->internal->pool;
+     int i, ret, ch, planes;
+ 
+     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
+         int planar = av_sample_fmt_is_planar(frame->format);
+         ch     = frame->ch_layout.nb_channels;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        if (!ch)
+-            ch = frame->channels;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+         planes = planar ? ch : 1;
+     }
+ 
+     if (pool && pool->format == frame->format) {
+         if (avctx->codec_type == AVMEDIA_TYPE_VIDEO &&
+             pool->width == frame->width && pool->height == frame->height)
+             return 0;
+         if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && pool->planes == planes &&
+@@ -258,16 +252,32 @@ fail:
+ }
+ 
+ int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags)
+ {
+     int ret;
+ 
+     if (avctx->hw_frames_ctx) {
+         ret = av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0);
++        if (ret == AVERROR(ENOMEM)) {
++            AVHWFramesContext *frames_ctx =
++                (AVHWFramesContext*)avctx->hw_frames_ctx->data;
++            if (frames_ctx->initial_pool_size > 0 &&
++                !avctx->internal->warned_on_failed_allocation_from_fixed_pool) {
++                av_log(avctx, AV_LOG_WARNING, "Failed to allocate a %s/%s "
++                       "frame from a fixed pool of hardware frames.\n",
++                       av_get_pix_fmt_name(frames_ctx->format),
++                       av_get_pix_fmt_name(frames_ctx->sw_format));
++                av_log(avctx, AV_LOG_WARNING, "Consider setting "
++                       "extra_hw_frames to a larger value "
++                       "(currently set to %d, giving a pool size of %d).\n",
++                       avctx->extra_hw_frames, frames_ctx->initial_pool_size);
++                avctx->internal->warned_on_failed_allocation_from_fixed_pool = 1;
++            }
++        }
+         frame->width  = avctx->coded_width;
+         frame->height = avctx->coded_height;
+         return ret;
+     }
+ 
+     if ((ret = update_frame_pool(avctx, frame)) < 0)
+         return ret;
+ 
+diff --git a/media/ffvpx/libavcodec/hwaccel.h b/media/ffvpx/libavcodec/hwaccel.h
+deleted file mode 100644
+--- a/media/ffvpx/libavcodec/hwaccel.h
++++ /dev/null
+@@ -1,84 +0,0 @@
+-/*
+- * 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
+- */
+-
+-#ifndef AVCODEC_HWACCEL_H
+-#define AVCODEC_HWACCEL_H
+-
+-#include "avcodec.h"
+-#include "hwaccels.h"
+-
+-
+-#define HWACCEL_CAP_ASYNC_SAFE      (1 << 0)
+-
+-
+-typedef struct AVCodecHWConfigInternal {
+-    /**
+-     * This is the structure which will be returned to the user by
+-     * avcodec_get_hw_config().
+-     */
+-    AVCodecHWConfig public;
+-    /**
+-     * If this configuration uses a hwaccel, a pointer to it.
+-     * If not, NULL.
+-     */
+-    const AVHWAccel *hwaccel;
+-} AVCodecHWConfigInternal;
+-
+-
+-// These macros are used to simplify AVCodecHWConfigInternal definitions.
+-
+-#define HW_CONFIG_HWACCEL(device, frames, ad_hoc, format, device_type_, name) \
+-    &(const AVCodecHWConfigInternal) { \
+-        .public          = { \
+-            .pix_fmt     = AV_PIX_FMT_ ## format, \
+-            .methods     = (device ? AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX : 0) | \
+-                           (frames ? AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX : 0) | \
+-                           (ad_hoc ? AV_CODEC_HW_CONFIG_METHOD_AD_HOC        : 0),  \
+-            .device_type = AV_HWDEVICE_TYPE_ ## device_type_, \
+-        }, \
+-        .hwaccel         = &name, \
+-    }
+-
+-#define HW_CONFIG_INTERNAL(format) \
+-    &(const AVCodecHWConfigInternal) { \
+-        .public          = { \
+-            .pix_fmt     = AV_PIX_FMT_ ## format, \
+-            .methods     = AV_CODEC_HW_CONFIG_METHOD_INTERNAL, \
+-            .device_type = AV_HWDEVICE_TYPE_NONE, \
+-        }, \
+-        .hwaccel         = NULL, \
+-    }
+-
+-#define HWACCEL_DXVA2(codec) \
+-    HW_CONFIG_HWACCEL(1, 1, 1, DXVA2_VLD,    DXVA2,        ff_ ## codec ## _dxva2_hwaccel)
+-#define HWACCEL_D3D11VA2(codec) \
+-    HW_CONFIG_HWACCEL(1, 1, 0, D3D11,        D3D11VA,      ff_ ## codec ## _d3d11va2_hwaccel)
+-#define HWACCEL_NVDEC(codec) \
+-    HW_CONFIG_HWACCEL(1, 1, 0, CUDA,         CUDA,         ff_ ## codec ## _nvdec_hwaccel)
+-#define HWACCEL_VAAPI(codec) \
+-    HW_CONFIG_HWACCEL(1, 1, 1, VAAPI,        VAAPI,        ff_ ## codec ## _vaapi_hwaccel)
+-#define HWACCEL_VDPAU(codec) \
+-    HW_CONFIG_HWACCEL(1, 1, 1, VDPAU,        VDPAU,        ff_ ## codec ## _vdpau_hwaccel)
+-#define HWACCEL_VIDEOTOOLBOX(codec) \
+-    HW_CONFIG_HWACCEL(1, 1, 1, VIDEOTOOLBOX, VIDEOTOOLBOX, ff_ ## codec ## _videotoolbox_hwaccel)
+-#define HWACCEL_D3D11VA(codec) \
+-    HW_CONFIG_HWACCEL(0, 0, 1, D3D11VA_VLD,  NONE,         ff_ ## codec ## _d3d11va_hwaccel)
+-#define HWACCEL_XVMC(codec) \
+-    HW_CONFIG_HWACCEL(0, 0, 1, XVMC,         NONE,         ff_ ## codec ## _xvmc_hwaccel)
+-
+-#endif /* AVCODEC_HWACCEL_H */
+diff --git a/media/ffvpx/libavcodec/hwaccel_internal.h b/media/ffvpx/libavcodec/hwaccel_internal.h
+--- a/media/ffvpx/libavcodec/hwaccel_internal.h
++++ b/media/ffvpx/libavcodec/hwaccel_internal.h
+@@ -123,17 +123,17 @@ typedef struct FFHWAccel {
+      * hwaccel_context are set and the hwaccel private data in AVCodecInternal
+      * is allocated.
+      */
+     int (*init)(AVCodecContext *avctx);
+ 
+     /**
+      * Uninitialize the hwaccel private data.
+      *
+-     * This will be called from get_format() or avcodec_close(), after hwaccel
++     * This will be called from get_format() or ff_codec_close(), after hwaccel
+      * and hwaccel_context are already uninitialized.
+      */
+     int (*uninit)(AVCodecContext *avctx);
+ 
+     /**
+      * Fill the given hw_frames context with current codec parameters. Called
+      * from get_format. Refer to avcodec_get_hw_frames_parameters() for
+      * details.
+diff --git a/media/ffvpx/libavcodec/idctdsp.c b/media/ffvpx/libavcodec/idctdsp.c
+--- a/media/ffvpx/libavcodec/idctdsp.c
++++ b/media/ffvpx/libavcodec/idctdsp.c
+@@ -65,17 +65,17 @@ av_cold void ff_init_scantable_permutati
+             idct_permutation[i] = (i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3);
+         break;
+     default:
+         av_log(NULL, AV_LOG_ERROR,
+                "Internal error, IDCT permutation not set\n");
+     }
+ }
+ 
+-void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
++void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels,
+                              ptrdiff_t line_size)
+ {
+     int i;
+ 
+     /* read the pixels */
+     for (i = 0; i < 8; i++) {
+         pixels[0] = av_clip_uint8(block[0]);
+         pixels[1] = av_clip_uint8(block[1]);
+@@ -86,50 +86,50 @@ void ff_put_pixels_clamped_c(const int16
+         pixels[6] = av_clip_uint8(block[6]);
+         pixels[7] = av_clip_uint8(block[7]);
+ 
+         pixels += line_size;
+         block  += 8;
+     }
+ }
+ 
+-static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
++static void put_pixels_clamped4_c(const int16_t *block, uint8_t *restrict pixels,
+                                  int line_size)
+ {
+     int i;
+ 
+     /* read the pixels */
+     for(i=0;i<4;i++) {
+         pixels[0] = av_clip_uint8(block[0]);
+         pixels[1] = av_clip_uint8(block[1]);
+         pixels[2] = av_clip_uint8(block[2]);
+         pixels[3] = av_clip_uint8(block[3]);
+ 
+         pixels += line_size;
+         block += 8;
+     }
+ }
+ 
+-static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
++static void put_pixels_clamped2_c(const int16_t *block, uint8_t *restrict pixels,
+                                  int line_size)
+ {
+     int i;
+ 
+     /* read the pixels */
+     for(i=0;i<2;i++) {
+         pixels[0] = av_clip_uint8(block[0]);
+         pixels[1] = av_clip_uint8(block[1]);
+ 
+         pixels += line_size;
+         block += 8;
+     }
+ }
+ 
+ static void put_signed_pixels_clamped_c(const int16_t *block,
+-                                        uint8_t *av_restrict pixels,
++                                        uint8_t *restrict pixels,
+                                         ptrdiff_t line_size)
+ {
+     int i, j;
+ 
+     for (i = 0; i < 8; i++) {
+         for (j = 0; j < 8; j++) {
+             if (*block < -128)
+                 *pixels = 0;
+@@ -139,17 +139,17 @@ static void put_signed_pixels_clamped_c(
+                 *pixels = (uint8_t) (*block + 128);
+             block++;
+             pixels++;
+         }
+         pixels += (line_size - 8);
+     }
+ }
+ 
+-void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
++void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels,
+                              ptrdiff_t line_size)
+ {
+     int i;
+ 
+     /* read the pixels */
+     for (i = 0; i < 8; i++) {
+         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
+         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
+@@ -159,33 +159,33 @@ void ff_add_pixels_clamped_c(const int16
+         pixels[5] = av_clip_uint8(pixels[5] + block[5]);
+         pixels[6] = av_clip_uint8(pixels[6] + block[6]);
+         pixels[7] = av_clip_uint8(pixels[7] + block[7]);
+         pixels   += line_size;
+         block    += 8;
+     }
+ }
+ 
+-static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
++static void add_pixels_clamped4_c(const int16_t *block, uint8_t *restrict pixels,
+                           int line_size)
+ {
+     int i;
+ 
+     /* read the pixels */
+     for(i=0;i<4;i++) {
+         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
+         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
+         pixels[2] = av_clip_uint8(pixels[2] + block[2]);
+         pixels[3] = av_clip_uint8(pixels[3] + block[3]);
+         pixels += line_size;
+         block += 8;
+     }
+ }
+ 
+-static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
++static void add_pixels_clamped2_c(const int16_t *block, uint8_t *restrict pixels,
+                           int line_size)
+ {
+     int i;
+ 
+     /* read the pixels */
+     for(i=0;i<2;i++) {
+         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
+         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
+diff --git a/media/ffvpx/libavcodec/idctdsp.h b/media/ffvpx/libavcodec/idctdsp.h
+--- a/media/ffvpx/libavcodec/idctdsp.h
++++ b/media/ffvpx/libavcodec/idctdsp.h
+@@ -17,18 +17,16 @@
+  */
+ 
+ #ifndef AVCODEC_IDCTDSP_H
+ #define AVCODEC_IDCTDSP_H
+ 
+ #include <stddef.h>
+ #include <stdint.h>
+ 
+-#include "config.h"
+-
+ struct AVCodecContext;
+ 
+ enum idct_permutation_type {
+     FF_IDCT_PERM_NONE,
+     FF_IDCT_PERM_LIBMPEG2,
+     FF_IDCT_PERM_SIMPLE,
+     FF_IDCT_PERM_TRANSPOSE,
+     FF_IDCT_PERM_PARTTRANS,
+@@ -40,23 +38,23 @@ void ff_permute_scantable(uint8_t dst[64
+ void ff_init_scantable_permutation(uint8_t *idct_permutation,
+                                    enum idct_permutation_type perm_type);
+ int ff_init_scantable_permutation_x86(uint8_t *idct_permutation,
+                                       enum idct_permutation_type perm_type);
+ 
+ typedef struct IDCTDSPContext {
+     /* pixel ops : interface with DCT */
+     void (*put_pixels_clamped)(const int16_t *block /* align 16 */,
+-                               uint8_t *av_restrict pixels /* align 8 */,
++                               uint8_t *restrict pixels /* align 8 */,
+                                ptrdiff_t line_size);
+     void (*put_signed_pixels_clamped)(const int16_t *block /* align 16 */,
+-                                      uint8_t *av_restrict pixels /* align 8 */,
++                                      uint8_t *restrict pixels /* align 8 */,
+                                       ptrdiff_t line_size);
+     void (*add_pixels_clamped)(const int16_t *block /* align 16 */,
+-                               uint8_t *av_restrict pixels /* align 8 */,
++                               uint8_t *restrict pixels /* align 8 */,
+                                ptrdiff_t line_size);
+ 
+     void (*idct)(int16_t *block /* align 16 */);
+ 
+     /**
+      * block -> idct -> clip to unsigned 8 bit -> dest.
+      * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...)
+      * @param line_size size in bytes of a horizontal line of dest
+@@ -86,19 +84,19 @@ typedef struct IDCTDSPContext {
+      *    -> simple_idct_mmx -> ...)
+      */
+     uint8_t idct_permutation[64];
+     enum idct_permutation_type perm_type;
+ 
+     int mpeg4_studio_profile;
+ } IDCTDSPContext;
+ 
+-void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
++void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels,
+                              ptrdiff_t line_size);
+-void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
++void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels,
+                              ptrdiff_t line_size);
+ 
+ void ff_idctdsp_init(IDCTDSPContext *c, struct AVCodecContext *avctx);
+ 
+ void ff_idctdsp_init_aarch64(IDCTDSPContext *c, struct AVCodecContext *avctx,
+                              unsigned high_bit_depth);
+ void ff_idctdsp_init_alpha(IDCTDSPContext *c, struct AVCodecContext *avctx,
+                            unsigned high_bit_depth);
+diff --git a/media/ffvpx/libavcodec/internal.h b/media/ffvpx/libavcodec/internal.h
+--- a/media/ffvpx/libavcodec/internal.h
++++ b/media/ffvpx/libavcodec/internal.h
+@@ -21,20 +21,17 @@
+  * common internal api header.
+  */
+ 
+ #ifndef AVCODEC_INTERNAL_H
+ #define AVCODEC_INTERNAL_H
+ 
+ #include <stdint.h>
+ 
+-#include "libavutil/buffer.h"
+ #include "libavutil/channel_layout.h"
+-#include "libavutil/mathematics.h"
+-#include "libavutil/pixfmt.h"
+ #include "avcodec.h"
+ #include "config.h"
+ 
+ #if CONFIG_LCMS2
+ # include "fflcms2.h"
+ #endif
+ 
+ #define FF_SANE_NB_CHANNELS 512U
+@@ -142,45 +139,32 @@ typedef struct AVCodecInternal {
+     int initial_width, initial_height;
+     int initial_sample_rate;
+     AVChannelLayout initial_ch_layout;
+ #endif
+ 
+ #if CONFIG_LCMS2
+     FFIccContext icc; /* used to read and write embedded ICC profiles */
+ #endif
++
++    /**
++     * Set when the user has been warned about a failed allocation from
++     * a fixed frame pool.
++     */
++    int warned_on_failed_allocation_from_fixed_pool;
+ } AVCodecInternal;
+ 
+ /**
+  * Return the index into tab at which {a,b} match elements {[0],[1]} of tab.
+  * If there is no such matching pair then size is returned.
+  */
+ int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b);
+ 
+ unsigned int ff_toupper4(unsigned int x);
+ 
+-/**
+- * 2^(x) for integer x
+- * @return correctly rounded float
+- */
+-static av_always_inline float ff_exp2fi(int x) {
+-    /* Normal range */
+-    if (-126 <= x && x <= 128)
+-        return av_int2float((x+127) << 23);
+-    /* Too large */
+-    else if (x > 128)
+-        return INFINITY;
+-    /* Subnormal numbers */
+-    else if (x > -150)
+-        return av_int2float(1 << (x+149));
+-    /* Negligibly small */
+-    else
+-        return 0;
+-}
+-
+ int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx);
+ 
+ int avpriv_codec_get_cap_skip_frame_fill_param(const AVCodec *codec);
+ 
+ /**
+  * Check AVFrame for S12M timecode side data and allocate and fill TC SEI message with timecode info
+  *
+  * @param frame      Raw frame to get S12M timecode side data from
+diff --git a/media/ffvpx/libavcodec/itut35.h b/media/ffvpx/libavcodec/itut35.h
+new file mode 100644
+--- /dev/null
++++ b/media/ffvpx/libavcodec/itut35.h
+@@ -0,0 +1,30 @@
++/*
++ * 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
++ */
++
++#ifndef AVCODEC_ITUT35_H
++#define AVCODEC_ITUT35_H
++
++#define ITU_T_T35_COUNTRY_CODE_CN 0x26
++#define ITU_T_T35_COUNTRY_CODE_US 0xB5
++
++#define ITU_T_T35_PROVIDER_CODE_ATSC  0x31
++#define ITU_T_T35_PROVIDER_CODE_CUVA  0x04
++#define ITU_T_T35_PROVIDER_CODE_DOLBY 0x3B
++#define ITU_T_T35_PROVIDER_CODE_SMTPE 0x3C
++
++#endif /* AVCODEC_ITUT35_H */
+diff --git a/media/ffvpx/libavcodec/leb.h b/media/ffvpx/libavcodec/leb.h
+new file mode 100644
+--- /dev/null
++++ b/media/ffvpx/libavcodec/leb.h
+@@ -0,0 +1,70 @@
++/*
++ * 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
++ */
++
++/**
++ * @file
++ * leb128 handling implementations
++ */
++
++#ifndef AVCODEC_LEB_H
++#define AVCODEC_LEB_H
++
++#include "get_bits.h"
++
++/**
++ * Read a unsigned integer coded as a variable number of up to eight
++ * little-endian bytes, where the MSB in a byte signals another byte
++ * must be read.
++ * All coded bits are read, but values > UINT_MAX are truncated.
++ */
++static inline unsigned get_leb(GetBitContext *s) {
++    int more, i = 0;
++    unsigned leb = 0;
++
++    do {
++        int byte = get_bits(s, 8);
++        unsigned bits = byte & 0x7f;
++        more = byte & 0x80;
++        if (i <= 4)
++            leb |= bits << (i * 7);
++        if (++i == 8)
++            break;
++    } while (more);
++
++    return leb;
++}
++
++/**
++ * Read a unsigned integer coded as a variable number of up to eight
++ * little-endian bytes, where the MSB in a byte signals another byte
++ * must be read.
++ */
++static inline int64_t get_leb128(GetBitContext *gb) {
++    int64_t ret = 0;
++
++    for (int i = 0; i < 8; i++) {
++        int byte = get_bits(gb, 8);
++        ret |= (int64_t)(byte & 0x7f) << (i * 7);
++        if (!(byte & 0x80))
++            break;
++    }
++
++    return ret;
++}
++
++#endif /* AVCODEC_LEB_H */
+diff --git a/media/ffvpx/libavcodec/libaomenc.c b/media/ffvpx/libavcodec/libaomenc.c
+--- a/media/ffvpx/libavcodec/libaomenc.c
++++ b/media/ffvpx/libavcodec/libaomenc.c
+@@ -30,16 +30,17 @@
+ #include <aom/aomcx.h>
+ 
+ #include "libavutil/avassert.h"
+ #include "libavutil/base64.h"
+ #include "libavutil/common.h"
+ #include "libavutil/cpu.h"
+ #include "libavutil/imgutils.h"
+ #include "libavutil/mathematics.h"
++#include "libavutil/mem.h"
+ #include "libavutil/opt.h"
+ #include "libavutil/pixdesc.h"
+ 
+ #include "av1.h"
+ #include "avcodec.h"
+ #include "bsf.h"
+ #include "codec_internal.h"
+ #include "encode.h"
+@@ -1462,23 +1463,23 @@ static av_cold int av1_init(AVCodecConte
+ static const AVOption options[] = {
+     { "cpu-used",        "Quality/Speed ratio modifier",           OFFSET(cpu_used),        AV_OPT_TYPE_INT, {.i64 = 1}, 0, 8, VE},
+     { "auto-alt-ref",    "Enable use of alternate reference "
+                          "frames (2-pass only)",                   OFFSET(auto_alt_ref),    AV_OPT_TYPE_INT, {.i64 = -1},      -1,      2,       VE},
+     { "lag-in-frames",   "Number of frames to look ahead at for "
+                          "alternate reference frame selection",    OFFSET(lag_in_frames),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE},
+     { "arnr-max-frames", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE},
+     { "arnr-strength",   "altref noise reduction filter strength", OFFSET(arnr_strength),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      6,       VE},
+-    { "aq-mode",         "adaptive quantization mode",             OFFSET(aq_mode),         AV_OPT_TYPE_INT, {.i64 = -1},      -1,      4, VE, "aq_mode"},
+-    { "none",            "Aq not used",         0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, "aq_mode"},
+-    { "variance",        "Variance based Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "aq_mode"},
+-    { "complexity",      "Complexity based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "aq_mode"},
+-    { "cyclic",          "Cyclic Refresh Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "aq_mode"},
+-    { "error-resilience", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"},
+-    { "default",         "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"},
++    { "aq-mode",         "adaptive quantization mode",             OFFSET(aq_mode),         AV_OPT_TYPE_INT, {.i64 = -1},      -1,      4, VE, .unit = "aq_mode"},
++    { "none",            "Aq not used",         0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, .unit = "aq_mode"},
++    { "variance",        "Variance based Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, .unit = "aq_mode"},
++    { "complexity",      "Complexity based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, .unit = "aq_mode"},
++    { "cyclic",          "Cyclic Refresh Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, .unit = "aq_mode"},
++    { "error-resilience", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, .unit = "er"},
++    { "default",         "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, .unit = "er"},
+     { "crf",              "Select the quality for constant quality mode", offsetof(AOMContext, crf), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, VE },
+     { "static-thresh",    "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
+     { "drop-threshold",   "Frame drop threshold", offsetof(AOMContext, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE },
+     { "denoise-noise-level", "Amount of noise to be removed", OFFSET(denoise_noise_level), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
+     { "denoise-block-size", "Denoise block size ", OFFSET(denoise_block_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
+     { "undershoot-pct",   "Datarate undershoot (min) target (%)", OFFSET(rc_undershoot_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
+     { "overshoot-pct",    "Datarate overshoot (max) target (%)", OFFSET(rc_overshoot_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1000, VE},
+     { "minsection-pct",   "GOP min bitrate (% of target)", OFFSET(minsection_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
+@@ -1487,23 +1488,23 @@ static const AVOption options[] = {
+     { "tiles",            "Tile columns x rows", OFFSET(tile_cols), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, VE },
+     { "tile-columns",     "Log2 of number of tile columns to use", OFFSET(tile_cols_log2), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
+     { "tile-rows",        "Log2 of number of tile rows to use",    OFFSET(tile_rows_log2), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
+     { "row-mt",           "Enable row based multi-threading",      OFFSET(row_mt),         AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-cdef",      "Enable CDEF filtering",                 OFFSET(enable_cdef),    AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-global-motion",  "Enable global motion",             OFFSET(enable_global_motion), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-intrabc",  "Enable intra block copy prediction mode", OFFSET(enable_intrabc), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-restoration", "Enable Loop Restoration filtering", OFFSET(enable_restoration), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+-    { "usage",           "Quality and compression efficiency vs speed trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, "usage"},
+-    { "good",            "Good quality",      0, AV_OPT_TYPE_CONST, {.i64 = 0 /* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, "usage"},
+-    { "realtime",        "Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 1 /* AOM_USAGE_REALTIME */},     0, 0, VE, "usage"},
+-    { "allintra",        "All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 2 /* AOM_USAGE_ALL_INTRA */},    0, 0, VE, "usage"},
+-    { "tune",            "The metric that the encoder tunes for. Automatically chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, "tune"},
+-    { "psnr",            NULL,         0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_PSNR}, 0, 0, VE, "tune"},
+-    { "ssim",            NULL,         0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_SSIM}, 0, 0, VE, "tune"},
++    { "usage",           "Quality and compression efficiency vs speed trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, .unit = "usage"},
++    { "good",            "Good quality",      0, AV_OPT_TYPE_CONST, {.i64 = 0 /* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, .unit = "usage"},
++    { "realtime",        "Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 1 /* AOM_USAGE_REALTIME */},     0, 0, VE, .unit = "usage"},
++    { "allintra",        "All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 2 /* AOM_USAGE_ALL_INTRA */},    0, 0, VE, .unit = "usage"},
++    { "tune",            "The metric that the encoder tunes for. Automatically chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, .unit = "tune"},
++    { "psnr",            NULL,         0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_PSNR}, 0, 0, VE, .unit = "tune"},
++    { "ssim",            NULL,         0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_SSIM}, 0, 0, VE, .unit = "tune"},
+     FF_AV1_PROFILE_OPTS
+     { "still-picture", "Encode in single frame mode (typically used for still AVIF images).", OFFSET(still_picture), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, VE },
+     { "enable-rect-partitions", "Enable rectangular partitions", OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-1to4-partitions", "Enable 1:4/4:1 partitions",     OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-ab-partitions",   "Enable ab shape partitions",    OFFSET(enable_ab_partitions),   AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-angle-delta",       "Enable angle delta intra prediction",                OFFSET(enable_angle_delta),       AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-cfl-intra",         "Enable chroma predicted from luma intra prediction", OFFSET(enable_cfl_intra),         AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+     { "enable-filter-intra",      "Enable filter intra predictor",                      OFFSET(enable_filter_intra),      AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+diff --git a/media/ffvpx/libavcodec/libdav1d.c b/media/ffvpx/libavcodec/libdav1d.c
+--- a/media/ffvpx/libavcodec/libdav1d.c
++++ b/media/ffvpx/libavcodec/libdav1d.c
+@@ -30,25 +30,28 @@
+ #include "libavutil/opt.h"
+ 
+ #include "atsc_a53.h"
+ #include "av1_parse.h"
+ #include "avcodec.h"
+ #include "bytestream.h"
+ #include "codec_internal.h"
+ #include "decode.h"
++#include "dovi_rpu.h"
+ #include "internal.h"
++#include "itut35.h"
+ 
+ #define FF_DAV1D_VERSION_AT_LEAST(x,y) \
+     (DAV1D_API_VERSION_MAJOR > (x) || DAV1D_API_VERSION_MAJOR == (x) && DAV1D_API_VERSION_MINOR >= (y))
+ 
+ typedef struct Libdav1dContext {
+     AVClass *class;
+     Dav1dContext *c;
+     AVBufferPool *pool;
++    DOVIContext dovi;
+     int pool_size;
+ 
+     Dav1dData data;
+     int tile_threads;
+     int frame_threads;
+     int max_frame_delay;
+     int apply_grain;
+     int operating_point;
+@@ -208,19 +211,20 @@ static av_cold int libdav1d_init(AVCodec
+ {
+     Libdav1dContext *dav1d = c->priv_data;
+     Dav1dSettings s;
+ #if FF_DAV1D_VERSION_AT_LEAST(6,0)
+     int threads = c->thread_count;
+ #else
+     int threads = (c->thread_count ? c->thread_count : av_cpu_count()) * 3 / 2;
+ #endif
++    const AVPacketSideData *sd;
+     int res;
+ 
+-    av_log(c, AV_LOG_INFO, "libdav1d %s\n", dav1d_version());
++    av_log(c, AV_LOG_VERBOSE, "libdav1d %s\n", dav1d_version());
+ 
+     dav1d_default_settings(&s);
+     s.logger.cookie = c;
+     s.logger.callback = libdav1d_log_callback;
+     s.allocator.cookie = dav1d;
+     s.allocator.alloc_picture_callback = libdav1d_picture_allocator;
+     s.allocator.release_picture_callback = libdav1d_picture_release;
+     s.frame_size_limit = c->max_pixels;
+@@ -280,44 +284,41 @@ static av_cold int libdav1d_init(AVCodec
+     res = dav1d_get_frame_delay(&s);
+     if (res < 0) // Should not happen
+         return AVERROR_EXTERNAL;
+ 
+     // When dav1d_get_frame_delay() returns 1, there's no delay whatsoever
+     c->delay = res > 1 ? res : 0;
+ #endif
+ 
++    dav1d->dovi.logctx = c;
++    dav1d->dovi.dv_profile = 10; // default for AV1
++    sd = ff_get_coded_side_data(c, AV_PKT_DATA_DOVI_CONF);
++    if (sd && sd->size > 0)
++        ff_dovi_update_cfg(&dav1d->dovi, (AVDOVIDecoderConfigurationRecord *) sd->data);
+     return 0;
+ }
+ 
+ static void libdav1d_flush(AVCodecContext *c)
+ {
+     Libdav1dContext *dav1d = c->priv_data;
+ 
+     dav1d_data_unref(&dav1d->data);
+     dav1d_flush(dav1d->c);
+ }
+ 
+-typedef struct OpaqueData {
+-    void    *pkt_orig_opaque;
+-#if FF_API_REORDERED_OPAQUE
+-    int64_t  reordered_opaque;
+-#endif
+-} OpaqueData;
+-
+ static void libdav1d_data_free(const uint8_t *data, void *opaque) {
+     AVBufferRef *buf = opaque;
+ 
+     av_buffer_unref(&buf);
+ }
+ 
+ static void libdav1d_user_data_free(const uint8_t *data, void *opaque) {
+     AVPacket *pkt = opaque;
+     av_assert0(data == opaque);
+-    av_free(pkt->opaque);
+     av_packet_free(&pkt);
+ }
+ 
+ static int libdav1d_receive_frame_internal(AVCodecContext *c, Dav1dPicture *p)
+ {
+     Libdav1dContext *dav1d = c->priv_data;
+     Dav1dData *data = &dav1d->data;
+     int res;
+@@ -330,51 +331,28 @@ static int libdav1d_receive_frame_intern
+ 
+         res = ff_decode_get_packet(c, pkt);
+         if (res < 0 && res != AVERROR_EOF) {
+             av_packet_free(&pkt);
+             return res;
+         }
+ 
+         if (pkt->size) {
+-            OpaqueData *od = NULL;
+-
+             res = dav1d_data_wrap(data, pkt->data, pkt->size,
+                                   libdav1d_data_free, pkt->buf);
+             if (res < 0) {
+                 av_packet_free(&pkt);
+                 return res;
+             }
+ 
+             pkt->buf = NULL;
+ 
+-FF_DISABLE_DEPRECATION_WARNINGS
+-            if (
+-#if FF_API_REORDERED_OPAQUE
+-                c->reordered_opaque != AV_NOPTS_VALUE ||
+-#endif
+-                (pkt->opaque && (c->flags & AV_CODEC_FLAG_COPY_OPAQUE))) {
+-                od = av_mallocz(sizeof(*od));
+-                if (!od) {
+-                    av_packet_free(&pkt);
+-                    dav1d_data_unref(data);
+-                    return AVERROR(ENOMEM);
+-                }
+-                od->pkt_orig_opaque  = pkt->opaque;
+-#if FF_API_REORDERED_OPAQUE
+-                od->reordered_opaque = c->reordered_opaque;
+-#endif
+-FF_ENABLE_DEPRECATION_WARNINGS
+-            }
+-            pkt->opaque = od;
+-
+             res = dav1d_data_wrap_user_data(data, (const uint8_t *)pkt,
+                                             libdav1d_user_data_free, pkt);
+             if (res < 0) {
+-                av_free(pkt->opaque);
+                 av_packet_free(&pkt);
+                 dav1d_data_unref(data);
+                 return res;
+             }
+             pkt = NULL;
+         } else {
+             av_packet_free(&pkt);
+             if (res >= 0)
+@@ -403,17 +381,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
+     return res;
+ }
+ 
+ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
+ {
+     Libdav1dContext *dav1d = c->priv_data;
+     Dav1dPicture pic = { 0 }, *p = &pic;
+     AVPacket *pkt;
+-    OpaqueData *od = NULL;
+ #if FF_DAV1D_VERSION_AT_LEAST(5,1)
+     enum Dav1dEventFlags event_flags = 0;
+ #endif
+     int res;
+ 
+     do {
+         res = libdav1d_receive_frame_internal(c, p);
+     } while (res > 0);
+@@ -458,34 +435,19 @@ static int libdav1d_receive_frame(AVCode
+     av_reduce(&frame->sample_aspect_ratio.num,
+               &frame->sample_aspect_ratio.den,
+               frame->height * (int64_t)p->frame_hdr->render_width,
+               frame->width  * (int64_t)p->frame_hdr->render_height,
+               INT_MAX);
+     ff_set_sar(c, frame->sample_aspect_ratio);
+ 
+     pkt = (AVPacket *)p->m.user_data.data;
+-    od  = pkt->opaque;
+-#if FF_API_REORDERED_OPAQUE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    if (od && od->reordered_opaque != AV_NOPTS_VALUE)
+-        frame->reordered_opaque = od->reordered_opaque;
+-    else
+-        frame->reordered_opaque = AV_NOPTS_VALUE;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+-    // restore the original user opaque value for
+-    // ff_decode_frame_props_from_pkt()
+-    pkt->opaque = od ? od->pkt_orig_opaque : NULL;
+-    av_freep(&od);
+ 
+     // match timestamps and packet size
+     res = ff_decode_frame_props_from_pkt(c, frame, pkt);
+-    pkt->opaque = NULL;
+     if (res < 0)
+         goto fail;
+ 
+     frame->pkt_dts = pkt->pts;
+     if (p->frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY)
+         frame->flags |= AV_FRAME_FLAG_KEY;
+     else
+         frame->flags &= ~AV_FRAME_FLAG_KEY;
+@@ -502,119 +464,153 @@ FF_ENABLE_DEPRECATION_WARNINGS
+         frame->pict_type = AV_PICTURE_TYPE_SP;
+         break;
+     default:
+         res = AVERROR_INVALIDDATA;
+         goto fail;
+     }
+ 
+     if (p->mastering_display) {
+-        AVMasteringDisplayMetadata *mastering = av_mastering_display_metadata_create_side_data(frame);
+-        if (!mastering) {
+-            res = AVERROR(ENOMEM);
++        AVMasteringDisplayMetadata *mastering;
++
++        res = ff_decode_mastering_display_new(c, frame, &mastering);
++        if (res < 0)
+             goto fail;
+-        }
+ 
+-        for (int i = 0; i < 3; i++) {
+-            mastering->display_primaries[i][0] = av_make_q(p->mastering_display->primaries[i][0], 1 << 16);
+-            mastering->display_primaries[i][1] = av_make_q(p->mastering_display->primaries[i][1], 1 << 16);
++        if (mastering) {
++            for (int i = 0; i < 3; i++) {
++                mastering->display_primaries[i][0] = av_make_q(p->mastering_display->primaries[i][0], 1 << 16);
++                mastering->display_primaries[i][1] = av_make_q(p->mastering_display->primaries[i][1], 1 << 16);
++            }
++            mastering->white_point[0] = av_make_q(p->mastering_display->white_point[0], 1 << 16);
++            mastering->white_point[1] = av_make_q(p->mastering_display->white_point[1], 1 << 16);
++
++            mastering->max_luminance = av_make_q(p->mastering_display->max_luminance, 1 << 8);
++            mastering->min_luminance = av_make_q(p->mastering_display->min_luminance, 1 << 14);
++
++            mastering->has_primaries = 1;
++            mastering->has_luminance = 1;
+         }
+-        mastering->white_point[0] = av_make_q(p->mastering_display->white_point[0], 1 << 16);
+-        mastering->white_point[1] = av_make_q(p->mastering_display->white_point[1], 1 << 16);
+-
+-        mastering->max_luminance = av_make_q(p->mastering_display->max_luminance, 1 << 8);
+-        mastering->min_luminance = av_make_q(p->mastering_display->min_luminance, 1 << 14);
+-
+-        mastering->has_primaries = 1;
+-        mastering->has_luminance = 1;
+     }
+     if (p->content_light) {
+-        AVContentLightMetadata *light = av_content_light_metadata_create_side_data(frame);
+-        if (!light) {
+-            res = AVERROR(ENOMEM);
++        AVContentLightMetadata *light;
++
++        res = ff_decode_content_light_new(c, frame, &light);
++        if (res < 0)
+             goto fail;
++
++        if (light) {
++            light->MaxCLL = p->content_light->max_content_light_level;
++            light->MaxFALL = p->content_light->max_frame_average_light_level;
+         }
+-        light->MaxCLL = p->content_light->max_content_light_level;
+-        light->MaxFALL = p->content_light->max_frame_average_light_level;
+     }
+     if (p->itut_t35) {
+ #if FF_DAV1D_VERSION_AT_LEAST(6,9)
+         for (size_t i = 0; i < p->n_itut_t35; i++) {
+             const Dav1dITUTT35 *itut_t35 = &p->itut_t35[i];
+ #else
+         const Dav1dITUTT35 *itut_t35 = p->itut_t35;
+ #endif
+         GetByteContext gb;
+         int provider_code;
+ 
+         bytestream2_init(&gb, itut_t35->payload, itut_t35->payload_size);
+ 
+         provider_code = bytestream2_get_be16(&gb);
+         switch (provider_code) {
+-        case 0x31: { // atsc_provider_code
++        case ITU_T_T35_PROVIDER_CODE_ATSC: {
+             uint32_t user_identifier = bytestream2_get_be32(&gb);
+             switch (user_identifier) {
+             case MKBETAG('G', 'A', '9', '4'): { // closed captions
+                 AVBufferRef *buf = NULL;
+ 
+                 res = ff_parse_a53_cc(&buf, gb.buffer, bytestream2_get_bytes_left(&gb));
+                 if (res < 0)
+                     goto fail;
+                 if (!res)
+                     break;
+ 
+-                if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_A53_CC, buf))
+-                    av_buffer_unref(&buf);
++                res = ff_frame_new_side_data_from_buf(c, frame, AV_FRAME_DATA_A53_CC, &buf, NULL);
++                if (res < 0)
++                    goto fail;
+ 
+                 c->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+                 break;
+             }
+             default: // ignore unsupported identifiers
+                 break;
+             }
+             break;
+         }
+-        case 0x3C: { // smpte_provider_code
++        case ITU_T_T35_PROVIDER_CODE_SMTPE: {
+             AVDynamicHDRPlus *hdrplus;
+             int provider_oriented_code = bytestream2_get_be16(&gb);
+             int application_identifier = bytestream2_get_byte(&gb);
+ 
+-            if (itut_t35->country_code != 0xB5 ||
++            if (itut_t35->country_code != ITU_T_T35_COUNTRY_CODE_US ||
+                 provider_oriented_code != 1 || application_identifier != 4)
+                 break;
+ 
+             hdrplus = av_dynamic_hdr_plus_create_side_data(frame);
+             if (!hdrplus) {
+                 res = AVERROR(ENOMEM);
+                 goto fail;
+             }
+ 
+             res = av_dynamic_hdr_plus_from_t35(hdrplus, gb.buffer,
+                                                bytestream2_get_bytes_left(&gb));
+             if (res < 0)
+                 goto fail;
+             break;
+         }
++        case ITU_T_T35_PROVIDER_CODE_DOLBY: {
++            int provider_oriented_code = bytestream2_get_be32(&gb);
++            if (itut_t35->country_code != ITU_T_T35_COUNTRY_CODE_US ||
++                provider_oriented_code != 0x800)
++                break;
++
++            res = ff_dovi_rpu_parse(&dav1d->dovi, gb.buffer, gb.buffer_end - gb.buffer,
++                                    c->err_recognition);
++            if (res < 0) {
++                av_log(c, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");
++                break; // ignore
++            }
++
++            res = ff_dovi_attach_side_data(&dav1d->dovi, frame);
++            if (res < 0)
++                goto fail;
++            break;
++        }
+         default: // ignore unsupported provider codes
+             break;
+         }
+ #if FF_DAV1D_VERSION_AT_LEAST(6,9)
+         }
+ #endif
+     }
+     if (p->frame_hdr->film_grain.present && (!dav1d->apply_grain ||
+         (c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN))) {
+         AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame);
++        const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(frame->format);
++        av_assert0(pixdesc);
+         if (!fgp) {
+             res = AVERROR(ENOMEM);
+             goto fail;
+         }
+ 
+         fgp->type = AV_FILM_GRAIN_PARAMS_AV1;
+         fgp->seed = p->frame_hdr->film_grain.data.seed;
++        fgp->width = frame->width;
++        fgp->height = frame->height;
++        fgp->color_range = frame->color_range;
++        fgp->color_primaries = frame->color_primaries;
++        fgp->color_trc = frame->color_trc;
++        fgp->color_space = frame->colorspace;
++        fgp->subsampling_x = pixdesc->log2_chroma_w;
++        fgp->subsampling_y = pixdesc->log2_chroma_h;
+         fgp->codec.aom.num_y_points = p->frame_hdr->film_grain.data.num_y_points;
+         fgp->codec.aom.chroma_scaling_from_luma = p->frame_hdr->film_grain.data.chroma_scaling_from_luma;
+         fgp->codec.aom.scaling_shift = p->frame_hdr->film_grain.data.scaling_shift;
+         fgp->codec.aom.ar_coeff_lag = p->frame_hdr->film_grain.data.ar_coeff_lag;
+         fgp->codec.aom.ar_coeff_shift = p->frame_hdr->film_grain.data.ar_coeff_shift;
+         fgp->codec.aom.grain_scale_shift = p->frame_hdr->film_grain.data.grain_scale_shift;
+         fgp->codec.aom.overlap_flag = p->frame_hdr->film_grain.data.overlap_flag;
+         fgp->codec.aom.limit_output_range = p->frame_hdr->film_grain.data.clip_to_restricted_range;
+@@ -647,16 +643,17 @@ fail:
+     return res;
+ }
+ 
+ static av_cold int libdav1d_close(AVCodecContext *c)
+ {
+     Libdav1dContext *dav1d = c->priv_data;
+ 
+     av_buffer_pool_uninit(&dav1d->pool);
++    ff_dovi_ctx_unref(&dav1d->dovi);
+     dav1d_data_unref(&dav1d->data);
+     dav1d_close(&dav1d->c);
+ 
+     return 0;
+ }
+ 
+ #ifndef DAV1D_MAX_FRAME_THREADS
+ #define DAV1D_MAX_FRAME_THREADS DAV1D_MAX_THREADS
+diff --git a/media/ffvpx/libavcodec/libopusenc.c b/media/ffvpx/libavcodec/libopusenc.c
+--- a/media/ffvpx/libavcodec/libopusenc.c
++++ b/media/ffvpx/libavcodec/libopusenc.c
+@@ -18,16 +18,17 @@
+  * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #include <opus.h>
+ #include <opus_multistream.h>
+ 
+ #include "libavutil/channel_layout.h"
++#include "libavutil/mem.h"
+ #include "libavutil/opt.h"
+ #include "avcodec.h"
+ #include "bytestream.h"
+ #include "codec_internal.h"
+ #include "encode.h"
+ #include "libopus.h"
+ #include "audio_frame_queue.h"
+ #include "vorbis_data.h"
+@@ -547,28 +548,28 @@ static av_cold int libopus_encode_close(
+     av_freep(&opus->samples);
+ 
+     return 0;
+ }
+ 
+ #define OFFSET(x) offsetof(LibopusEncContext, opts.x)
+ #define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+ static const AVOption libopus_options[] = {
+-    { "application",    "Intended application type",           OFFSET(application),    AV_OPT_TYPE_INT,   { .i64 = OPUS_APPLICATION_AUDIO }, OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY, FLAGS, "application" },
+-        { "voip",           "Favor improved speech intelligibility",   0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_VOIP },                0, 0, FLAGS, "application" },
+-        { "audio",          "Favor faithfulness to the input",         0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO },               0, 0, FLAGS, "application" },
+-        { "lowdelay",       "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" },
++    { "application",    "Intended application type",           OFFSET(application),    AV_OPT_TYPE_INT,   { .i64 = OPUS_APPLICATION_AUDIO }, OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY, FLAGS, .unit = "application" },
++        { "voip",           "Favor improved speech intelligibility",   0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_VOIP },                0, 0, FLAGS, .unit = "application" },
++        { "audio",          "Favor faithfulness to the input",         0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO },               0, 0, FLAGS, .unit = "application" },
++        { "lowdelay",       "Restrict to only the lowest delay modes, disable voice-optimized modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, .unit = "application" },
+     { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 120.0, FLAGS },
+     { "packet_loss",    "Expected packet loss percentage",     OFFSET(packet_loss),    AV_OPT_TYPE_INT,   { .i64 = 0 },    0,   100,  FLAGS },
+     { "fec",             "Enable inband FEC. Expected packet loss must be non-zero",     OFFSET(fec),    AV_OPT_TYPE_BOOL,   { .i64 = 0 }, 0, 1, FLAGS },
+-    { "vbr",            "Variable bit rate mode",              OFFSET(vbr),            AV_OPT_TYPE_INT,   { .i64 = 1 },    0,   2,    FLAGS, "vbr" },
+-        { "off",            "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" },
+-        { "on",             "Use variable bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "vbr" },
+-        { "constrained",    "Use constrained VBR",   0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, "vbr" },
+-    { "mapping_family", "Channel Mapping Family",              OFFSET(mapping_family), AV_OPT_TYPE_INT,   { .i64 = -1 },   -1,  255,  FLAGS, "mapping_family" },
++    { "vbr",            "Variable bit rate mode",              OFFSET(vbr),            AV_OPT_TYPE_INT,   { .i64 = 1 },    0,   2,    FLAGS, .unit = "vbr" },
++        { "off",            "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, .unit = "vbr" },
++        { "on",             "Use variable bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, .unit = "vbr" },
++        { "constrained",    "Use constrained VBR",   0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, .unit = "vbr" },
++    { "mapping_family", "Channel Mapping Family",              OFFSET(mapping_family), AV_OPT_TYPE_INT,   { .i64 = -1 },   -1,  255,  FLAGS, .unit = "mapping_family" },
+     { "dtx", "Enable DTX", OFFSET(dtx), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
+ #ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST
+     { "apply_phase_inv", "Apply intensity stereo phase inversion", OFFSET(apply_phase_inv), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
+ #endif
+     { NULL },
+ };
+ 
+ static const AVClass libopus_class = {
+diff --git a/media/ffvpx/libavcodec/libvorbisenc.c b/media/ffvpx/libavcodec/libvorbisenc.c
+--- a/media/ffvpx/libavcodec/libvorbisenc.c
++++ b/media/ffvpx/libavcodec/libvorbisenc.c
+@@ -18,16 +18,17 @@
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #include <vorbis/vorbisenc.h>
+ 
+ #include "libavutil/avassert.h"
+ #include "libavutil/channel_layout.h"
+ #include "libavutil/fifo.h"
++#include "libavutil/mem.h"
+ #include "libavutil/opt.h"
+ #include "avcodec.h"
+ #include "audio_frame_queue.h"
+ #include "codec_internal.h"
+ #include "encode.h"
+ #include "version.h"
+ #include "vorbis_parser.h"
+ 
+diff --git a/media/ffvpx/libavcodec/libvpxenc.c b/media/ffvpx/libavcodec/libvpxenc.c
+--- a/media/ffvpx/libavcodec/libvpxenc.c
++++ b/media/ffvpx/libavcodec/libvpxenc.c
+@@ -28,32 +28,35 @@
+ #define VPX_DISABLE_CTRL_TYPECHECKS 1
+ #define VPX_CODEC_DISABLE_COMPAT    1
+ #include <vpx/vpx_encoder.h>
+ #include <vpx/vp8cx.h>
+ 
+ #include "avcodec.h"
+ #include "codec_internal.h"
+ #include "encode.h"
+-#include "internal.h"
+ #include "libavutil/avassert.h"
++#include "libavutil/mem.h"
+ #include "libvpx.h"
+ #include "packet_internal.h"
+ #include "profiles.h"
+ #include "libavutil/avstring.h"
+ #include "libavutil/base64.h"
+ #include "libavutil/common.h"
+ #include "libavutil/cpu.h"
+ #include "libavutil/fifo.h"
+ #include "libavutil/internal.h"
+ #include "libavutil/intreadwrite.h"
+ #include "libavutil/mathematics.h"
+ #include "libavutil/opt.h"
+ #include "libavutil/pixdesc.h"
+ 
++#define IS_VP9(avctx) (CONFIG_LIBVPX_VP9_ENCODER && avctx->codec_id == AV_CODEC_ID_VP9)
++#define IS_VP8(avctx) (CONFIG_LIBVPX_VP8_ENCODER && avctx->codec_id == AV_CODEC_ID_VP8)
++
+ /**
+  * Portion of struct vpx_codec_cx_pkt from vpx_encoder.h.
+  * One encoded frame returned from the library.
+  */
+ struct FrameListData {
+     void *buf;                       /**< compressed data buffer */
+     size_t sz;                       /**< length of compressed data */
+     int64_t pts;                     /**< time stamp to show frame
+@@ -63,19 +66,16 @@ struct FrameListData {
+     int have_sse;                    /**< true if we have pending sse[] */
+     struct FrameListData *next;
+ };
+ 
+ typedef struct FrameData {
+     int64_t pts;
+     int64_t duration;
+ 
+-#if FF_API_REORDERED_OPAQUE
+-    int64_t      reordered_opaque;
+-#endif
+     void        *frame_opaque;
+     AVBufferRef *frame_opaque_ref;
+ 
+     AVBufferRef *hdr10_plus;
+ } FrameData;
+ 
+ typedef struct VPxEncoderContext {
+     AVClass *class;
+@@ -116,16 +116,19 @@ typedef struct VPxEncoderContext {
+     int max_intra_rate;
+     int rc_undershoot_pct;
+     int rc_overshoot_pct;
+ 
+     AVDictionary *vpx_ts_parameters;
+     int *ts_layer_flags;
+     int current_temporal_idx;
+ 
++    // VP8-only
++    int screen_content_mode;
++
+     // VP9-only
+     int lossless;
+     int tile_columns;
+     int tile_rows;
+     int frame_parallel;
+     int aq_mode;
+     int drop_threshold;
+     int noise_sensitivity;
+@@ -159,16 +162,17 @@ static const char *const ctlidstr[] = {
+     [VP8E_SET_ARNR_MAXFRAMES]    = "VP8E_SET_ARNR_MAXFRAMES",
+     [VP8E_SET_ARNR_STRENGTH]     = "VP8E_SET_ARNR_STRENGTH",
+     [VP8E_SET_ARNR_TYPE]         = "VP8E_SET_ARNR_TYPE",
+     [VP8E_SET_TUNING]            = "VP8E_SET_TUNING",
+     [VP8E_SET_CQ_LEVEL]          = "VP8E_SET_CQ_LEVEL",
+     [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT",
+     [VP8E_SET_SHARPNESS]               = "VP8E_SET_SHARPNESS",
+     [VP8E_SET_TEMPORAL_LAYER_ID]       = "VP8E_SET_TEMPORAL_LAYER_ID",
++    [VP8E_SET_SCREEN_CONTENT_MODE]     = "VP8E_SET_SCREEN_CONTENT_MODE",
+ #if CONFIG_LIBVPX_VP9_ENCODER
+     [VP9E_SET_LOSSLESS]                = "VP9E_SET_LOSSLESS",
+     [VP9E_SET_TILE_COLUMNS]            = "VP9E_SET_TILE_COLUMNS",
+     [VP9E_SET_TILE_ROWS]               = "VP9E_SET_TILE_ROWS",
+     [VP9E_SET_FRAME_PARALLEL_DECODING] = "VP9E_SET_FRAME_PARALLEL_DECODING",
+     [VP9E_SET_AQ_MODE]                 = "VP9E_SET_AQ_MODE",
+     [VP9E_SET_COLOR_SPACE]             = "VP9E_SET_COLOR_SPACE",
+     [VP9E_SET_SVC_LAYER_ID]            = "VP9E_SET_SVC_LAYER_ID",
+@@ -351,44 +355,38 @@ static av_cold void fifo_free(AVFifo **f
+ 
+ static int frame_data_submit(AVCodecContext *avctx, AVFifo *fifo,
+                              const AVFrame *frame)
+ {
+     VPxContext *ctx = avctx->priv_data;
+     const struct vpx_codec_enc_cfg *enccfg = ctx->encoder.config.enc;
+ 
+     FrameData fd = { .pts = frame->pts };
+-
+-    AVFrameSideData *av_uninit(sd);
+     int ret;
+ 
+-#if CONFIG_LIBVPX_VP9_ENCODER
+-    // Keep HDR10+ if it has bit depth higher than 8 and
+-    // it has PQ trc (SMPTE2084).
+-    sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS);
+-    if (avctx->codec_id == AV_CODEC_ID_VP9 && sd &&
++    if (IS_VP9(avctx) &&
++        // Keep HDR10+ if it has bit depth higher than 8 and
++        // it has PQ trc (SMPTE2084).
+         enccfg->g_bit_depth > 8 && avctx->color_trc == AVCOL_TRC_SMPTE2084) {
+-        fd.hdr10_plus = av_buffer_ref(sd->buf);
+-        if (!fd.hdr10_plus)
+-            return AVERROR(ENOMEM);
++        const AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS);
++
++        if (sd) {
++            fd.hdr10_plus = av_buffer_ref(sd->buf);
++            if (!fd.hdr10_plus)
++                return AVERROR(ENOMEM);
++        }
+     }
+-#endif
+ 
+     fd.duration     = frame->duration;
+     fd.frame_opaque = frame->opaque;
+     if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE && frame->opaque_ref) {
+         ret = av_buffer_replace(&fd.frame_opaque_ref, frame->opaque_ref);
+         if (ret < 0)
+             goto fail;
+     }
+-#if FF_API_REORDERED_OPAQUE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    fd.reordered_opaque = frame->reordered_opaque;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+ 
+     ret = av_fifo_write(fifo, &fd, 1);
+     if (ret < 0)
+         goto fail;
+ 
+     return 0;
+ fail:
+     frame_data_uninit(&fd);
+@@ -405,22 +403,16 @@ static int frame_data_apply(AVCodecConte
+         return 0;
+     if (fd.pts != pkt->pts) {
+         av_log(avctx, AV_LOG_WARNING,
+                "Mismatching timestamps: libvpx %"PRId64" queued %"PRId64"; "
+                "this is a bug, please report it\n", pkt->pts, fd.pts);
+         goto skip;
+     }
+ 
+-#if FF_API_REORDERED_OPAQUE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    avctx->reordered_opaque = fd.reordered_opaque;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+     pkt->duration = fd.duration;
+     if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
+         pkt->opaque         = fd.frame_opaque;
+         pkt->opaque_ref     = fd.frame_opaque_ref;
+         fd.frame_opaque_ref = NULL;
+     }
+ 
+     if (fd.hdr10_plus) {
+@@ -789,17 +781,17 @@ static int vpx_parse_ref_frame_config(vp
+ }
+ #endif
+ 
+ #if CONFIG_LIBVPX_VP9_ENCODER
+ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps,
+                        struct vpx_codec_enc_cfg *enccfg, vpx_codec_flags_t *flags,
+                        vpx_img_fmt_t *img_fmt)
+ {
+-    VPxContext av_unused *ctx = avctx->priv_data;
++    VPxContext *ctx = avctx->priv_data;
+     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+     enccfg->g_bit_depth = enccfg->g_input_bit_depth = desc->comp[0].depth;
+     switch (avctx->pix_fmt) {
+     case AV_PIX_FMT_YUV420P:
+     case AV_PIX_FMT_YUVA420P:
+         enccfg->g_profile = 0;
+         *img_fmt = VPX_IMG_FMT_I420;
+         return 0;
+@@ -1257,16 +1249,24 @@ static av_cold int vpx_init(AVCodecConte
+             codecctl_int(avctx, VP9E_SET_TPL, ctx->tpl_model);
+ #endif
+ #ifdef VPX_CTRL_VP9E_SET_MIN_GF_INTERVAL
+         if (ctx->min_gf_interval >= 0)
+             codecctl_int(avctx, VP9E_SET_MIN_GF_INTERVAL, ctx->min_gf_interval);
+ #endif
+     }
+ #endif
++    if (avctx->codec_id == AV_CODEC_ID_VP8 && ctx->screen_content_mode >= 0) {
++        if (ctx->screen_content_mode == 2 && ctx->is_alpha) {
++            av_log(avctx, AV_LOG_ERROR,
++                   "Transparency encoding with screen mode with aggressive rate control not supported\n");
++            return AVERROR(EINVAL);
++        }
++        codecctl_int(avctx, VP8E_SET_SCREEN_CONTENT_MODE, ctx->screen_content_mode);
++    }
+ 
+     av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline);
+ 
+     //provide dummy value to initialize wrapper, values will be updated each _encode()
+     vpx_img_wrap(&ctx->rawimg, img_fmt, avctx->width, avctx->height, 1,
+                  (unsigned char*)1);
+ #if CONFIG_LIBVPX_VP9_ENCODER
+     if (avctx->codec_id == AV_CODEC_ID_VP9 && (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH))
+@@ -1897,101 +1897,102 @@ FF_ENABLE_DEPRECATION_WARNINGS
+ #define OFFSET(x) offsetof(VPxContext, x)
+ #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+ 
+ #define COMMON_OPTIONS \
+     { "lag-in-frames",   "Number of frames to look ahead for " \
+                          "alternate reference frame selection",    OFFSET(lag_in_frames),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE}, \
+     { "arnr-maxframes",  "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE}, \
+     { "arnr-strength",   "altref noise reduction filter strength", OFFSET(arnr_strength),   AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE}, \
+-    { "arnr-type",       "altref noise reduction filter type",     OFFSET(arnr_type),       AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE, "arnr_type"}, \
+-    { "backward",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "arnr_type" }, \
+-    { "forward",         NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "arnr_type" }, \
+-    { "centered",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "arnr_type" }, \
+-    { "tune",            "Tune the encoding to a specific scenario", OFFSET(tune),          AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE, "tune"}, \
+-    { "psnr",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VP8_TUNE_PSNR}, 0, 0, VE, "tune"}, \
+-    { "ssim",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VP8_TUNE_SSIM}, 0, 0, VE, "tune"}, \
+-    { "deadline",        "Time to spend encoding, in microseconds.", OFFSET(deadline),      AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, \
+-    { "best",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_BEST_QUALITY}, 0, 0, VE, "quality"}, \
+-    { "good",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"}, \
+-    { "realtime",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME},     0, 0, VE, "quality"}, \
+-    { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"}, \
++    { "arnr-type",       "altref noise reduction filter type",     OFFSET(arnr_type),       AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE, .unit = "arnr_type"}, \
++    { "backward",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, .unit = "arnr_type" }, \
++    { "forward",         NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, .unit = "arnr_type" }, \
++    { "centered",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, .unit = "arnr_type" }, \
++    { "tune",            "Tune the encoding to a specific scenario", OFFSET(tune),          AV_OPT_TYPE_INT, {.i64 = -1},      -1,      INT_MAX, VE, .unit = "tune"}, \
++    { "psnr",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VP8_TUNE_PSNR}, 0, 0, VE, .unit = "tune"}, \
++    { "ssim",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VP8_TUNE_SSIM}, 0, 0, VE, .unit = "tune"}, \
++    { "deadline",        "Time to spend encoding, in microseconds.", OFFSET(deadline),      AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, .unit = "quality"}, \
++    { "best",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_BEST_QUALITY}, 0, 0, VE, .unit = "quality"}, \
++    { "good",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, .unit = "quality"}, \
++    { "realtime",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME},     0, 0, VE, .unit = "quality"}, \
++    { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, .unit = "er"}, \
+     { "max-intra-rate",  "Maximum I-frame bitrate (pct) 0=unlimited",  OFFSET(max_intra_rate),  AV_OPT_TYPE_INT,  {.i64 = -1}, -1,      INT_MAX, VE}, \
+-    { "default",         "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"}, \
++    { "default",         "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, .unit = "er"}, \
+     { "partitions",      "The frame partitions are independently decodable " \
+                          "by the bool decoder, meaning that partitions can be decoded even " \
+                          "though earlier partitions have been lost. Note that intra prediction" \
+-                         " is still done over the partition boundary.",       0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"}, \
++                         " is still done over the partition boundary.",       0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, .unit = "er"}, \
+     { "crf",              "Select the quality for constant quality mode", offsetof(VPxContext, crf), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, VE }, \
+     { "static-thresh",    "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, \
+     { "drop-threshold",   "Frame drop threshold", offsetof(VPxContext, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE }, \
+     { "noise-sensitivity", "Noise sensitivity", OFFSET(noise_sensitivity), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 4, VE}, \
+     { "undershoot-pct",  "Datarate undershoot (min) target (%)", OFFSET(rc_undershoot_pct), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 100, VE }, \
+     { "overshoot-pct",   "Datarate overshoot (max) target (%)", OFFSET(rc_overshoot_pct), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1000, VE }, \
+     { "ts-parameters",   "Temporal scaling configuration using a :-separated list of key=value parameters", OFFSET(vpx_ts_parameters), AV_OPT_TYPE_DICT, {.str=NULL},  0,  0, VE}, \
+ 
+ #define LEGACY_OPTIONS \
+     {"speed", "", offsetof(VPxContext, cpu_used), AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE}, \
+-    {"quality", "", offsetof(VPxContext, deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, \
+-    {"vp8flags", "", offsetof(VPxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, UINT_MAX, VE, "flags"}, \
+-    {"error_resilient", "enable error resilience", 0, AV_OPT_TYPE_CONST, {.i64 = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, "flags"}, \
+-    {"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, AV_OPT_TYPE_CONST, {.i64 = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, "flags"}, \
++    {"quality", "", offsetof(VPxContext, deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, .unit = "quality"}, \
++    {"vp8flags", "", offsetof(VPxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, UINT_MAX, VE, .unit = "flags"}, \
++    {"error_resilient", "enable error resilience", 0, AV_OPT_TYPE_CONST, {.i64 = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, .unit = "flags"}, \
++    {"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, AV_OPT_TYPE_CONST, {.i64 = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, .unit = "flags"}, \
+     {"arnr_max_frames", "altref noise reduction max frame count", offsetof(VPxContext, arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 15, VE}, \
+     {"arnr_strength", "altref noise reduction filter strength", offsetof(VPxContext, arnr_strength), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 6, VE}, \
+     {"arnr_type", "altref noise reduction filter type", offsetof(VPxContext, arnr_type), AV_OPT_TYPE_INT, {.i64 = 3}, 1, 3, VE}, \
+     {"rc_lookahead", "Number of frames to look ahead for alternate reference frame selection", offsetof(VPxContext, lag_in_frames), AV_OPT_TYPE_INT, {.i64 = 25}, 0, 25, VE}, \
+     {"sharpness", "Increase sharpness at the expense of lower PSNR", offsetof(VPxContext, sharpness), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 7, VE},
+ 
+ #if CONFIG_LIBVPX_VP8_ENCODER
+ static const AVOption vp8_options[] = {
+     COMMON_OPTIONS
+     { "auto-alt-ref",    "Enable use of alternate reference "
+                          "frames (2-pass only)",                        OFFSET(auto_alt_ref),    AV_OPT_TYPE_INT, {.i64 = -1}, -1,  2, VE},
+     { "cpu-used",        "Quality/Speed ratio modifier",                OFFSET(cpu_used),        AV_OPT_TYPE_INT, {.i64 = 1}, -16, 16, VE},
++    { "screen-content-mode",     "Encoder screen content mode",         OFFSET(screen_content_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1,  2, VE},
+     LEGACY_OPTIONS
+     { NULL }
+ };
+ #endif
+ 
+ #if CONFIG_LIBVPX_VP9_ENCODER
+ static const AVOption vp9_options[] = {
+     COMMON_OPTIONS
+     { "auto-alt-ref",    "Enable use of alternate reference "
+                          "frames (2-pass only)",                        OFFSET(auto_alt_ref),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
+     { "cpu-used",        "Quality/Speed ratio modifier",                OFFSET(cpu_used),        AV_OPT_TYPE_INT, {.i64 = 1},  -8, 8, VE},
+     { "lossless",        "Lossless mode",                               OFFSET(lossless),        AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE},
+     { "tile-columns",    "Number of tile columns to use, log2",         OFFSET(tile_columns),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
+     { "tile-rows",       "Number of tile rows to use, log2",            OFFSET(tile_rows),       AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE},
+     { "frame-parallel",  "Enable frame parallel decodability features", OFFSET(frame_parallel),  AV_OPT_TYPE_BOOL,{.i64 = -1}, -1, 1, VE},
+ #if VPX_ENCODER_ABI_VERSION >= 12
+-    { "aq-mode",         "adaptive quantization mode",                  OFFSET(aq_mode),         AV_OPT_TYPE_INT, {.i64 = -1}, -1, 4, VE, "aq_mode"},
++    { "aq-mode",         "adaptive quantization mode",                  OFFSET(aq_mode),         AV_OPT_TYPE_INT, {.i64 = -1}, -1, 4, VE, .unit = "aq_mode"},
+ #else
+-    { "aq-mode",         "adaptive quantization mode",                  OFFSET(aq_mode),         AV_OPT_TYPE_INT, {.i64 = -1}, -1, 3, VE, "aq_mode"},
++    { "aq-mode",         "adaptive quantization mode",                  OFFSET(aq_mode),         AV_OPT_TYPE_INT, {.i64 = -1}, -1, 3, VE, .unit = "aq_mode"},
+ #endif
+-    { "none",            "Aq not used",         0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, "aq_mode" },
+-    { "variance",        "Variance based Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "aq_mode" },
+-    { "complexity",      "Complexity based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "aq_mode" },
+-    { "cyclic",          "Cyclic Refresh Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "aq_mode" },
++    { "none",            "Aq not used",         0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, .unit = "aq_mode" },
++    { "variance",        "Variance based Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, .unit = "aq_mode" },
++    { "complexity",      "Complexity based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, .unit = "aq_mode" },
++    { "cyclic",          "Cyclic Refresh Aq",   0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, .unit = "aq_mode" },
+ #if VPX_ENCODER_ABI_VERSION >= 12
+-    { "equator360",      "360 video Aq",        0, AV_OPT_TYPE_CONST, {.i64 = 4}, 0, 0, VE, "aq_mode" },
++    { "equator360",      "360 video Aq",        0, AV_OPT_TYPE_CONST, {.i64 = 4}, 0, 0, VE, .unit = "aq_mode" },
+     {"level", "Specify level", OFFSET(level), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 6.2, VE},
+ #endif
+ #ifdef VPX_CTRL_VP9E_SET_ROW_MT
+     {"row-mt", "Row based multi-threading", OFFSET(row_mt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
+ #endif
+ #ifdef VPX_CTRL_VP9E_SET_TUNE_CONTENT
+ #if VPX_ENCODER_ABI_VERSION >= 14
+-    { "tune-content",    "Tune content type", OFFSET(tune_content), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE, "tune_content" },
++    { "tune-content",    "Tune content type", OFFSET(tune_content), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE, .unit = "tune_content" },
+ #else
+-    { "tune-content",    "Tune content type", OFFSET(tune_content), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE, "tune_content" },
++    { "tune-content",    "Tune content type", OFFSET(tune_content), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE, .unit = "tune_content" },
+ #endif
+-    { "default",         "Regular video content",                  0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, "tune_content" },
+-    { "screen",          "Screen capture content",                 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "tune_content" },
++    { "default",         "Regular video content",                  0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, .unit = "tune_content" },
++    { "screen",          "Screen capture content",                 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, .unit = "tune_content" },
+ #if VPX_ENCODER_ABI_VERSION >= 14
+-    { "film",            "Film content; improves grain retention", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "tune_content" },
++    { "film",            "Film content; improves grain retention", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, .unit = "tune_content" },
+ #endif
+ #endif
+ #if VPX_ENCODER_ABI_VERSION >= 14
+     { "corpus-complexity", "corpus vbr complexity midpoint", OFFSET(corpus_complexity), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 10000, VE },
+ #endif
+ #ifdef VPX_CTRL_VP9E_SET_TPL
+     { "enable-tpl",      "Enable temporal dependency model", OFFSET(tpl_model), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE },
+ #endif
+diff --git a/media/ffvpx/libavcodec/me_cmp.h b/media/ffvpx/libavcodec/me_cmp.h
+--- a/media/ffvpx/libavcodec/me_cmp.h
++++ b/media/ffvpx/libavcodec/me_cmp.h
+@@ -81,16 +81,17 @@ typedef struct MECmpContext {
+     me_cmp_func median_sad[6];
+ } MECmpContext;
+ 
+ void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx);
++void ff_me_cmp_init_riscv(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx);
+ 
+ int ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type);
+ 
+ void ff_dsputil_init_dwt(MECmpContext *c);
+ 
+ #endif /* AVCODEC_ME_CMP_H */
+diff --git a/media/ffvpx/libavcodec/moz.build b/media/ffvpx/libavcodec/moz.build
+--- a/media/ffvpx/libavcodec/moz.build
++++ b/media/ffvpx/libavcodec/moz.build
+@@ -10,26 +10,26 @@ if CONFIG['FFVPX_ASFLAGS']:
+     if CONFIG['TARGET_CPU'] == 'x86' or CONFIG['TARGET_CPU'] == 'x86_64':
+         DIRS += ['x86']
+     elif CONFIG['TARGET_CPU'] == 'arm':
+         DIRS += ['arm']
+ 
+ if CONFIG['TARGET_CPU'] == 'aarch64':
+     DIRS += ['aarch64']
+ 
++DIRS += ['bsf']
++
+ LOCAL_INCLUDES += ['/modules/fdlibm/inexact-math-override']
+ 
+ SharedLibrary('mozavcodec')
+ SOURCES += [
+     'allcodecs.c',
+     'audio_frame_queue.c',
+     'avcodec.c',
+     'avdct.c',
+-    'avfft.c',
+-    'avpacket.c',
+     'bitstream.c',
+     'bitstream_filters.c',
+     'bsf.c',
+     'codec_desc.c',
+     'codec_par.c',
+     'dct32_fixed.c',
+     'dct32_float.c',
+     'decode.c',
+@@ -57,18 +57,18 @@ SOURCES += [
+     'mpegaudiodec_common.c',
+     'mpegaudiodec_fixed.c',
+     'mpegaudiodecheader.c',
+     'mpegaudiodsp.c',
+     'mpegaudiodsp_data.c',
+     'mpegaudiodsp_fixed.c',
+     'mpegaudiodsp_float.c',
+     'mpegaudiotabs.c',
+-    'null_bsf.c',
+     'options.c',
++    'packet.c',
+     'parser.c',
+     'parsers.c',
+     'pcm.c',
+     'profiles.c',
+     'pthread.c',
+     'pthread_frame.c',
+     'pthread_slice.c',
+     'refstruct.c',
+@@ -80,20 +80,18 @@ SOURCES += [
+     'vorbis_data.c',
+     'vorbis_parser.c',
+     'xiph.c'
+ ]
+ 
+ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
+     SOURCES += [
+         'atsc_a53.c',
+-        'av1_frame_split_bsf.c',
+         'av1_parse.c',
+         'av1dec.c',
+-        'avpicture.c',
+         'cbs.c',
+         'cbs_av1.c',
+         'golomb.c',
+         'h264pred.c',
+         'imgconvert.c',
+         'libaom.c',
+         'libaomenc.c',
+         'libdav1d.c',
+@@ -104,17 +102,16 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
+         'raw.c',
+         'videodsp.c',
+         'vp8.c',
+         'vp8_parser.c',
+         'vp8data.c',
+         'vp8dsp.c',
+         'vp9.c',
+         'vp9_parser.c',
+-        'vp9_superframe_split_bsf.c',
+         'vp9block.c',
+         'vp9data.c',
+         'vp9dsp.c',
+         'vp9dsp_10bpp.c',
+         'vp9dsp_12bpp.c',
+         'vp9dsp_8bpp.c',
+         'vp9lpf.c',
+         'vp9mvs.c',
+@@ -138,16 +135,21 @@ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
+           'mozva'
+         ]
+ 
+ LOCAL_INCLUDES += [
+     '/media/libopus/include',
+     '/media/libvorbis',
+ ]
+ 
++c11_flags = ["-std=gnu11"]
++if CONFIG["CC_TYPE"] == "clang-cl":
++    c11_flags.insert(0, "-Xclang")
++CFLAGS += c11_flags
++
+ if not CONFIG["MOZ_SYSTEM_LIBVPX"]:
+   LOCAL_INCLUDES += ['/media/libvpx']
+ else:
+   CXXFLAGS += CONFIG["MOZ_LIBVPX_CFLAGS"]
+   OS_LIBS += CONFIG["MOZ_LIBVPX_LIBS"]
+ 
+ SYMBOLS_FILE = 'avcodec.symbols'
+ NoVisibilityFlags()
+diff --git a/media/ffvpx/libavcodec/mpegaudiodata.h b/media/ffvpx/libavcodec/mpegaudiodata.h
+--- a/media/ffvpx/libavcodec/mpegaudiodata.h
++++ b/media/ffvpx/libavcodec/mpegaudiodata.h
+@@ -26,21 +26,23 @@
+ 
+ #ifndef AVCODEC_MPEGAUDIODATA_H
+ #define AVCODEC_MPEGAUDIODATA_H
+ 
+ #include <stdint.h>
+ 
+ #include "config.h"
+ 
++#include "libavutil/attributes_internal.h"
+ #include "vlc.h"
+ 
+ #define MODE_EXT_MS_STEREO 2
+ #define MODE_EXT_I_STEREO  1
+ 
++FF_VISIBILITY_PUSH_HIDDEN
+ extern const uint16_t ff_mpa_bitrate_tab[2][3][15];
+ extern const uint16_t ff_mpa_freq_tab[3];
+ extern const int ff_mpa_sblimit_table[5];
+ extern const int ff_mpa_quant_steps[17];
+ extern const int ff_mpa_quant_bits[17];
+ extern const unsigned char * const ff_mpa_alloc_tables[5];
+ 
+ #define TABLE_4_3_SIZE ((8191 + 16)*4)
+@@ -73,10 +75,11 @@ extern int16_t *const ff_division_tabs[4
+ /* lower 2 bits: modulo 3, higher bits: shift */
+ extern uint16_t ff_scale_factor_modshift[64];
+ 
+ extern const uint8_t ff_mpa_pretab[2][22];
+ 
+ /* Initialize tables shared between the fixed and
+  * floating point MPEG audio decoders. */
+ void ff_mpegaudiodec_common_init_static(void);
++FF_VISIBILITY_POP_HIDDEN
+ 
+ #endif /* AVCODEC_MPEGAUDIODATA_H */
+diff --git a/media/ffvpx/libavcodec/mpegaudiodec_template.c b/media/ffvpx/libavcodec/mpegaudiodec_template.c
+--- a/media/ffvpx/libavcodec/mpegaudiodec_template.c
++++ b/media/ffvpx/libavcodec/mpegaudiodec_template.c
+@@ -27,16 +27,17 @@
+ #include "config_components.h"
+ 
+ #include "libavutil/attributes.h"
+ #include "libavutil/avassert.h"
+ #include "libavutil/channel_layout.h"
+ #include "libavutil/crc.h"
+ #include "libavutil/float_dsp.h"
+ #include "libavutil/libm.h"
++#include "libavutil/mem.h"
+ #include "libavutil/mem_internal.h"
+ #include "libavutil/thread.h"
+ 
+ #include "avcodec.h"
+ #include "decode.h"
+ #include "get_bits.h"
+ #include "mathops.h"
+ #include "mpegaudiodsp.h"
+@@ -87,17 +88,17 @@ typedef struct MPADecodeContext {
+     DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT];
+     INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
+     GranuleDef granules[2][2]; /* Used in Layer 3 */
+     int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
+     int dither_state;
+     int err_recognition;
+     AVCodecContext* avctx;
+     MPADSPContext mpadsp;
+-    void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len);
++    void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);
+     AVFrame *frame;
+     uint32_t crc;
+ } MPADecodeContext;
+ 
+ #define HEADER_SIZE 4
+ 
+ #include "mpegaudiodata.h"
+ 
+diff --git a/media/ffvpx/libavcodec/mpegaudiodectab.h b/media/ffvpx/libavcodec/mpegaudiodectab.h
+deleted file mode 100644
+--- a/media/ffvpx/libavcodec/mpegaudiodectab.h
++++ /dev/null
+@@ -1,615 +0,0 @@
+-/*
+- * MPEG Audio decoder
+- * copyright (c) 2002 Fabrice Bellard
+- *
+- * 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
+- */
+-
+-/**
+- * @file
+- * mpeg audio layer decoder tables.
+- */
+-
+-#ifndef AVCODEC_MPEGAUDIODECTAB_H
+-#define AVCODEC_MPEGAUDIODECTAB_H
+-
+-#include <stddef.h>
+-#include <stdint.h>
+-
+-#include "mpegaudio.h"
+-
+-/*******************************************************/
+-/* layer 3 tables */
+-
+-/* layer 3 huffman tables */
+-typedef struct HuffTable {
+-    int xsize;
+-    const uint8_t *bits;
+-    const uint16_t *codes;
+-} HuffTable;
+-
+-/* layer3 scale factor size */
+-static const uint8_t slen_table[2][16] = {
+-    { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
+-    { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 },
+-};
+-
+-/* number of lsf scale factors for a given size */
+-static const uint8_t lsf_nsf_table[6][3][4] = {
+-    { {  6,  5,  5, 5 }, {  9,  9,  9, 9 }, {  6,  9,  9, 9 } },
+-    { {  6,  5,  7, 3 }, {  9,  9, 12, 6 }, {  6,  9, 12, 6 } },
+-    { { 11, 10,  0, 0 }, { 18, 18,  0, 0 }, { 15, 18,  0, 0 } },
+-    { {  7,  7,  7, 0 }, { 12, 12, 12, 0 }, {  6, 15, 12, 0 } },
+-    { {  6,  6,  6, 3 }, { 12,  9,  9, 6 }, {  6, 12,  9, 6 } },
+-    { {  8,  8,  5, 0 }, { 15, 12,  9, 0 }, {  6, 18,  9, 0 } },
+-};
+-
+-/* mpegaudio layer 3 huffman tables */
+-
+-static const uint16_t mpa_huffcodes_1[4] = {
+- 0x0001, 0x0001, 0x0001, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_1[4] = {
+-  1,  3,  2,  3,
+-};
+-
+-static const uint16_t mpa_huffcodes_2[9] = {
+- 0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0001, 0x0003, 0x0002,
+- 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_2[9] = {
+-  1,  3,  6,  3,  3,  5,  5,  5,
+-  6,
+-};
+-
+-static const uint16_t mpa_huffcodes_3[9] = {
+- 0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0002,
+- 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_3[9] = {
+-  2,  2,  6,  3,  2,  5,  5,  5,
+-  6,
+-};
+-
+-static const uint16_t mpa_huffcodes_5[16] = {
+- 0x0001, 0x0002, 0x0006, 0x0005, 0x0003, 0x0001, 0x0004, 0x0004,
+- 0x0007, 0x0005, 0x0007, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_5[16] = {
+-  1,  3,  6,  7,  3,  3,  6,  7,
+-  6,  6,  7,  8,  7,  6,  7,  8,
+-};
+-
+-static const uint16_t mpa_huffcodes_6[16] = {
+- 0x0007, 0x0003, 0x0005, 0x0001, 0x0006, 0x0002, 0x0003, 0x0002,
+- 0x0005, 0x0004, 0x0004, 0x0001, 0x0003, 0x0003, 0x0002, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_6[16] = {
+-  3,  3,  5,  7,  3,  2,  4,  5,
+-  4,  4,  5,  6,  6,  5,  6,  7,
+-};
+-
+-static const uint16_t mpa_huffcodes_7[36] = {
+- 0x0001, 0x0002, 0x000a, 0x0013, 0x0010, 0x000a, 0x0003, 0x0003,
+- 0x0007, 0x000a, 0x0005, 0x0003, 0x000b, 0x0004, 0x000d, 0x0011,
+- 0x0008, 0x0004, 0x000c, 0x000b, 0x0012, 0x000f, 0x000b, 0x0002,
+- 0x0007, 0x0006, 0x0009, 0x000e, 0x0003, 0x0001, 0x0006, 0x0004,
+- 0x0005, 0x0003, 0x0002, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_7[36] = {
+-  1,  3,  6,  8,  8,  9,  3,  4,
+-  6,  7,  7,  8,  6,  5,  7,  8,
+-  8,  9,  7,  7,  8,  9,  9,  9,
+-  7,  7,  8,  9,  9, 10,  8,  8,
+-  9, 10, 10, 10,
+-};
+-
+-static const uint16_t mpa_huffcodes_8[36] = {
+- 0x0003, 0x0004, 0x0006, 0x0012, 0x000c, 0x0005, 0x0005, 0x0001,
+- 0x0002, 0x0010, 0x0009, 0x0003, 0x0007, 0x0003, 0x0005, 0x000e,
+- 0x0007, 0x0003, 0x0013, 0x0011, 0x000f, 0x000d, 0x000a, 0x0004,
+- 0x000d, 0x0005, 0x0008, 0x000b, 0x0005, 0x0001, 0x000c, 0x0004,
+- 0x0004, 0x0001, 0x0001, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_8[36] = {
+-  2,  3,  6,  8,  8,  9,  3,  2,
+-  4,  8,  8,  8,  6,  4,  6,  8,
+-  8,  9,  8,  8,  8,  9,  9, 10,
+-  8,  7,  8,  9, 10, 10,  9,  8,
+-  9,  9, 11, 11,
+-};
+-
+-static const uint16_t mpa_huffcodes_9[36] = {
+- 0x0007, 0x0005, 0x0009, 0x000e, 0x000f, 0x0007, 0x0006, 0x0004,
+- 0x0005, 0x0005, 0x0006, 0x0007, 0x0007, 0x0006, 0x0008, 0x0008,
+- 0x0008, 0x0005, 0x000f, 0x0006, 0x0009, 0x000a, 0x0005, 0x0001,
+- 0x000b, 0x0007, 0x0009, 0x0006, 0x0004, 0x0001, 0x000e, 0x0004,
+- 0x0006, 0x0002, 0x0006, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_9[36] = {
+-  3,  3,  5,  6,  8,  9,  3,  3,
+-  4,  5,  6,  8,  4,  4,  5,  6,
+-  7,  8,  6,  5,  6,  7,  7,  8,
+-  7,  6,  7,  7,  8,  9,  8,  7,
+-  8,  8,  9,  9,
+-};
+-
+-static const uint16_t mpa_huffcodes_10[64] = {
+- 0x0001, 0x0002, 0x000a, 0x0017, 0x0023, 0x001e, 0x000c, 0x0011,
+- 0x0003, 0x0003, 0x0008, 0x000c, 0x0012, 0x0015, 0x000c, 0x0007,
+- 0x000b, 0x0009, 0x000f, 0x0015, 0x0020, 0x0028, 0x0013, 0x0006,
+- 0x000e, 0x000d, 0x0016, 0x0022, 0x002e, 0x0017, 0x0012, 0x0007,
+- 0x0014, 0x0013, 0x0021, 0x002f, 0x001b, 0x0016, 0x0009, 0x0003,
+- 0x001f, 0x0016, 0x0029, 0x001a, 0x0015, 0x0014, 0x0005, 0x0003,
+- 0x000e, 0x000d, 0x000a, 0x000b, 0x0010, 0x0006, 0x0005, 0x0001,
+- 0x0009, 0x0008, 0x0007, 0x0008, 0x0004, 0x0004, 0x0002, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_10[64] = {
+-  1,  3,  6,  8,  9,  9,  9, 10,
+-  3,  4,  6,  7,  8,  9,  8,  8,
+-  6,  6,  7,  8,  9, 10,  9,  9,
+-  7,  7,  8,  9, 10, 10,  9, 10,
+-  8,  8,  9, 10, 10, 10, 10, 10,
+-  9,  9, 10, 10, 11, 11, 10, 11,
+-  8,  8,  9, 10, 10, 10, 11, 11,
+-  9,  8,  9, 10, 10, 11, 11, 11,
+-};
+-
+-static const uint16_t mpa_huffcodes_11[64] = {
+- 0x0003, 0x0004, 0x000a, 0x0018, 0x0022, 0x0021, 0x0015, 0x000f,
+- 0x0005, 0x0003, 0x0004, 0x000a, 0x0020, 0x0011, 0x000b, 0x000a,
+- 0x000b, 0x0007, 0x000d, 0x0012, 0x001e, 0x001f, 0x0014, 0x0005,
+- 0x0019, 0x000b, 0x0013, 0x003b, 0x001b, 0x0012, 0x000c, 0x0005,
+- 0x0023, 0x0021, 0x001f, 0x003a, 0x001e, 0x0010, 0x0007, 0x0005,
+- 0x001c, 0x001a, 0x0020, 0x0013, 0x0011, 0x000f, 0x0008, 0x000e,
+- 0x000e, 0x000c, 0x0009, 0x000d, 0x000e, 0x0009, 0x0004, 0x0001,
+- 0x000b, 0x0004, 0x0006, 0x0006, 0x0006, 0x0003, 0x0002, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_11[64] = {
+-  2,  3,  5,  7,  8,  9,  8,  9,
+-  3,  3,  4,  6,  8,  8,  7,  8,
+-  5,  5,  6,  7,  8,  9,  8,  8,
+-  7,  6,  7,  9,  8, 10,  8,  9,
+-  8,  8,  8,  9,  9, 10,  9, 10,
+-  8,  8,  9, 10, 10, 11, 10, 11,
+-  8,  7,  7,  8,  9, 10, 10, 10,
+-  8,  7,  8,  9, 10, 10, 10, 10,
+-};
+-
+-static const uint16_t mpa_huffcodes_12[64] = {
+- 0x0009, 0x0006, 0x0010, 0x0021, 0x0029, 0x0027, 0x0026, 0x001a,
+- 0x0007, 0x0005, 0x0006, 0x0009, 0x0017, 0x0010, 0x001a, 0x000b,
+- 0x0011, 0x0007, 0x000b, 0x000e, 0x0015, 0x001e, 0x000a, 0x0007,
+- 0x0011, 0x000a, 0x000f, 0x000c, 0x0012, 0x001c, 0x000e, 0x0005,
+- 0x0020, 0x000d, 0x0016, 0x0013, 0x0012, 0x0010, 0x0009, 0x0005,
+- 0x0028, 0x0011, 0x001f, 0x001d, 0x0011, 0x000d, 0x0004, 0x0002,
+- 0x001b, 0x000c, 0x000b, 0x000f, 0x000a, 0x0007, 0x0004, 0x0001,
+- 0x001b, 0x000c, 0x0008, 0x000c, 0x0006, 0x0003, 0x0001, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_12[64] = {
+-  4,  3,  5,  7,  8,  9,  9,  9,
+-  3,  3,  4,  5,  7,  7,  8,  8,
+-  5,  4,  5,  6,  7,  8,  7,  8,
+-  6,  5,  6,  6,  7,  8,  8,  8,
+-  7,  6,  7,  7,  8,  8,  8,  9,
+-  8,  7,  8,  8,  8,  9,  8,  9,
+-  8,  7,  7,  8,  8,  9,  9, 10,
+-  9,  8,  8,  9,  9,  9,  9, 10,
+-};
+-
+-static const uint16_t mpa_huffcodes_13[256] = {
+- 0x0001, 0x0005, 0x000e, 0x0015, 0x0022, 0x0033, 0x002e, 0x0047,
+- 0x002a, 0x0034, 0x0044, 0x0034, 0x0043, 0x002c, 0x002b, 0x0013,
+- 0x0003, 0x0004, 0x000c, 0x0013, 0x001f, 0x001a, 0x002c, 0x0021,
+- 0x001f, 0x0018, 0x0020, 0x0018, 0x001f, 0x0023, 0x0016, 0x000e,
+- 0x000f, 0x000d, 0x0017, 0x0024, 0x003b, 0x0031, 0x004d, 0x0041,
+- 0x001d, 0x0028, 0x001e, 0x0028, 0x001b, 0x0021, 0x002a, 0x0010,
+- 0x0016, 0x0014, 0x0025, 0x003d, 0x0038, 0x004f, 0x0049, 0x0040,
+- 0x002b, 0x004c, 0x0038, 0x0025, 0x001a, 0x001f, 0x0019, 0x000e,
+- 0x0023, 0x0010, 0x003c, 0x0039, 0x0061, 0x004b, 0x0072, 0x005b,
+- 0x0036, 0x0049, 0x0037, 0x0029, 0x0030, 0x0035, 0x0017, 0x0018,
+- 0x003a, 0x001b, 0x0032, 0x0060, 0x004c, 0x0046, 0x005d, 0x0054,
+- 0x004d, 0x003a, 0x004f, 0x001d, 0x004a, 0x0031, 0x0029, 0x0011,
+- 0x002f, 0x002d, 0x004e, 0x004a, 0x0073, 0x005e, 0x005a, 0x004f,
+- 0x0045, 0x0053, 0x0047, 0x0032, 0x003b, 0x0026, 0x0024, 0x000f,
+- 0x0048, 0x0022, 0x0038, 0x005f, 0x005c, 0x0055, 0x005b, 0x005a,
+- 0x0056, 0x0049, 0x004d, 0x0041, 0x0033, 0x002c, 0x002b, 0x002a,
+- 0x002b, 0x0014, 0x001e, 0x002c, 0x0037, 0x004e, 0x0048, 0x0057,
+- 0x004e, 0x003d, 0x002e, 0x0036, 0x0025, 0x001e, 0x0014, 0x0010,
+- 0x0035, 0x0019, 0x0029, 0x0025, 0x002c, 0x003b, 0x0036, 0x0051,
+- 0x0042, 0x004c, 0x0039, 0x0036, 0x0025, 0x0012, 0x0027, 0x000b,
+- 0x0023, 0x0021, 0x001f, 0x0039, 0x002a, 0x0052, 0x0048, 0x0050,
+- 0x002f, 0x003a, 0x0037, 0x0015, 0x0016, 0x001a, 0x0026, 0x0016,
+- 0x0035, 0x0019, 0x0017, 0x0026, 0x0046, 0x003c, 0x0033, 0x0024,
+- 0x0037, 0x001a, 0x0022, 0x0017, 0x001b, 0x000e, 0x0009, 0x0007,
+- 0x0022, 0x0020, 0x001c, 0x0027, 0x0031, 0x004b, 0x001e, 0x0034,
+- 0x0030, 0x0028, 0x0034, 0x001c, 0x0012, 0x0011, 0x0009, 0x0005,
+- 0x002d, 0x0015, 0x0022, 0x0040, 0x0038, 0x0032, 0x0031, 0x002d,
+- 0x001f, 0x0013, 0x000c, 0x000f, 0x000a, 0x0007, 0x0006, 0x0003,
+- 0x0030, 0x0017, 0x0014, 0x0027, 0x0024, 0x0023, 0x0035, 0x0015,
+- 0x0010, 0x0017, 0x000d, 0x000a, 0x0006, 0x0001, 0x0004, 0x0002,
+- 0x0010, 0x000f, 0x0011, 0x001b, 0x0019, 0x0014, 0x001d, 0x000b,
+- 0x0011, 0x000c, 0x0010, 0x0008, 0x0001, 0x0001, 0x0000, 0x0001,
+-};
+-
+-static const uint8_t mpa_huffbits_13[256] = {
+-  1,  4,  6,  7,  8,  9,  9, 10,
+-  9, 10, 11, 11, 12, 12, 13, 13,
+-  3,  4,  6,  7,  8,  8,  9,  9,
+-  9,  9, 10, 10, 11, 12, 12, 12,
+-  6,  6,  7,  8,  9,  9, 10, 10,
+-  9, 10, 10, 11, 11, 12, 13, 13,
+-  7,  7,  8,  9,  9, 10, 10, 10,
+- 10, 11, 11, 11, 11, 12, 13, 13,
+-  8,  7,  9,  9, 10, 10, 11, 11,
+- 10, 11, 11, 12, 12, 13, 13, 14,
+-  9,  8,  9, 10, 10, 10, 11, 11,
+- 11, 11, 12, 11, 13, 13, 14, 14,
+-  9,  9, 10, 10, 11, 11, 11, 11,
+- 11, 12, 12, 12, 13, 13, 14, 14,
+- 10,  9, 10, 11, 11, 11, 12, 12,
+- 12, 12, 13, 13, 13, 14, 16, 16,
+-  9,  8,  9, 10, 10, 11, 11, 12,
+- 12, 12, 12, 13, 13, 14, 15, 15,
+- 10,  9, 10, 10, 11, 11, 11, 13,
+- 12, 13, 13, 14, 14, 14, 16, 15,
+- 10, 10, 10, 11, 11, 12, 12, 13,
+- 12, 13, 14, 13, 14, 15, 16, 17,
+- 11, 10, 10, 11, 12, 12, 12, 12,
+- 13, 13, 13, 14, 15, 15, 15, 16,
+- 11, 11, 11, 12, 12, 13, 12, 13,
+- 14, 14, 15, 15, 15, 16, 16, 16,
+- 12, 11, 12, 13, 13, 13, 14, 14,
+- 14, 14, 14, 15, 16, 15, 16, 16,
+- 13, 12, 12, 13, 13, 13, 15, 14,
+- 14, 17, 15, 15, 15, 17, 16, 16,
+- 12, 12, 13, 14, 14, 14, 15, 14,
+- 15, 15, 16, 16, 19, 18, 19, 16,
+-};
+-
+-static const uint16_t mpa_huffcodes_15[256] = {
+- 0x0007, 0x000c, 0x0012, 0x0035, 0x002f, 0x004c, 0x007c, 0x006c,
+- 0x0059, 0x007b, 0x006c, 0x0077, 0x006b, 0x0051, 0x007a, 0x003f,
+- 0x000d, 0x0005, 0x0010, 0x001b, 0x002e, 0x0024, 0x003d, 0x0033,
+- 0x002a, 0x0046, 0x0034, 0x0053, 0x0041, 0x0029, 0x003b, 0x0024,
+- 0x0013, 0x0011, 0x000f, 0x0018, 0x0029, 0x0022, 0x003b, 0x0030,
+- 0x0028, 0x0040, 0x0032, 0x004e, 0x003e, 0x0050, 0x0038, 0x0021,
+- 0x001d, 0x001c, 0x0019, 0x002b, 0x0027, 0x003f, 0x0037, 0x005d,
+- 0x004c, 0x003b, 0x005d, 0x0048, 0x0036, 0x004b, 0x0032, 0x001d,
+- 0x0034, 0x0016, 0x002a, 0x0028, 0x0043, 0x0039, 0x005f, 0x004f,
+- 0x0048, 0x0039, 0x0059, 0x0045, 0x0031, 0x0042, 0x002e, 0x001b,
+- 0x004d, 0x0025, 0x0023, 0x0042, 0x003a, 0x0034, 0x005b, 0x004a,
+- 0x003e, 0x0030, 0x004f, 0x003f, 0x005a, 0x003e, 0x0028, 0x0026,
+- 0x007d, 0x0020, 0x003c, 0x0038, 0x0032, 0x005c, 0x004e, 0x0041,
+- 0x0037, 0x0057, 0x0047, 0x0033, 0x0049, 0x0033, 0x0046, 0x001e,
+- 0x006d, 0x0035, 0x0031, 0x005e, 0x0058, 0x004b, 0x0042, 0x007a,
+- 0x005b, 0x0049, 0x0038, 0x002a, 0x0040, 0x002c, 0x0015, 0x0019,
+- 0x005a, 0x002b, 0x0029, 0x004d, 0x0049, 0x003f, 0x0038, 0x005c,
+- 0x004d, 0x0042, 0x002f, 0x0043, 0x0030, 0x0035, 0x0024, 0x0014,
+- 0x0047, 0x0022, 0x0043, 0x003c, 0x003a, 0x0031, 0x0058, 0x004c,
+- 0x0043, 0x006a, 0x0047, 0x0036, 0x0026, 0x0027, 0x0017, 0x000f,
+- 0x006d, 0x0035, 0x0033, 0x002f, 0x005a, 0x0052, 0x003a, 0x0039,
+- 0x0030, 0x0048, 0x0039, 0x0029, 0x0017, 0x001b, 0x003e, 0x0009,
+- 0x0056, 0x002a, 0x0028, 0x0025, 0x0046, 0x0040, 0x0034, 0x002b,
+- 0x0046, 0x0037, 0x002a, 0x0019, 0x001d, 0x0012, 0x000b, 0x000b,
+- 0x0076, 0x0044, 0x001e, 0x0037, 0x0032, 0x002e, 0x004a, 0x0041,
+- 0x0031, 0x0027, 0x0018, 0x0010, 0x0016, 0x000d, 0x000e, 0x0007,
+- 0x005b, 0x002c, 0x0027, 0x0026, 0x0022, 0x003f, 0x0034, 0x002d,
+- 0x001f, 0x0034, 0x001c, 0x0013, 0x000e, 0x0008, 0x0009, 0x0003,
+- 0x007b, 0x003c, 0x003a, 0x0035, 0x002f, 0x002b, 0x0020, 0x0016,
+- 0x0025, 0x0018, 0x0011, 0x000c, 0x000f, 0x000a, 0x0002, 0x0001,
+- 0x0047, 0x0025, 0x0022, 0x001e, 0x001c, 0x0014, 0x0011, 0x001a,
+- 0x0015, 0x0010, 0x000a, 0x0006, 0x0008, 0x0006, 0x0002, 0x0000,
+-};
+-
+-static const uint8_t mpa_huffbits_15[256] = {
+-  3,  4,  5,  7,  7,  8,  9,  9,
+-  9, 10, 10, 11, 11, 11, 12, 13,
+-  4,  3,  5,  6,  7,  7,  8,  8,
+-  8,  9,  9, 10, 10, 10, 11, 11,
+-  5,  5,  5,  6,  7,  7,  8,  8,
+-  8,  9,  9, 10, 10, 11, 11, 11,
+-  6,  6,  6,  7,  7,  8,  8,  9,
+-  9,  9, 10, 10, 10, 11, 11, 11,
+-  7,  6,  7,  7,  8,  8,  9,  9,
+-  9,  9, 10, 10, 10, 11, 11, 11,
+-  8,  7,  7,  8,  8,  8,  9,  9,
+-  9,  9, 10, 10, 11, 11, 11, 12,
+-  9,  7,  8,  8,  8,  9,  9,  9,
+-  9, 10, 10, 10, 11, 11, 12, 12,
+-  9,  8,  8,  9,  9,  9,  9, 10,
+- 10, 10, 10, 10, 11, 11, 11, 12,
+-  9,  8,  8,  9,  9,  9,  9, 10,
+- 10, 10, 10, 11, 11, 12, 12, 12,
+-  9,  8,  9,  9,  9,  9, 10, 10,
+- 10, 11, 11, 11, 11, 12, 12, 12,
+- 10,  9,  9,  9, 10, 10, 10, 10,
+- 10, 11, 11, 11, 11, 12, 13, 12,
+- 10,  9,  9,  9, 10, 10, 10, 10,
+- 11, 11, 11, 11, 12, 12, 12, 13,
+- 11, 10,  9, 10, 10, 10, 11, 11,
+- 11, 11, 11, 11, 12, 12, 13, 13,
+- 11, 10, 10, 10, 10, 11, 11, 11,
+- 11, 12, 12, 12, 12, 12, 13, 13,
+- 12, 11, 11, 11, 11, 11, 11, 11,
+- 12, 12, 12, 12, 13, 13, 12, 13,
+- 12, 11, 11, 11, 11, 11, 11, 12,
+- 12, 12, 12, 12, 13, 13, 13, 13,
+-};
+-
+-static const uint16_t mpa_huffcodes_16[256] = {
+- 0x0001, 0x0005, 0x000e, 0x002c, 0x004a, 0x003f, 0x006e, 0x005d,
+- 0x00ac, 0x0095, 0x008a, 0x00f2, 0x00e1, 0x00c3, 0x0178, 0x0011,
+- 0x0003, 0x0004, 0x000c, 0x0014, 0x0023, 0x003e, 0x0035, 0x002f,
+- 0x0053, 0x004b, 0x0044, 0x0077, 0x00c9, 0x006b, 0x00cf, 0x0009,
+- 0x000f, 0x000d, 0x0017, 0x0026, 0x0043, 0x003a, 0x0067, 0x005a,
+- 0x00a1, 0x0048, 0x007f, 0x0075, 0x006e, 0x00d1, 0x00ce, 0x0010,
+- 0x002d, 0x0015, 0x0027, 0x0045, 0x0040, 0x0072, 0x0063, 0x0057,
+- 0x009e, 0x008c, 0x00fc, 0x00d4, 0x00c7, 0x0183, 0x016d, 0x001a,
+- 0x004b, 0x0024, 0x0044, 0x0041, 0x0073, 0x0065, 0x00b3, 0x00a4,
+- 0x009b, 0x0108, 0x00f6, 0x00e2, 0x018b, 0x017e, 0x016a, 0x0009,
+- 0x0042, 0x001e, 0x003b, 0x0038, 0x0066, 0x00b9, 0x00ad, 0x0109,
+- 0x008e, 0x00fd, 0x00e8, 0x0190, 0x0184, 0x017a, 0x01bd, 0x0010,
+- 0x006f, 0x0036, 0x0034, 0x0064, 0x00b8, 0x00b2, 0x00a0, 0x0085,
+- 0x0101, 0x00f4, 0x00e4, 0x00d9, 0x0181, 0x016e, 0x02cb, 0x000a,
+- 0x0062, 0x0030, 0x005b, 0x0058, 0x00a5, 0x009d, 0x0094, 0x0105,
+- 0x00f8, 0x0197, 0x018d, 0x0174, 0x017c, 0x0379, 0x0374, 0x0008,
+- 0x0055, 0x0054, 0x0051, 0x009f, 0x009c, 0x008f, 0x0104, 0x00f9,
+- 0x01ab, 0x0191, 0x0188, 0x017f, 0x02d7, 0x02c9, 0x02c4, 0x0007,
+- 0x009a, 0x004c, 0x0049, 0x008d, 0x0083, 0x0100, 0x00f5, 0x01aa,
+- 0x0196, 0x018a, 0x0180, 0x02df, 0x0167, 0x02c6, 0x0160, 0x000b,
+- 0x008b, 0x0081, 0x0043, 0x007d, 0x00f7, 0x00e9, 0x00e5, 0x00db,
+- 0x0189, 0x02e7, 0x02e1, 0x02d0, 0x0375, 0x0372, 0x01b7, 0x0004,
+- 0x00f3, 0x0078, 0x0076, 0x0073, 0x00e3, 0x00df, 0x018c, 0x02ea,
+- 0x02e6, 0x02e0, 0x02d1, 0x02c8, 0x02c2, 0x00df, 0x01b4, 0x0006,
+- 0x00ca, 0x00e0, 0x00de, 0x00da, 0x00d8, 0x0185, 0x0182, 0x017d,
+- 0x016c, 0x0378, 0x01bb, 0x02c3, 0x01b8, 0x01b5, 0x06c0, 0x0004,
+- 0x02eb, 0x00d3, 0x00d2, 0x00d0, 0x0172, 0x017b, 0x02de, 0x02d3,
+- 0x02ca, 0x06c7, 0x0373, 0x036d, 0x036c, 0x0d83, 0x0361, 0x0002,
+- 0x0179, 0x0171, 0x0066, 0x00bb, 0x02d6, 0x02d2, 0x0166, 0x02c7,
+- 0x02c5, 0x0362, 0x06c6, 0x0367, 0x0d82, 0x0366, 0x01b2, 0x0000,
+- 0x000c, 0x000a, 0x0007, 0x000b, 0x000a, 0x0011, 0x000b, 0x0009,
+- 0x000d, 0x000c, 0x000a, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
+-};
+-
+-static const uint8_t mpa_huffbits_16[256] = {
+-  1,  4,  6,  8,  9,  9, 10, 10,
+- 11, 11, 11, 12, 12, 12, 13,  9,
+-  3,  4,  6,  7,  8,  9,  9,  9,
+- 10, 10, 10, 11, 12, 11, 12,  8,
+-  6,  6,  7,  8,  9,  9, 10, 10,
+- 11, 10, 11, 11, 11, 12, 12,  9,
+-  8,  7,  8,  9,  9, 10, 10, 10,
+- 11, 11, 12, 12, 12, 13, 13, 10,
+-  9,  8,  9,  9, 10, 10, 11, 11,
+- 11, 12, 12, 12, 13, 13, 13,  9,
+-  9,  8,  9,  9, 10, 11, 11, 12,
+- 11, 12, 12, 13, 13, 13, 14, 10,
+- 10,  9,  9, 10, 11, 11, 11, 11,
+- 12, 12, 12, 12, 13, 13, 14, 10,
+- 10,  9, 10, 10, 11, 11, 11, 12,
+- 12, 13, 13, 13, 13, 15, 15, 10,
+- 10, 10, 10, 11, 11, 11, 12, 12,
+- 13, 13, 13, 13, 14, 14, 14, 10,
+- 11, 10, 10, 11, 11, 12, 12, 13,
+- 13, 13, 13, 14, 13, 14, 13, 11,
+- 11, 11, 10, 11, 12, 12, 12, 12,
+- 13, 14, 14, 14, 15, 15, 14, 10,
+- 12, 11, 11, 11, 12, 12, 13, 14,
+- 14, 14, 14, 14, 14, 13, 14, 11,
+- 12, 12, 12, 12, 12, 13, 13, 13,
+- 13, 15, 14, 14, 14, 14, 16, 11,
+- 14, 12, 12, 12, 13, 13, 14, 14,
+- 14, 16, 15, 15, 15, 17, 15, 11,
+- 13, 13, 11, 12, 14, 14, 13, 14,
+- 14, 15, 16, 15, 17, 15, 14, 11,
+-  9,  8,  8,  9,  9, 10, 10, 10,
+- 11, 11, 11, 11, 11, 11, 11,  8,
+-};
+-
+-static const uint16_t mpa_huffcodes_24[256] = {
+- 0x000f, 0x000d, 0x002e, 0x0050, 0x0092, 0x0106, 0x00f8, 0x01b2,
+- 0x01aa, 0x029d, 0x028d, 0x0289, 0x026d, 0x0205, 0x0408, 0x0058,
+- 0x000e, 0x000c, 0x0015, 0x0026, 0x0047, 0x0082, 0x007a, 0x00d8,
+- 0x00d1, 0x00c6, 0x0147, 0x0159, 0x013f, 0x0129, 0x0117, 0x002a,
+- 0x002f, 0x0016, 0x0029, 0x004a, 0x0044, 0x0080, 0x0078, 0x00dd,
+- 0x00cf, 0x00c2, 0x00b6, 0x0154, 0x013b, 0x0127, 0x021d, 0x0012,
+- 0x0051, 0x0027, 0x004b, 0x0046, 0x0086, 0x007d, 0x0074, 0x00dc,
+- 0x00cc, 0x00be, 0x00b2, 0x0145, 0x0137, 0x0125, 0x010f, 0x0010,
+- 0x0093, 0x0048, 0x0045, 0x0087, 0x007f, 0x0076, 0x0070, 0x00d2,
+- 0x00c8, 0x00bc, 0x0160, 0x0143, 0x0132, 0x011d, 0x021c, 0x000e,
+- 0x0107, 0x0042, 0x0081, 0x007e, 0x0077, 0x0072, 0x00d6, 0x00ca,
+- 0x00c0, 0x00b4, 0x0155, 0x013d, 0x012d, 0x0119, 0x0106, 0x000c,
+- 0x00f9, 0x007b, 0x0079, 0x0075, 0x0071, 0x00d7, 0x00ce, 0x00c3,
+- 0x00b9, 0x015b, 0x014a, 0x0134, 0x0123, 0x0110, 0x0208, 0x000a,
+- 0x01b3, 0x0073, 0x006f, 0x006d, 0x00d3, 0x00cb, 0x00c4, 0x00bb,
+- 0x0161, 0x014c, 0x0139, 0x012a, 0x011b, 0x0213, 0x017d, 0x0011,
+- 0x01ab, 0x00d4, 0x00d0, 0x00cd, 0x00c9, 0x00c1, 0x00ba, 0x00b1,
+- 0x00a9, 0x0140, 0x012f, 0x011e, 0x010c, 0x0202, 0x0179, 0x0010,
+- 0x014f, 0x00c7, 0x00c5, 0x00bf, 0x00bd, 0x00b5, 0x00ae, 0x014d,
+- 0x0141, 0x0131, 0x0121, 0x0113, 0x0209, 0x017b, 0x0173, 0x000b,
+- 0x029c, 0x00b8, 0x00b7, 0x00b3, 0x00af, 0x0158, 0x014b, 0x013a,
+- 0x0130, 0x0122, 0x0115, 0x0212, 0x017f, 0x0175, 0x016e, 0x000a,
+- 0x028c, 0x015a, 0x00ab, 0x00a8, 0x00a4, 0x013e, 0x0135, 0x012b,
+- 0x011f, 0x0114, 0x0107, 0x0201, 0x0177, 0x0170, 0x016a, 0x0006,
+- 0x0288, 0x0142, 0x013c, 0x0138, 0x0133, 0x012e, 0x0124, 0x011c,
+- 0x010d, 0x0105, 0x0200, 0x0178, 0x0172, 0x016c, 0x0167, 0x0004,
+- 0x026c, 0x012c, 0x0128, 0x0126, 0x0120, 0x011a, 0x0111, 0x010a,
+- 0x0203, 0x017c, 0x0176, 0x0171, 0x016d, 0x0169, 0x0165, 0x0002,
+- 0x0409, 0x0118, 0x0116, 0x0112, 0x010b, 0x0108, 0x0103, 0x017e,
+- 0x017a, 0x0174, 0x016f, 0x016b, 0x0168, 0x0166, 0x0164, 0x0000,
+- 0x002b, 0x0014, 0x0013, 0x0011, 0x000f, 0x000d, 0x000b, 0x0009,
+- 0x0007, 0x0006, 0x0004, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
+-};
+-
+-static const uint8_t mpa_huffbits_24[256] = {
+-  4,  4,  6,  7,  8,  9,  9, 10,
+- 10, 11, 11, 11, 11, 11, 12,  9,
+-  4,  4,  5,  6,  7,  8,  8,  9,
+-  9,  9, 10, 10, 10, 10, 10,  8,
+-  6,  5,  6,  7,  7,  8,  8,  9,
+-  9,  9,  9, 10, 10, 10, 11,  7,
+-  7,  6,  7,  7,  8,  8,  8,  9,
+-  9,  9,  9, 10, 10, 10, 10,  7,
+-  8,  7,  7,  8,  8,  8,  8,  9,
+-  9,  9, 10, 10, 10, 10, 11,  7,
+-  9,  7,  8,  8,  8,  8,  9,  9,
+-  9,  9, 10, 10, 10, 10, 10,  7,
+-  9,  8,  8,  8,  8,  9,  9,  9,
+-  9, 10, 10, 10, 10, 10, 11,  7,
+- 10,  8,  8,  8,  9,  9,  9,  9,
+- 10, 10, 10, 10, 10, 11, 11,  8,
+- 10,  9,  9,  9,  9,  9,  9,  9,
+-  9, 10, 10, 10, 10, 11, 11,  8,
+- 10,  9,  9,  9,  9,  9,  9, 10,
+- 10, 10, 10, 10, 11, 11, 11,  8,
+- 11,  9,  9,  9,  9, 10, 10, 10,
+- 10, 10, 10, 11, 11, 11, 11,  8,
+- 11, 10,  9,  9,  9, 10, 10, 10,
+- 10, 10, 10, 11, 11, 11, 11,  8,
+- 11, 10, 10, 10, 10, 10, 10, 10,
+- 10, 10, 11, 11, 11, 11, 11,  8,
+- 11, 10, 10, 10, 10, 10, 10, 10,
+- 11, 11, 11, 11, 11, 11, 11,  8,
+- 12, 10, 10, 10, 10, 10, 10, 11,
+- 11, 11, 11, 11, 11, 11, 11,  8,
+-  8,  7,  7,  7,  7,  7,  7,  7,
+-  7,  7,  7,  8,  8,  8,  8,  4,
+-};
+-
+-static const HuffTable mpa_huff_tables[16] = {
+-{ 1, NULL, NULL },
+-{ 2, mpa_huffbits_1, mpa_huffcodes_1 },
+-{ 3, mpa_huffbits_2, mpa_huffcodes_2 },
+-{ 3, mpa_huffbits_3, mpa_huffcodes_3 },
+-{ 4, mpa_huffbits_5, mpa_huffcodes_5 },
+-{ 4, mpa_huffbits_6, mpa_huffcodes_6 },
+-{ 6, mpa_huffbits_7, mpa_huffcodes_7 },
+-{ 6, mpa_huffbits_8, mpa_huffcodes_8 },
+-{ 6, mpa_huffbits_9, mpa_huffcodes_9 },
+-{ 8, mpa_huffbits_10, mpa_huffcodes_10 },
+-{ 8, mpa_huffbits_11, mpa_huffcodes_11 },
+-{ 8, mpa_huffbits_12, mpa_huffcodes_12 },
+-{ 16, mpa_huffbits_13, mpa_huffcodes_13 },
+-{ 16, mpa_huffbits_15, mpa_huffcodes_15 },
+-{ 16, mpa_huffbits_16, mpa_huffcodes_16 },
+-{ 16, mpa_huffbits_24, mpa_huffcodes_24 },
+-};
+-
+-static const uint8_t mpa_huff_data[32][2] = {
+-{ 0, 0 },
+-{ 1, 0 },
+-{ 2, 0 },
+-{ 3, 0 },
+-{ 0, 0 },
+-{ 4, 0 },
+-{ 5, 0 },
+-{ 6, 0 },
+-{ 7, 0 },
+-{ 8, 0 },
+-{ 9, 0 },
+-{ 10, 0 },
+-{ 11, 0 },
+-{ 12, 0 },
+-{ 0, 0 },
+-{ 13, 0 },
+-{ 14, 1 },
+-{ 14, 2 },
+-{ 14, 3 },
+-{ 14, 4 },
+-{ 14, 6 },
+-{ 14, 8 },
+-{ 14, 10 },
+-{ 14, 13 },
+-{ 15, 4 },
+-{ 15, 5 },
+-{ 15, 6 },
+-{ 15, 7 },
+-{ 15, 8 },
+-{ 15, 9 },
+-{ 15, 11 },
+-{ 15, 13 },
+-};
+-
+-
+-/* huffman tables for quadrules */
+-static const uint8_t mpa_quad_codes[2][16] = {
+-    {  1,  5,  4,  5,  6,  5,  4,  4, 7,  3,  6,  0,  7,  2,  3,  1, },
+-    { 15, 14, 13, 12, 11, 10,  9,  8, 7,  6,  5,  4,  3,  2,  1,  0, },
+-};
+-
+-static const uint8_t mpa_quad_bits[2][16] = {
+-    { 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, },
+-    { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, },
+-};
+-
+-/* band size tables */
+-static const uint8_t band_size_long[9][22] = {
+-{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
+-  12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */
+-{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
+-  12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, }, /* 48000 */
+-{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
+-  16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, }, /* 32000 */
+-{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
+-  20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 22050 */
+-{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
+-  18, 22, 26, 32, 38, 46, 52, 64, 70, 76, 36, }, /* 24000 */
+-{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
+-  20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 16000 */
+-{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
+-  20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 11025 */
+-{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
+-  20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 12000 */
+-{ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
+-  40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */
+-};
+-
+-static const uint8_t band_size_short[9][13] = {
+-{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */
+-{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */
+-{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */
+-{ 4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18, }, /* 22050 */
+-{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12, }, /* 24000 */
+-{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 16000 */
+-{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 11025 */
+-{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 12000 */
+-{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */
+-};
+-
+-static const uint8_t mpa_pretab[2][22] = {
+-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 },
+-};
+-
+-/* table for alias reduction (XXX: store it as integer !) */
+-static const float ci_table[8] = {
+-    -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037,
+-};
+-
+-#endif /* AVCODEC_MPEGAUDIODECTAB_H */
+diff --git a/media/ffvpx/libavcodec/mpegaudiodsp.h b/media/ffvpx/libavcodec/mpegaudiodsp.h
+--- a/media/ffvpx/libavcodec/mpegaudiodsp.h
++++ b/media/ffvpx/libavcodec/mpegaudiodsp.h
+@@ -17,16 +17,17 @@
+  */
+ 
+ #ifndef AVCODEC_MPEGAUDIODSP_H
+ #define AVCODEC_MPEGAUDIODSP_H
+ 
+ #include <stddef.h>
+ #include <stdint.h>
+ 
++#include "libavutil/attributes_internal.h"
+ #include "libavutil/macros.h"
+ 
+ typedef struct MPADSPContext {
+     void (*apply_window_float)(float *synth_buf, float *window,
+                                int *dither_state, float *samples,
+                                ptrdiff_t incr);
+     void (*apply_window_fixed)(int32_t *synth_buf, int32_t *window,
+                                int *dither_state, int16_t *samples,
+@@ -35,16 +36,17 @@ typedef struct MPADSPContext {
+     void (*dct32_fixed)(int *dst, const int *src);
+ 
+     void (*imdct36_blocks_float)(float *out, float *buf, float *in,
+                                  int count, int switch_point, int block_type);
+     void (*imdct36_blocks_fixed)(int *out, int *buf, int *in,
+                                  int count, int switch_point, int block_type);
+ } MPADSPContext;
+ 
++FF_VISIBILITY_PUSH_HIDDEN
+ void ff_mpadsp_init(MPADSPContext *s);
+ 
+ extern int32_t ff_mpa_synth_window_fixed[];
+ extern float   ff_mpa_synth_window_float[];
+ 
+ extern const int32_t ff_mpa_enwindow[257];
+ 
+ void ff_mpa_synth_filter_fixed(MPADSPContext *s,
+@@ -83,10 +85,11 @@ void ff_imdct36_blocks_float(float *out,
+ void ff_imdct36_blocks_fixed(int *out, int *buf, int *in,
+                              int count, int switch_point, int block_type);
+ 
+ /** For SSE implementation, MDCT_BUF_SIZE/2 should be 128-bit aligned */
+ #define MDCT_BUF_SIZE FFALIGN(36, 2*4)
+ 
+ extern int ff_mdct_win_fixed[8][MDCT_BUF_SIZE];
+ extern float ff_mdct_win_float[8][MDCT_BUF_SIZE];
++FF_VISIBILITY_POP_HIDDEN
+ 
+ #endif /* AVCODEC_MPEGAUDIODSP_H */
+diff --git a/media/ffvpx/libavcodec/mpegvideodsp.h b/media/ffvpx/libavcodec/mpegvideodsp.h
+deleted file mode 100644
+--- a/media/ffvpx/libavcodec/mpegvideodsp.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/*
+- * 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
+- */
+-
+-#ifndef AVCODEC_MPEGVIDEODSP_H
+-#define AVCODEC_MPEGVIDEODSP_H
+-
+-#include <stdint.h>
+-
+-void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy,
+-              int dxx, int dxy, int dyx, int dyy, int shift, int r,
+-              int width, int height);
+-
+-typedef struct MpegVideoDSPContext {
+-    /**
+-     * translational global motion compensation.
+-     */
+-    void (*gmc1)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */,
+-                 int srcStride, int h, int x16, int y16, int rounder);
+-    /**
+-     * global motion compensation.
+-     */
+-    void (*gmc)(uint8_t *dst /* align 8 */, uint8_t *src /* align 1 */,
+-                int stride, int h, int ox, int oy,
+-                int dxx, int dxy, int dyx, int dyy,
+-                int shift, int r, int width, int height);
+-} MpegVideoDSPContext;
+-
+-void ff_mpegvideodsp_init(MpegVideoDSPContext *c);
+-void ff_mpegvideodsp_init_ppc(MpegVideoDSPContext *c);
+-void ff_mpegvideodsp_init_x86(MpegVideoDSPContext *c);
+-
+-#endif /* AVCODEC_MPEGVIDEODSP_H */
+diff --git a/media/ffvpx/libavcodec/options.c b/media/ffvpx/libavcodec/options.c
+--- a/media/ffvpx/libavcodec/options.c
++++ b/media/ffvpx/libavcodec/options.c
+@@ -22,16 +22,17 @@
+ /**
+  * @file
+  * Options definition for AVCodecContext.
+  */
+ 
+ #include "config_components.h"
+ 
+ #include "avcodec.h"
++#include "avcodec_internal.h"
+ #include "codec_internal.h"
+ #include "libavutil/avassert.h"
+ #include "libavutil/internal.h"
+ #include "libavutil/mem.h"
+ #include "libavutil/opt.h"
+ #include <string.h>
+ 
+ FF_DISABLE_DEPRECATION_WARNINGS
+@@ -119,21 +120,16 @@ static int init_context_defaults(AVCodec
+     s->execute             = avcodec_default_execute;
+     s->execute2            = avcodec_default_execute2;
+     s->sample_aspect_ratio = (AVRational){0,1};
+     s->ch_layout.order     = AV_CHANNEL_ORDER_UNSPEC;
+     s->pix_fmt             = AV_PIX_FMT_NONE;
+     s->sw_pix_fmt          = AV_PIX_FMT_NONE;
+     s->sample_fmt          = AV_SAMPLE_FMT_NONE;
+ 
+-#if FF_API_REORDERED_OPAQUE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    s->reordered_opaque    = AV_NOPTS_VALUE;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     if(codec && codec2->priv_data_size){
+         s->priv_data = av_mallocz(codec2->priv_data_size);
+         if (!s->priv_data)
+             return AVERROR(ENOMEM);
+         if(codec->priv_class){
+             *(const AVClass**)s->priv_data = codec->priv_class;
+             av_opt_set_defaults(s->priv_data);
+         }
+@@ -167,24 +163,27 @@ AVCodecContext *avcodec_alloc_context3(c
+ 
+ void avcodec_free_context(AVCodecContext **pavctx)
+ {
+     AVCodecContext *avctx = *pavctx;
+ 
+     if (!avctx)
+         return;
+ 
+-    avcodec_close(avctx);
++    ff_codec_close(avctx);
+ 
+     av_freep(&avctx->extradata);
+     av_freep(&avctx->subtitle_header);
+     av_freep(&avctx->intra_matrix);
++    av_freep(&avctx->chroma_intra_matrix);
+     av_freep(&avctx->inter_matrix);
+     av_freep(&avctx->rc_override);
+     av_channel_layout_uninit(&avctx->ch_layout);
++    av_frame_side_data_free(
++        &avctx->decoded_side_data, &avctx->nb_decoded_side_data);
+ 
+     av_freep(pavctx);
+ }
+ 
+ const AVClass *avcodec_get_class(void)
+ {
+     return &av_codec_context_class;
+ }
+@@ -192,17 +191,17 @@ const AVClass *avcodec_get_class(void)
+ #define SROFFSET(x) offsetof(AVSubtitleRect,x)
+ 
+ static const AVOption subtitle_rect_options[]={
+ {"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+ {"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+ {"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+ {"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+ {"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+-{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"},
++{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, .unit = "flags"},
+ {"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0},
+ {NULL},
+ };
+ 
+ static const AVClass av_subtitle_rect_class = {
+     .class_name             = "AVSubtitleRect",
+     .item_name              = NULL,
+     .option                 = subtitle_rect_options,
+diff --git a/media/ffvpx/libavcodec/options_table.h b/media/ffvpx/libavcodec/options_table.h
+--- a/media/ffvpx/libavcodec/options_table.h
++++ b/media/ffvpx/libavcodec/options_table.h
+@@ -37,379 +37,384 @@
+ //these names are too long to be readable
+ #define V AV_OPT_FLAG_VIDEO_PARAM
+ #define A AV_OPT_FLAG_AUDIO_PARAM
+ #define S AV_OPT_FLAG_SUBTITLE_PARAM
+ #define E AV_OPT_FLAG_ENCODING_PARAM
+ #define D AV_OPT_FLAG_DECODING_PARAM
+ #define CC AV_OPT_FLAG_CHILD_CONSTS
+ 
++#define AR AV_OPT_TYPE_FLAG_ARRAY
++
+ #define AV_CODEC_DEFAULT_BITRATE 200*1000
+ 
+ static const AVOption avcodec_options[] = {
+ {"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = AV_CODEC_DEFAULT_BITRATE }, 0, INT64_MAX, A|V|E},
+ {"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT64, {.i64 = 128*1000 }, 0, INT_MAX, A|E},
+ {"bt", "Set video bitrate tolerance (in bits/s). In 1-pass mode, bitrate tolerance specifies how far "
+        "ratecontrol is willing to deviate from the target average bitrate value. This is not related "
+        "to minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.",
+        OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 0, INT_MAX, A|V|E},
+-{"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, "flags"},
+-{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" },
+-{"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"},
+-{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
+-{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
+-{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, "flags"},
++{"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|S|E|D, .unit = "flags"},
++{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = AV_CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, .unit = "flags" },
++{"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, .unit = "flags"},
++{"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, .unit = "flags"},
++{"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, .unit = "flags"},
++{"qscale", "use fixed qscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_QSCALE }, INT_MIN, INT_MAX, 0, .unit = "flags"},
+ {"recon_frame", "export reconstructed frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_RECON_FRAME}, .unit = "flags"},
+ {"copy_opaque", "propagate opaque values", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_COPY_OPAQUE}, .unit = "flags"},
+ {"frame_duration", "use frame durations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_FRAME_DURATION}, .unit = "flags"},
+-{"pass1", "use internal 2-pass ratecontrol in first  pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, "flags"},
+-{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, "flags"},
+-{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, "flags"},
+-{"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, "flags"},
+-{"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, "flags"},
+-{"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, "flags"},
+-{"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"},
+-{"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"},
+-{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
+-{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
+-{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
+-{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"},
++{"pass1", "use internal 2-pass ratecontrol in first  pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS1 }, INT_MIN, INT_MAX, 0, .unit = "flags"},
++{"pass2", "use internal 2-pass ratecontrol in second pass mode", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PASS2 }, INT_MIN, INT_MAX, 0, .unit = "flags"},
++{"gray", "only decode/encode grayscale", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GRAY }, INT_MIN, INT_MAX, V|E|D, .unit = "flags"},
++{"psnr", "error[?] variables will be set during encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_PSNR }, INT_MIN, INT_MAX, V|E, .unit = "flags"},
++{"ildct", "use interlaced DCT", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_DCT }, INT_MIN, INT_MAX, V|E, .unit = "flags"},
++{"low_delay", "force low delay", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_LOW_DELAY }, INT_MIN, INT_MAX, V|D|E, .unit = "flags"},
++{"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, .unit = "flags"},
++{"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "flags"},
++{"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, .unit = "flags"},
++{"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, .unit = "flags"},
++{"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, .unit = "flags"},
++{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, .unit = "flags"},
+ #if FF_API_DROPCHANGED
+-{"drop_changed", "Drop frames whose parameters differ from first decoded frame", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_DROPCHANGED }, INT_MIN, INT_MAX, A|V|D | AV_OPT_FLAG_DEPRECATED, "flags"},
++{"drop_changed", "Drop frames whose parameters differ from first decoded frame", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG_DROPCHANGED }, INT_MIN, INT_MAX, A|V|D | AV_OPT_FLAG_DEPRECATED, .unit = "flags"},
+ #endif
+-{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D|S, "flags2"},
+-{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
+-{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
+-{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
+-{"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
+-{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"},
+-{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"},
+-{"export_mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, "flags2"},
+-{"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, A|D, "flags2"},
+-{"ass_ro_flush_noop", "do not reset ASS ReadOrder field on flush", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_RO_FLUSH_NOOP}, INT_MIN, INT_MAX, S|D, "flags2"},
+-{"icc_profiles", "generate/parse embedded ICC profiles from/to colorimetry tags", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_ICC_PROFILES}, INT_MIN, INT_MAX, S|D, "flags2"},
+-{"export_side_data", "Export metadata as side data", OFFSET(export_side_data), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, A|V|S|D|E, "export_side_data"},
+-{"mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_MVS}, INT_MIN, INT_MAX, V|D, "export_side_data"},
+-{"prft", "export Producer Reference Time through packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_PRFT}, INT_MIN, INT_MAX, A|V|S|E, "export_side_data"},
+-{"venc_params", "export video encoding parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS}, INT_MIN, INT_MAX, V|D, "export_side_data"},
+-{"film_grain", "export film grain parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_FILM_GRAIN}, INT_MIN, INT_MAX, V|D, "export_side_data"},
++{"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D|S, .unit = "flags2"},
++{"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, .unit = "flags2"},
++{"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, .unit = "flags2"},
++{"ignorecrop", "ignore cropping information from sps", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, .unit = "flags2"},
++{"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, .unit = "flags2"},
++{"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, .unit = "flags2"},
++{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, .unit = "flags2"},
++{"export_mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_EXPORT_MVS}, INT_MIN, INT_MAX, V|D, .unit = "flags2"},
++{"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, A|D, .unit = "flags2"},
++{"ass_ro_flush_noop", "do not reset ASS ReadOrder field on flush", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_RO_FLUSH_NOOP}, INT_MIN, INT_MAX, S|D, .unit = "flags2"},
++{"icc_profiles", "generate/parse embedded ICC profiles from/to colorimetry tags", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_ICC_PROFILES}, INT_MIN, INT_MAX, S|D, .unit = "flags2"},
++{"export_side_data", "Export metadata as side data", OFFSET(export_side_data), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, A|V|S|D|E, .unit = "export_side_data"},
++{"mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_MVS}, INT_MIN, INT_MAX, V|D, .unit = "export_side_data"},
++{"prft", "export Producer Reference Time through packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_PRFT}, INT_MIN, INT_MAX, A|V|S|E, .unit = "export_side_data"},
++{"venc_params", "export video encoding parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS}, INT_MIN, INT_MAX, V|D, .unit = "export_side_data"},
++{"film_grain", "export film grain parameters through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_FILM_GRAIN}, INT_MIN, INT_MAX, V|D, .unit = "export_side_data"},
+ {"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, INT_MAX},
+ {"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
+ {"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E},
+-#endif
+ {"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E},
+ {"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|E},
+ {"frame_number", NULL, OFFSET(frame_num), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+ {"delay", NULL, OFFSET(delay), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+ {"qcomp", "video quantizer scale compression (VBR). Constant of ratecontrol equation. "
+           "Recommended range for default rc_eq: 0.0-1.0",
+           OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E},
+ {"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E},
+ {"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E},
+ {"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 1024, V|E},
+ {"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E},
+ {"bf", "set maximum number of B-frames between non-B-frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, V|E},
+ {"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
+ {"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+-{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"},
+-{"iedge", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_IEDGE }, INT_MIN, INT_MAX, V|D, "bug"},
+-{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
+-{"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
+-{"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
+-{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
+-{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
+-{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
++{"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"direct_blocksize", "direct-qpel-blocksize bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DIRECT_BLOCKSIZE }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"edge", "edge padding bug (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_EDGE }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"hpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_HPEL_CHROMA }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"iedge", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_IEDGE }, INT_MIN, INT_MAX, V|D, .unit = "bug"},
++{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, .unit = "strict"},
++{"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, A|V|D|E, .unit = "strict"},
++{"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, A|V|D|E, .unit = "strict"},
++{"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, A|V|D|E, .unit = "strict"},
++{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, A|V|D|E, .unit = "strict"},
++{"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, A|V|D|E, .unit = "strict"},
+ {"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
+-{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
+-{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
+-{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
+-{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
+-{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
+-{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
+-{"careful",    "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
+-{"compliant",  "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT | AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
+-{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE | AV_EF_COMPLIANT | AV_EF_CAREFUL}, INT_MIN, INT_MAX, A|V|S|D|E, "err_detect"},
++{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
++{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
++{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
++{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
++{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
++{"ignore_err", "ignore errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_IGNORE_ERR }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
++{"careful",    "consider things that violate the spec, are fast to check and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
++{"compliant",  "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT | AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
++{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE | AV_EF_COMPLIANT | AV_EF_CAREFUL}, INT_MIN, INT_MAX, A|V|S|D|E, .unit = "err_detect"},
+ {"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX},
+ {"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX},
+ {"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+ {"maxrate", "maximum bitrate (in bits/s). Used for VBV together with bufsize.", OFFSET(rc_max_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT_MAX, V|A|E},
+ {"minrate", "minimum bitrate (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise.",
+             OFFSET(rc_min_rate), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
+ {"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|E},
+ {"i_qfactor", "QP factor between P- and I-frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E},
+ {"i_qoffset", "QP offset between P- and I-frames", OFFSET(i_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 0.0 }, -FLT_MAX, FLT_MAX, V|E},
+-{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"},
+-{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"},
+-{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"},
++{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, .unit = "dct"},
++{"auto", "autoselect a good one", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"fastint", "fast integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
++{"faan", "floating point AAN DCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, .unit = "dct"},
+ {"lumi_mask", "compresses bright areas stronger than medium ones", OFFSET(lumi_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+ {"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+ {"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+ {"p_mask", "inter masking", OFFSET(p_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+ {"dark_mask", "compresses dark areas stronger than medium ones", OFFSET(dark_masking), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, -FLT_MAX, FLT_MAX, V|E},
+-{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"},
+-{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"xvid", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"xvidmmx", "deprecated, for compatibility only", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
+-{"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"},
+-#if FF_API_SLICE_OFFSET
+-{"slice_count", NULL, OFFSET(slice_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+-#endif
+-{"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 = 3 }, INT_MIN, INT_MAX, V|D, "ec"},
+-{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, "ec"},
+-{"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, "ec"},
+-{"favor_inter", "favor predicting from the previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, "ec"},
++{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, .unit = "idct"},
++{"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simplearm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"xvid", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"xvidmmx", "deprecated, for compatibility only", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVID }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, .unit = "idct"},
++{"simpleauto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, .unit = "idct"},
++{"ec", "set error concealment strategy", OFFSET(error_concealment), AV_OPT_TYPE_FLAGS, {.i64 = 3 }, INT_MIN, INT_MAX, V|D, .unit = "ec"},
++{"guess_mvs", "iterative motion vector (MV) search (slow)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_GUESS_MVS }, INT_MIN, INT_MAX, V|D, .unit = "ec"},
++{"deblock", "use strong deblock filter for damaged MBs", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_DEBLOCK }, INT_MIN, INT_MAX, V|D, .unit = "ec"},
++{"favor_inter", "favor predicting from the previous frame", 0, AV_OPT_TYPE_CONST, {.i64 = FF_EC_FAVOR_INTER }, INT_MIN, INT_MAX, V|D, .unit = "ec"},
+ {"bits_per_coded_sample", NULL, OFFSET(bits_per_coded_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX},
+ {"aspect", "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
+ {"sar",    "sample aspect ratio", OFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, 0, 10, V|E},
+-{"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, "debug"},
+-{"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, "debug"},
+-{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
+-{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"},
+-{"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, "debug"},
++{"debug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, V|A|S|E|D, .unit = "debug"},
++{"pict", "picture info", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_PICT_INFO }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"rc", "rate control", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_RC }, INT_MIN, INT_MAX, V|E, .unit = "debug"},
++{"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"green_metadata", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_GREEN_MD }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, .unit = "debug"},
++{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, .unit = "debug"},
++{"nomc", "skip motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_NOMC }, INT_MIN, INT_MAX, V|A|D, .unit = "debug"},
+ {"dia_size", "diamond type & size for motion estimation", OFFSET(dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+ {"last_pred", "amount of motion predictors from the previous frame", OFFSET(last_predictor_count), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+ {"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+ {"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
+ {"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+ {"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
+ {"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+-{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, "mbd"},
+-{"simple", "use mbcmp", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
+-{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
+-{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, "mbd"},
++{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, 2, V|E, .unit = "mbd"},
++{"simple", "use mbcmp", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, .unit = "mbd"},
++{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, .unit = "mbd"},
++{"rd", "use best rate distortion", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_RD }, INT_MIN, INT_MAX, V|E, .unit = "mbd"},
+ {"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
+-{"threads", "set the number of threads", OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"},
+-{"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
++{"threads", "set the number of threads", OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, .unit = "threads"},
++{"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, .unit = "threads"},
+ {"dc", "intra_dc_precision", OFFSET(intra_dc_precision), AV_OPT_TYPE_INT, {.i64 = 0 }, -8, 16, V|E},
+ {"nssew", "nsse weight", OFFSET(nsse_weight), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
+ {"skip_top", "number of macroblock rows at the top which are skipped", OFFSET(skip_top), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D},
+ {"skip_bottom", "number of macroblock rows at the bottom which are skipped", OFFSET(skip_bottom), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|D},
+-{"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = AV_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, "avctx.profile"},
+-{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "avctx.profile"},
+-{"main10",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, V|E, "avctx.profile"},
+-{"level", "encoding level, usually corresponding to the profile level, codec-specific", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, "avctx.level"},
+-{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "avctx.level"},
++{"profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = AV_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, .unit = "avctx.profile"},
++{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, .unit = "avctx.profile"},
++{"main10",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_PROFILE_HEVC_MAIN_10 }, INT_MIN, INT_MAX, V|E, .unit = "avctx.profile"},
++{"level", "encoding level, usually corresponding to the profile level, codec-specific", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E|CC, .unit = "avctx.level"},
++{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, .unit = "avctx.level"},
+ {"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D},
+-{"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"sad", "sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"bit", "number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"zero", "0", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
++{"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"ildctcmp", "interlaced DCT compare function", OFFSET(ildct_cmp), AV_OPT_TYPE_INT, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"sad", "sum of absolute differences, fast", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SAD }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"sse", "sum of squared errors", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SSE }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"satd", "sum of absolute Hadamard transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_SATD }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"dct", "sum of absolute DCT transformed differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"psnr", "sum of squared quantization errors (avoid, low quality)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_PSNR }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"bit", "number of bits needed for the block", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_BIT }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"rd", "rate distortion optimal, slow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_RD }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"zero", "0", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_ZERO }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
+ #if CONFIG_SNOW_ENCODER
+-{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
++{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
+ #endif
+-{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+-{"msad", "sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
++{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
++{"msad", "sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, V|E, .unit = "cmp_func"},
+ {"mblmin", "minimum macroblock Lagrange factor (VBR)", OFFSET(mb_lmin), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 2 }, 1, FF_LAMBDA_MAX, V|E},
+ {"mblmax", "maximum macroblock Lagrange factor (VBR)", OFFSET(mb_lmax), AV_OPT_TYPE_INT, {.i64 = FF_QP2LAMBDA * 31 }, 1, FF_LAMBDA_MAX, V|E},
+-{"skip_loop_filter", "skip loop filtering process for the selected frames", OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"skip_idct"       , "skip IDCT/dequantization for the selected frames",    OFFSET(skip_idct),        AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"skip_frame"      , "skip decoding for the selected frames",               OFFSET(skip_frame),       AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"none"            , "discard no frame",                    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE    }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"default"         , "discard useless frames",              0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"noref"           , "discard all non-reference frames",    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF  }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"bidir"           , "discard all bidirectional frames",    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR   }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"nointra"         , "discard all frames except I frames",  0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"nokey"           , "discard all frames except keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY  }, INT_MIN, INT_MAX, V|D, "avdiscard"},
+-{"all"             , "discard all frames",                  0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL     }, INT_MIN, INT_MAX, V|D, "avdiscard"},
++{"skip_loop_filter", "skip loop filtering process for the selected frames", OFFSET(skip_loop_filter), AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"skip_idct"       , "skip IDCT/dequantization for the selected frames",    OFFSET(skip_idct),        AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"skip_frame"      , "skip decoding for the selected frames",               OFFSET(skip_frame),       AV_OPT_TYPE_INT, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"none"            , "discard no frame",                    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONE    }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"default"         , "discard useless frames",              0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_DEFAULT }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"noref"           , "discard all non-reference frames",    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONREF  }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"bidir"           , "discard all bidirectional frames",    0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_BIDIR   }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"nointra"         , "discard all frames except I frames",  0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONINTRA}, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"nokey"           , "discard all frames except keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_NONKEY  }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
++{"all"             , "discard all frames",                  0, AV_OPT_TYPE_CONST, {.i64 = AVDISCARD_ALL     }, INT_MIN, INT_MAX, V|D, .unit = "avdiscard"},
+ {"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, 4, V|E},
+ {"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, V|E},
+ {"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.i64 = 1 }, INT_MIN, INT_MAX, V|E},
+ {"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
+ {"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E},
+ {"compression_level", NULL, OFFSET(compression_level), AV_OPT_TYPE_INT, {.i64 = FF_COMPRESSION_DEFAULT }, INT_MIN, INT_MAX, V|A|E},
+ {"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX},
+-{"ch_layout", NULL, OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL }, 0, 0, A|E|D, "ch_layout"},
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = DEFAULT }, 0, UINT64_MAX, A|E|D, "channel_layout"},
+-{"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = DEFAULT }, 0, UINT64_MAX, A|D, "request_channel_layout"},
+-#endif
++{"ch_layout", NULL, OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL }, 0, 0, A|E|D, .unit = "ch_layout"},
+ {"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E},
+ {"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use),  AV_OPT_TYPE_FLOAT, {.dbl = 3 },     0.0, FLT_MAX, V|E},
+ #if FF_API_TICKS_PER_FRAME
+ {"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D},
+ #endif
+-{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_primaries_type"},
+-{"bt709",       "BT.709",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 },        INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"unknown",     "Unspecified",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"bt470m",      "BT.470 M",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M },       INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"bt470bg",     "BT.470 BG",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG },      INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"smpte170m",   "SMPTE 170 M",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M },    INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"smpte240m",   "SMPTE 240 M",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE240M },    INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"film",        "Film",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_FILM },         INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"bt2020",      "BT.2020",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020 },       INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"smpte428",    "SMPTE 428-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 },     INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"smpte428_1",  "SMPTE 428-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 },     INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"smpte431",    "SMPTE 431-2",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE431 },     INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"smpte432",    "SMPTE 422-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE432 },     INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"jedec-p22",   "JEDEC P22",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_JEDEC_P22 },    INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"ebu3213",     "EBU 3213-E",     0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_EBU3213 },      INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"unspecified", "Unspecified",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, "color_primaries_type"},
+-{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, INT_MAX, V|E|D, "color_trc_type"},
+-{"bt709",        "BT.709",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 },        INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"unknown",      "Unspecified",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"gamma22",      "BT.470 M",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 },      INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"gamma28",      "BT.470 BG",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 },      INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"smpte170m",    "SMPTE 170 M",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"smpte240m",    "SMPTE 240 M",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"linear",       "Linear",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR },       INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"log100",       "Log",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG },          INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"log316",       "Log square root",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT },     INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"iec61966-2-4", "IEC 61966-2-4",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"bt1361e",      "BT.1361",          0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG },   INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"iec61966-2-1", "IEC 61966-2-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"bt2020-10",    "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"bt2020-12",    "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"smpte2084",    "SMPTE 2084",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE2084 },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"smpte428",     "SMPTE 428-1",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 },     INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"arib-std-b67", "ARIB STD-B67",     0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_ARIB_STD_B67 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"unspecified",  "Unspecified",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"log",          "Log",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG },          INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"log_sqrt",     "Log square root",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT },     INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"iec61966_2_4", "IEC 61966-2-4",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"bt1361",       "BT.1361",          0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG },   INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"iec61966_2_1", "IEC 61966-2-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"bt2020_10bit", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 },    INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"smpte428_1",   "SMPTE 428-1",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 },     INT_MIN, INT_MAX, V|E|D, "color_trc_type"},
+-{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "colorspace_type"},
+-{"rgb",               "RGB",                0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB },                INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"bt709",             "BT.709",             0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 },              INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"unknown",           "Unspecified",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED },        INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"fcc",               "FCC",                0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC },                INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"bt470bg",           "BT.470 BG",          0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG },            INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"smpte170m",         "SMPTE 170 M",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M },          INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"smpte240m",         "SMPTE 240 M",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M },          INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"ycgco",             "YCGCO",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO },              INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"bt2020nc",          "BT.2020 NCL",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL },         INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"bt2020c",           "BT.2020 CL",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL },          INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"smpte2085",         "SMPTE 2085",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 },          INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"chroma-derived-nc", "Chroma-derived NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_CHROMA_DERIVED_NCL }, INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"chroma-derived-c",  "Chroma-derived CL",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_CHROMA_DERIVED_CL },  INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"ictcp",             "ICtCp",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_ICTCP },              INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"unspecified",       "Unspecified",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED },        INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"ycocg",             "YCGCO",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO },              INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"bt2020_ncl",        "BT.2020 NCL",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL },         INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"bt2020_cl",         "BT.2020 CL",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL },          INT_MIN, INT_MAX, V|E|D, "colorspace_type"},
+-{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, "color_range_type"},
+-{"unknown", "Unspecified",     0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
+-{"tv", "MPEG (219*2^(n-8))",   0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG },        INT_MIN, INT_MAX, V|E|D, "color_range_type"},
+-{"pc", "JPEG (2^n-1)",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG },        INT_MIN, INT_MAX, V|E|D, "color_range_type"},
+-{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "color_range_type"},
+-{"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG },        INT_MIN, INT_MAX, V|E|D, "color_range_type"},
+-{"jpeg", "JPEG (2^n-1)",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG },        INT_MIN, INT_MAX, V|E|D, "color_range_type"},
+-{"limited", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG },     INT_MIN, INT_MAX, V|E|D, "color_range_type"},
+-{"full", "JPEG (2^n-1)",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG },        INT_MIN, INT_MAX, V|E|D, "color_range_type"},
+-{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX, V|E|D, "chroma_sample_location_type"},
+-{"unknown",     "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+-{"left",        "Left",        0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT },        INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+-{"center",      "Center",      0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER },      INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+-{"topleft",     "Top-left",    0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOPLEFT },     INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+-{"top",         "Top",         0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOP },         INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+-{"bottomleft",  "Bottom-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOMLEFT },  INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+-{"bottom",      "Bottom",      0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOM },      INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
+-{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, "chroma_sample_location_type"},
++{"color_primaries", "color primaries", OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"bt709",       "BT.709",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT709 },        INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"unknown",     "Unspecified",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"bt470m",      "BT.470 M",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470M },       INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"bt470bg",     "BT.470 BG",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT470BG },      INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"smpte170m",   "SMPTE 170 M",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE170M },    INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"smpte240m",   "SMPTE 240 M",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE240M },    INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"film",        "Film",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_FILM },         INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"bt2020",      "BT.2020",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_BT2020 },       INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"smpte428",    "SMPTE 428-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 },     INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"smpte428_1",  "SMPTE 428-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE428 },     INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"smpte431",    "SMPTE 431-2",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE431 },     INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"smpte432",    "SMPTE 422-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_SMPTE432 },     INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"jedec-p22",   "JEDEC P22",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_JEDEC_P22 },    INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"ebu3213",     "EBU 3213-E",     0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_EBU3213 },      INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"unspecified", "Unspecified",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_PRI_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, .unit = "color_primaries_type"},
++{"color_trc", "color transfer characteristics", OFFSET(color_trc), AV_OPT_TYPE_INT, {.i64 = AVCOL_TRC_UNSPECIFIED }, 1, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"bt709",        "BT.709",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT709 },        INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"unknown",      "Unspecified",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"gamma22",      "BT.470 M",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA22 },      INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"gamma28",      "BT.470 BG",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_GAMMA28 },      INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"smpte170m",    "SMPTE 170 M",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE170M },    INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"smpte240m",    "SMPTE 240 M",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE240M },    INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"linear",       "Linear",           0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LINEAR },       INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"log100",       "Log",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG },          INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"log316",       "Log square root",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT },     INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"iec61966-2-4", "IEC 61966-2-4",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"bt1361e",      "BT.1361",          0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG },   INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"iec61966-2-1", "IEC 61966-2-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"bt2020-10",    "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 },    INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"bt2020-12",    "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 },    INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"smpte2084",    "SMPTE 2084",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE2084 },    INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"smpte428",     "SMPTE 428-1",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 },     INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"arib-std-b67", "ARIB STD-B67",     0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_ARIB_STD_B67 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"unspecified",  "Unspecified",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_UNSPECIFIED },  INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"log",          "Log",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG },          INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"log_sqrt",     "Log square root",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_LOG_SQRT },     INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"iec61966_2_4", "IEC 61966-2-4",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_4 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"bt1361",       "BT.1361",          0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT1361_ECG },   INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"iec61966_2_1", "IEC 61966-2-1",    0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_IEC61966_2_1 }, INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"bt2020_10bit", "BT.2020 - 10 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_10 },    INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"bt2020_12bit", "BT.2020 - 12 bit", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_BT2020_12 },    INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"smpte428_1",   "SMPTE 428-1",      0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTE428 },     INT_MIN, INT_MAX, V|E|D, .unit = "color_trc_type"},
++{"colorspace", "color space", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"rgb",               "RGB",                0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_RGB },                INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"bt709",             "BT.709",             0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT709 },              INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"unknown",           "Unspecified",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED },        INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"fcc",               "FCC",                0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_FCC },                INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"bt470bg",           "BT.470 BG",          0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT470BG },            INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"smpte170m",         "SMPTE 170 M",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE170M },          INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"smpte240m",         "SMPTE 240 M",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE240M },          INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"ycgco",             "YCGCO",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO },              INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"bt2020nc",          "BT.2020 NCL",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL },         INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"bt2020c",           "BT.2020 CL",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL },          INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"smpte2085",         "SMPTE 2085",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_SMPTE2085 },          INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"chroma-derived-nc", "Chroma-derived NCL", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_CHROMA_DERIVED_NCL }, INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"chroma-derived-c",  "Chroma-derived CL",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_CHROMA_DERIVED_CL },  INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"ictcp",             "ICtCp",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_ICTCP },              INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"ipt-c2",            "IPT-C2",             0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_IPT_C2 },             INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"unspecified",       "Unspecified",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_UNSPECIFIED },        INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"ycocg",             "YCGCO",              0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO },              INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"ycgco-re",          "YCgCo-R, even add.", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO_RE },           INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"ycgco-ro",          "YCgCo-R, odd add.",  0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_YCGCO_RO },           INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"bt2020_ncl",        "BT.2020 NCL",        0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_NCL },         INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"bt2020_cl",         "BT.2020 CL",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_SPC_BT2020_CL },          INT_MIN, INT_MAX, V|E|D, .unit = "colorspace_type"},
++{"color_range", "color range", OFFSET(color_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"unknown", "Unspecified",     0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"tv", "MPEG (219*2^(n-8))",   0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG },        INT_MIN, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"pc", "JPEG (2^n-1)",         0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG },        INT_MIN, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"mpeg", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG },        INT_MIN, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"jpeg", "JPEG (2^n-1)",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG },        INT_MIN, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"limited", "MPEG (219*2^(n-8))", 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG },     INT_MIN, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"full", "JPEG (2^n-1)",       0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG },        INT_MIN, INT_MAX, V|E|D, .unit = "color_range_type"},
++{"chroma_sample_location", "chroma sample location", OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
++{"unknown",     "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
++{"left",        "Left",        0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_LEFT },        INT_MIN, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
++{"center",      "Center",      0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_CENTER },      INT_MIN, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
++{"topleft",     "Top-left",    0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOPLEFT },     INT_MIN, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
++{"top",         "Top",         0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_TOP },         INT_MIN, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
++{"bottomleft",  "Bottom-left", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOMLEFT },  INT_MIN, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
++{"bottom",      "Bottom",      0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_BOTTOM },      INT_MIN, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
++{"unspecified", "Unspecified", 0, AV_OPT_TYPE_CONST, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, INT_MIN, INT_MAX, V|E|D, .unit = "chroma_sample_location_type"},
+ {"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX },
+ {"slices", "set the number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E},
+-{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"},
+-{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
+-{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
+-{"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"},
+-{"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN },              INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"ef", "Effects",            0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EFFECTS },           INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"vi", "Visually Impaired",  0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"hi", "Hearing Impaired",   0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED },  INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"di", "Dialogue",           0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_DIALOGUE },          INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"co", "Commentary",         0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_COMMENTARY },        INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"em", "Emergency",          0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY },         INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"vo", "Voice Over",         0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER },        INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"ka", "Karaoke",            0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE },           INT_MIN, INT_MAX, A|E, "audio_service_type"},
+-{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, "request_sample_fmt"},
++{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, .unit = "thread_type"},
++{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, .unit = "thread_type"},
++{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, .unit = "thread_type"},
++{"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, .unit = "audio_service_type"},
++{"ma", "Main Audio Service", 0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN },              INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"ef", "Effects",            0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EFFECTS },           INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"vi", "Visually Impaired",  0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED }, INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"hi", "Hearing Impaired",   0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED },  INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"di", "Dialogue",           0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_DIALOGUE },          INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"co", "Commentary",         0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_COMMENTARY },        INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"em", "Emergency",          0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY },         INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"vo", "Voice Over",         0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER },        INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"ka", "Karaoke",            0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_KARAOKE },           INT_MIN, INT_MAX, A|E, .unit = "audio_service_type"},
++{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|D, .unit = "request_sample_fmt"},
+ {"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
+ {"sub_charenc", "set input text subtitles character encoding", OFFSET(sub_charenc), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, S|D},
+-{"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, "sub_charenc_mode"},
+-{"do_nothing",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING},  INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
+-{"auto",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC},   INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
+-{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
+-{"ignore",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_IGNORE},      INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
++{"sub_charenc_mode", "set input text subtitles character encoding mode", OFFSET(sub_charenc_mode), AV_OPT_TYPE_FLAGS, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, -1, INT_MAX, S|D, .unit = "sub_charenc_mode"},
++{"do_nothing",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING},  INT_MIN, INT_MAX, S|D, .unit = "sub_charenc_mode"},
++{"auto",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC},   INT_MIN, INT_MAX, S|D, .unit = "sub_charenc_mode"},
++{"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, .unit = "sub_charenc_mode"},
++{"ignore",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_IGNORE},      INT_MIN, INT_MAX, S|D, .unit = "sub_charenc_mode"},
+ {"apply_cropping", NULL, OFFSET(apply_cropping), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, V | D },
+ {"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, V|D },
+-{"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, "field_order" },
+-{"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, "field_order" },
+-{"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, "field_order" },
+-{"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, "field_order" },
+-{"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" },
+-{"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" },
++{"field_order", "Field order", OFFSET(field_order), AV_OPT_TYPE_INT, {.i64 = AV_FIELD_UNKNOWN }, 0, 5, V|D|E, .unit = "field_order" },
++{"progressive", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_PROGRESSIVE }, 0, 0, V|D|E, .unit = "field_order" },
++{"tt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TT }, 0, 0, V|D|E, .unit = "field_order" },
++{"bb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BB }, 0, 0, V|D|E, .unit = "field_order" },
++{"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, .unit = "field_order" },
++{"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, .unit = "field_order" },
+ {"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, A|V|S|D|E},
+ {"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL },  0, 0, A|V|S|D },
+ {"pixel_format", "set pixel format", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64=AV_PIX_FMT_NONE}, -1, INT_MAX, 0 },
+ {"video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str=NULL}, 0, INT_MAX, 0 },
+ {"max_pixels", "Maximum number of pixels", OFFSET(max_pixels), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|V|S|D|E },
+ {"max_samples", "Maximum number of samples", OFFSET(max_samples), AV_OPT_TYPE_INT64, {.i64 = INT_MAX }, 0, INT_MAX, A|D|E },
+-{"hwaccel_flags", NULL, OFFSET(hwaccel_flags), AV_OPT_TYPE_FLAGS, {.i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, 0, UINT_MAX, V|D, "hwaccel_flags"},
+-{"ignore_level", "ignore level even if the codec level used is unknown or higher than the maximum supported level reported by the hardware driver", 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, INT_MIN, INT_MAX, V | D, "hwaccel_flags" },
+-{"allow_high_depth", "allow to output YUV pixel formats with a different chroma sampling than 4:2:0 and/or other than 8 bits per component", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"},
+-{"allow_profile_mismatch", "attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"},
+-{"unsafe_output", "allow potentially unsafe hwaccel frame output that might require special care to process successfully", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_UNSAFE_OUTPUT }, INT_MIN, INT_MAX, V | D, "hwaccel_flags"},
++{"hwaccel_flags", NULL, OFFSET(hwaccel_flags), AV_OPT_TYPE_FLAGS, {.i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, 0, UINT_MAX, V|D, .unit = "hwaccel_flags"},
++{"ignore_level", "ignore level even if the codec level used is unknown or higher than the maximum supported level reported by the hardware driver", 0, AV_OPT_TYPE_CONST, { .i64 = AV_HWACCEL_FLAG_IGNORE_LEVEL }, INT_MIN, INT_MAX, V | D, .unit = "hwaccel_flags" },
++{"allow_high_depth", "allow to output YUV pixel formats with a different chroma sampling than 4:2:0 and/or other than 8 bits per component", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, INT_MAX, V | D, .unit = "hwaccel_flags"},
++{"allow_profile_mismatch", "attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, INT_MAX, V | D, .unit = "hwaccel_flags"},
++{"unsafe_output", "allow potentially unsafe hwaccel frame output that might require special care to process successfully", 0, AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_UNSAFE_OUTPUT }, INT_MIN, INT_MAX, V | D, .unit = "hwaccel_flags"},
+ {"extra_hw_frames", "Number of extra hardware frames to allocate for the user", OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, V|D },
+ {"discard_damaged_percentage", "Percentage of damaged samples to discard a frame", OFFSET(discard_damaged_percentage), AV_OPT_TYPE_INT, {.i64 = 95 }, 0, 100, V|D },
++{"side_data_prefer_packet", "Comma-separated list of side data types for which user-supplied (container) data is preferred over coded bytestream",
++    OFFSET(side_data_prefer_packet), AV_OPT_TYPE_INT | AR, .min = -1, .max = INT_MAX, .flags = V|A|S|D, .unit = "side_data_pkt" },
++    {"replaygain",                  .default_val.i64 = AV_PKT_DATA_REPLAYGAIN,                  .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
++    {"displaymatrix",               .default_val.i64 = AV_PKT_DATA_DISPLAYMATRIX,               .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
++    {"spherical",                   .default_val.i64 = AV_PKT_DATA_SPHERICAL,                   .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
++    {"stereo3d",                    .default_val.i64 = AV_PKT_DATA_STEREO3D,                    .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
++    {"audio_service_type",          .default_val.i64 = AV_PKT_DATA_AUDIO_SERVICE_TYPE,          .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
++    {"mastering_display_metadata",  .default_val.i64 = AV_PKT_DATA_MASTERING_DISPLAY_METADATA,  .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
++    {"content_light_level",         .default_val.i64 = AV_PKT_DATA_CONTENT_LIGHT_LEVEL,         .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
++    {"icc_profile",                 .default_val.i64 = AV_PKT_DATA_ICC_PROFILE,                 .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
+ {NULL},
+ };
+ 
+ #undef A
+ #undef V
+ #undef S
+ #undef E
+ #undef D
+diff --git a/media/ffvpx/libavcodec/avpacket.c b/media/ffvpx/libavcodec/packet.c
+rename from media/ffvpx/libavcodec/avpacket.c
+rename to media/ffvpx/libavcodec/packet.c
+--- a/media/ffvpx/libavcodec/avpacket.c
++++ b/media/ffvpx/libavcodec/packet.c
+@@ -296,16 +296,17 @@ const char *av_packet_side_data_name(enu
+     case AV_PKT_DATA_ENCRYPTION_INIT_INFO:       return "Encryption initialization data";
+     case AV_PKT_DATA_ENCRYPTION_INFO:            return "Encryption info";
+     case AV_PKT_DATA_AFD:                        return "Active Format Description data";
+     case AV_PKT_DATA_PRFT:                       return "Producer Reference Time";
+     case AV_PKT_DATA_ICC_PROFILE:                return "ICC Profile";
+     case AV_PKT_DATA_DOVI_CONF:                  return "DOVI configuration record";
+     case AV_PKT_DATA_S12M_TIMECODE:              return "SMPTE ST 12-1:2014 timecode";
+     case AV_PKT_DATA_DYNAMIC_HDR10_PLUS:         return "HDR10+ Dynamic Metadata (SMPTE 2094-40)";
++    case AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT:return "Ambient viewing environment";
+     case AV_PKT_DATA_IAMF_MIX_GAIN_PARAM:        return "IAMF Mix Gain Parameter Data";
+     case AV_PKT_DATA_IAMF_DEMIXING_INFO_PARAM:   return "IAMF Demixing Info Parameter Data";
+     case AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM: return "IAMF Recon Gain Info Parameter Data";
+     }
+     return NULL;
+ }
+ 
+ uint8_t *av_packet_pack_dictionary(AVDictionary *dict, size_t *size)
+diff --git a/media/ffvpx/libavcodec/packet.h b/media/ffvpx/libavcodec/packet.h
+--- a/media/ffvpx/libavcodec/packet.h
++++ b/media/ffvpx/libavcodec/packet.h
+@@ -319,27 +319,36 @@ enum AVPacketSideDataType {
+      * IAMF Recon Gain Info Parameter Data associated with the audio frame. This
+      * metadata is in the form of the AVIAMFParamDefinition struct and contains
+      * information defined in sections 3.6.1 and 3.8.3 of the Immersive Audio Model
+      * and Formats standard.
+      */
+     AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM,
+ 
+     /**
++     * Ambient viewing environment metadata, as defined by H.274. This metadata
++     * should be associated with a video stream and contains data in the form
++     * of the AVAmbientViewingEnvironment struct.
++    */
++    AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT,
++
++    /**
+      * The number of side data types.
+      * This is not part of the public API/ABI in the sense that it may
+      * change when new side data types are added.
+      * This must stay the last enum value.
+      * If its value becomes huge, some code using it
+      * needs to be updated as it assumes it to be smaller than other limits.
+      */
+     AV_PKT_DATA_NB
+ };
+ 
++#if FF_API_QUALITY_FACTOR
+ #define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED
++#endif
+ 
+ /**
+  * This structure stores auxiliary information for decoding, presenting, or
+  * otherwise processing the coded stream. It is typically exported by demuxers
+  * and encoders and can be fed to decoders and muxers either in a per packet
+  * basis, or as global side data (applying to the entire coded stream).
+  *
+  * Global side data is handled as follows:
+@@ -584,23 +593,16 @@ typedef struct AVPacketList {
+ #define AV_PKT_FLAG_TRUSTED   0x0008
+ /**
+  * Flag is used to indicate packets that contain frames that can
+  * be discarded by the decoder.  I.e. Non-reference frames.
+  */
+ #define AV_PKT_FLAG_DISPOSABLE 0x0010
+ 
+ enum AVSideDataParamChangeFlags {
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-    /**
+-     * @deprecated those are not used by any decoder
+-     */
+-    AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT  = 0x0001,
+-    AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
+-#endif
+     AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE    = 0x0004,
+     AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS     = 0x0008,
+ };
+ 
+ /**
+  * Allocate an AVPacket and set its fields to default values.  The resulting
+  * struct must be freed using av_packet_free().
+  *
+diff --git a/media/ffvpx/libavcodec/parser.c b/media/ffvpx/libavcodec/parser.c
+--- a/media/ffvpx/libavcodec/parser.c
++++ b/media/ffvpx/libavcodec/parser.c
+@@ -247,16 +247,17 @@ int ff_combine_frame(ParseContext *pc, i
+ 
+     /* append to buffer */
+     if (pc->index) {
+         void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
+                                            next + pc->index +
+                                            AV_INPUT_BUFFER_PADDING_SIZE);
+         if (!new_buffer) {
+             av_log(NULL, AV_LOG_ERROR, "Failed to reallocate parser buffer to %d\n", next + pc->index + AV_INPUT_BUFFER_PADDING_SIZE);
++            *buf_size =
+             pc->overread_index =
+             pc->index = 0;
+             return AVERROR(ENOMEM);
+         }
+         pc->buffer = new_buffer;
+         if (next > -AV_INPUT_BUFFER_PADDING_SIZE)
+             memcpy(&pc->buffer[pc->index], *buf,
+                    next + AV_INPUT_BUFFER_PADDING_SIZE);
+diff --git a/media/ffvpx/libavcodec/pcm.c b/media/ffvpx/libavcodec/pcm.c
+--- a/media/ffvpx/libavcodec/pcm.c
++++ b/media/ffvpx/libavcodec/pcm.c
+@@ -23,16 +23,17 @@
+  * @file
+  * PCM codecs
+  */
+ 
+ #include "config.h"
+ #include "config_components.h"
+ #include "libavutil/attributes.h"
+ #include "libavutil/float_dsp.h"
++#include "libavutil/mem.h"
+ #include "libavutil/reverse.h"
+ #include "libavutil/thread.h"
+ #include "avcodec.h"
+ #include "bytestream.h"
+ #include "codec_internal.h"
+ #include "decode.h"
+ #include "encode.h"
+ #include "pcm_tablegen.h"
+diff --git a/media/ffvpx/libavcodec/pixblockdsp.h b/media/ffvpx/libavcodec/pixblockdsp.h
+--- a/media/ffvpx/libavcodec/pixblockdsp.h
++++ b/media/ffvpx/libavcodec/pixblockdsp.h
+@@ -16,32 +16,30 @@
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #ifndef AVCODEC_PIXBLOCKDSP_H
+ #define AVCODEC_PIXBLOCKDSP_H
+ 
+ #include <stdint.h>
+ 
+-#include "config.h"
+-
+ #include "avcodec.h"
+ 
+ typedef struct PixblockDSPContext {
+-    void (*get_pixels)(int16_t *av_restrict block /* align 16 */,
++    void (*get_pixels)(int16_t *restrict block /* align 16 */,
+                        const uint8_t *pixels /* align 8 */,
+                        ptrdiff_t stride);
+-    void (*get_pixels_unaligned)(int16_t *av_restrict block /* align 16 */,
++    void (*get_pixels_unaligned)(int16_t *restrict block /* align 16 */,
+                        const uint8_t *pixels,
+                        ptrdiff_t stride);
+-    void (*diff_pixels)(int16_t *av_restrict block /* align 16 */,
++    void (*diff_pixels)(int16_t *restrict block /* align 16 */,
+                         const uint8_t *s1 /* align 8 */,
+                         const uint8_t *s2 /* align 8 */,
+                         ptrdiff_t stride);
+-    void (*diff_pixels_unaligned)(int16_t *av_restrict block /* align 16 */,
++    void (*diff_pixels_unaligned)(int16_t *restrict block /* align 16 */,
+                         const uint8_t *s1,
+                         const uint8_t *s2,
+                         ptrdiff_t stride);
+ 
+ } PixblockDSPContext;
+ 
+ void ff_pixblockdsp_init(PixblockDSPContext *c, AVCodecContext *avctx);
+ void ff_pixblockdsp_init_aarch64(PixblockDSPContext *c, AVCodecContext *avctx,
+diff --git a/media/ffvpx/libavcodec/profiles.c b/media/ffvpx/libavcodec/profiles.c
+--- a/media/ffvpx/libavcodec/profiles.c
++++ b/media/ffvpx/libavcodec/profiles.c
+@@ -13,17 +13,18 @@
+  *
+  * 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
+  */
+ 
+ #include "config.h"
+ 
+-#include "avcodec.h"
++#include "codec.h"
++#include "defs.h"
+ #include "profiles.h"
+ 
+ #if !CONFIG_SMALL
+ 
+ const AVProfile ff_aac_profiles[] = {
+     { AV_PROFILE_AAC_LOW,   "LC"       },
+     { AV_PROFILE_AAC_HE,    "HE-AAC"   },
+     { AV_PROFILE_AAC_HE_V2, "HE-AACv2" },
+diff --git a/media/ffvpx/libavcodec/profiles.h b/media/ffvpx/libavcodec/profiles.h
+--- a/media/ffvpx/libavcodec/profiles.h
++++ b/media/ffvpx/libavcodec/profiles.h
+@@ -14,21 +14,22 @@
+  * 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
+  */
+ 
+ #ifndef AVCODEC_PROFILES_H
+ #define AVCODEC_PROFILES_H
+ 
+-#include "avcodec.h"
++#include "codec.h"
++#include "defs.h"
+ #include "libavutil/opt.h"
+ 
+ #define FF_AVCTX_PROFILE_OPTION(name, description, type, value) \
+-    {name, description, 0, AV_OPT_TYPE_CONST, {.i64 = value }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_## type ##_PARAM, "avctx.profile"},
++    {name, description, 0, AV_OPT_TYPE_CONST, {.i64 = value }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_## type ##_PARAM, .unit = "avctx.profile"},
+ 
+ #define FF_AAC_PROFILE_OPTS \
+     FF_AVCTX_PROFILE_OPTION("aac_main",      NULL, AUDIO, AV_PROFILE_AAC_MAIN)\
+     FF_AVCTX_PROFILE_OPTION("aac_low",       NULL, AUDIO, AV_PROFILE_AAC_LOW)\
+     FF_AVCTX_PROFILE_OPTION("aac_ssr",       NULL, AUDIO, AV_PROFILE_AAC_SSR)\
+     FF_AVCTX_PROFILE_OPTION("aac_ltp",       NULL, AUDIO, AV_PROFILE_AAC_LTP)\
+     FF_AVCTX_PROFILE_OPTION("aac_he",        NULL, AUDIO, AV_PROFILE_AAC_HE)\
+     FF_AVCTX_PROFILE_OPTION("aac_he_v2",     NULL, AUDIO, AV_PROFILE_AAC_HE_V2)\
+diff --git a/media/ffvpx/libavcodec/pthread_frame.c b/media/ffvpx/libavcodec/pthread_frame.c
+--- a/media/ffvpx/libavcodec/pthread_frame.c
++++ b/media/ffvpx/libavcodec/pthread_frame.c
+@@ -306,22 +306,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
+ 
+         dst->color_trc   = src->color_trc;
+         dst->colorspace  = src->colorspace;
+         dst->color_range = src->color_range;
+         dst->chroma_sample_location = src->chroma_sample_location;
+ 
+         dst->sample_rate    = src->sample_rate;
+         dst->sample_fmt     = src->sample_fmt;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        dst->channels       = src->channels;
+-        dst->channel_layout = src->channel_layout;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+         err = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
+         if (err < 0)
+             return err;
+ 
+         if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
+             (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
+             av_buffer_unref(&dst->hw_frames_ctx);
+ 
+@@ -413,26 +407,16 @@ static int update_context_from_user(AVCo
+     dst->flags2      = src->flags2;
+     dst->export_side_data = src->export_side_data;
+ 
+     dst->skip_loop_filter = src->skip_loop_filter;
+     dst->skip_idct        = src->skip_idct;
+     dst->skip_frame       = src->skip_frame;
+ 
+     dst->frame_num        = src->frame_num;
+-#if FF_API_AVCTX_FRAME_NUMBER
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    dst->frame_number     = src->frame_number;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-#if FF_API_REORDERED_OPAQUE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    dst->reordered_opaque = src->reordered_opaque;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+ 
+     av_packet_unref(dst->internal->last_pkt_props);
+     err = av_packet_copy_props(dst->internal->last_pkt_props, src->internal->last_pkt_props);
+     if (err < 0)
+         return err;
+ 
+     return 0;
+ }
+@@ -756,17 +740,17 @@ void ff_frame_thread_free(AVCodecContext
+ 
+         av_freep(&p->avctx);
+     }
+ 
+     av_freep(&fctx->threads);
+     ff_pthread_free(fctx, thread_ctx_offsets);
+ 
+     /* if we have stashed hwaccel state, move it to the user-facing context,
+-     * so it will be freed in avcodec_close() */
++     * so it will be freed in ff_codec_close() */
+     av_assert0(!avctx->hwaccel);
+     FFSWAP(const AVHWAccel*, avctx->hwaccel,                     fctx->stash_hwaccel);
+     FFSWAP(void*,            avctx->hwaccel_context,             fctx->stash_hwaccel_context);
+     FFSWAP(void*,            avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv);
+ 
+     av_freep(&avctx->internal->thread_ctx);
+ }
+ 
+diff --git a/media/ffvpx/libavcodec/ratecontrol.h b/media/ffvpx/libavcodec/ratecontrol.h
+--- a/media/ffvpx/libavcodec/ratecontrol.h
++++ b/media/ffvpx/libavcodec/ratecontrol.h
+@@ -23,19 +23,17 @@
+ #ifndef AVCODEC_RATECONTROL_H
+ #define AVCODEC_RATECONTROL_H
+ 
+ /**
+  * @file
+  * ratecontrol header.
+  */
+ 
+-#include <stdio.h>
+ #include <stdint.h>
+-#include "libavutil/eval.h"
+ 
+ typedef struct Predictor{
+     double coeff;
+     double count;
+     double decay;
+ } Predictor;
+ 
+ typedef struct RateControlEntry{
+@@ -75,17 +73,17 @@ typedef struct RateControlContext{
+     int64_t last_mb_var_sum;
+     uint64_t i_cplx_sum[5];
+     uint64_t p_cplx_sum[5];
+     uint64_t mv_bits_sum[5];
+     uint64_t qscale_sum[5];
+     int frame_count[5];
+     int last_non_b_pict_type;
+ 
+-    AVExpr * rc_eq_eval;
++    struct AVExpr *rc_eq_eval;
+ }RateControlContext;
+ 
+ struct MpegEncContext;
+ 
+ /* rate control */
+ int ff_rate_control_init(struct MpegEncContext *s);
+ float ff_rate_estimate_qscale(struct MpegEncContext *s, int dry_run);
+ void ff_write_pass1_stats(struct MpegEncContext *s);
+diff --git a/media/ffvpx/libavcodec/refstruct.c b/media/ffvpx/libavcodec/refstruct.c
+--- a/media/ffvpx/libavcodec/refstruct.c
++++ b/media/ffvpx/libavcodec/refstruct.c
+@@ -15,23 +15,23 @@
+  * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #include <stdatomic.h>
+ #include <stdint.h>
+ #include <string.h>
+ 
+-#include "internal.h"
+ #include "refstruct.h"
+ 
+ #include "libavutil/avassert.h"
+ #include "libavutil/error.h"
+ #include "libavutil/macros.h"
+ #include "libavutil/mem.h"
++#include "libavutil/mem_internal.h"
+ #include "libavutil/thread.h"
+ 
+ #ifndef REFSTRUCT_CHECKED
+ #ifndef ASSERT_LEVEL
+ #define ASSERT_LEVEL 0
+ #endif
+ #define REFSTRUCT_CHECKED (ASSERT_LEVEL >= 1)
+ #endif
+@@ -40,20 +40,20 @@
+ #define ff_assert(cond) av_assert0(cond)
+ #else
+ #define ff_assert(cond) ((void)0)
+ #endif
+ 
+ #define REFSTRUCT_COOKIE AV_NE((uint64_t)MKBETAG('R', 'e', 'f', 'S') << 32 | MKBETAG('t', 'r', 'u', 'c'), \
+                                MKTAG('R', 'e', 'f', 'S') | (uint64_t)MKTAG('t', 'r', 'u', 'c') << 32)
+ 
+-#if __STDC_VERSION__ >= 201112L
+-#define REFCOUNT_OFFSET FFALIGN(sizeof(RefCount), FFMAX3(STRIDE_ALIGN, 16, _Alignof(max_align_t)))
++#if __STDC_VERSION__ >= 201112L && !defined(_MSC_VER)
++#define REFCOUNT_OFFSET FFALIGN(sizeof(RefCount), FFMAX(ALIGN_64, _Alignof(max_align_t)))
+ #else
+-#define REFCOUNT_OFFSET FFALIGN(sizeof(RefCount), FFMAX(STRIDE_ALIGN, 16))
++#define REFCOUNT_OFFSET FFALIGN(sizeof(RefCount), ALIGN_64)
+ #endif
+ 
+ typedef struct RefCount {
+     /**
+      * An uintptr_t is big enough to hold the address of every reference,
+      * so no overflow can happen when incrementing the refcount as long as
+      * the user does not throw away references.
+      */
+diff --git a/media/ffvpx/libavcodec/utils.c b/media/ffvpx/libavcodec/utils.c
+--- a/media/ffvpx/libavcodec/utils.c
++++ b/media/ffvpx/libavcodec/utils.c
+@@ -357,27 +357,16 @@ void avcodec_align_dimensions(AVCodecCon
+ 
+     avcodec_align_dimensions2(s, width, height, linesize_align);
+     align               = FFMAX(linesize_align[0], linesize_align[3]);
+     linesize_align[1] <<= chroma_shift;
+     linesize_align[2] <<= chroma_shift;
+     align               = FFMAX3(align, linesize_align[1], linesize_align[2]);
+     *width              = FFALIGN(*width, align);
+ }
+-#if FF_API_AVCODEC_CHROMA_POS
+-int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos)
+-{
+-    return av_chroma_location_enum_to_pos(xpos, ypos, pos);
+-}
+-
+-enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos)
+-{
+-    return av_chroma_location_pos_to_enum(xpos, ypos);
+-}
+-#endif
+ 
+ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
+                              enum AVSampleFormat sample_fmt, const uint8_t *buf,
+                              int buf_size, int align)
+ {
+     int ch, planar, needed_size, ret = 0;
+ 
+     needed_size = av_samples_get_buffer_size(NULL, nb_channels,
+@@ -790,40 +779,30 @@ static int get_audio_frame_duration(enum
+ 
+     return 0;
+ }
+ 
+ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
+ {
+    int channels = avctx->ch_layout.nb_channels;
+    int duration;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    if (!channels)
+-        channels = avctx->channels;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
++
+     duration = get_audio_frame_duration(avctx->codec_id, avctx->sample_rate,
+                                     channels, avctx->block_align,
+                                     avctx->codec_tag, avctx->bits_per_coded_sample,
+                                     avctx->bit_rate, avctx->extradata, avctx->frame_size,
+                                     frame_bytes);
+     return FFMAX(0, duration);
+ }
+ 
+ int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes)
+ {
+    int channels = par->ch_layout.nb_channels;
+    int duration;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    if (!channels)
+-        channels = par->channels;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
++
+     duration = get_audio_frame_duration(par->codec_id, par->sample_rate,
+                                     channels, par->block_align,
+                                     par->codec_tag, par->bits_per_coded_sample,
+                                     par->bit_rate, par->extradata, par->frame_size,
+                                     frame_bytes);
+     return FFMAX(0, duration);
+ }
+ 
+@@ -955,19 +934,19 @@ void ff_thread_await_progress2(AVCodecCo
+ }
+ 
+ void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n)
+ {
+ }
+ 
+ #endif
+ 
+-const uint8_t *avpriv_find_start_code(const uint8_t *av_restrict p,
++const uint8_t *avpriv_find_start_code(const uint8_t *restrict p,
+                                       const uint8_t *end,
+-                                      uint32_t *av_restrict state)
++                                      uint32_t *restrict state)
+ {
+     int i;
+ 
+     av_assert0(p <= end);
+     if (p >= end)
+         return end;
+ 
+     for (i = 0; i < 3; i++) {
+diff --git a/media/ffvpx/libavcodec/vaapi.h b/media/ffvpx/libavcodec/vaapi.h
+deleted file mode 100644
+--- a/media/ffvpx/libavcodec/vaapi.h
++++ /dev/null
+@@ -1,86 +0,0 @@
+-/*
+- * Video Acceleration API (shared data between FFmpeg and the video player)
+- * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
+- *
+- * Copyright (C) 2008-2009 Splitted-Desktop Systems
+- *
+- * 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
+- */
+-
+-#ifndef AVCODEC_VAAPI_H
+-#define AVCODEC_VAAPI_H
+-
+-/**
+- * @file
+- * @ingroup lavc_codec_hwaccel_vaapi
+- * Public libavcodec VA API header.
+- */
+-
+-#include <stdint.h>
+-#include "libavutil/attributes.h"
+-#include "version.h"
+-
+-#if FF_API_STRUCT_VAAPI_CONTEXT
+-
+-/**
+- * @defgroup lavc_codec_hwaccel_vaapi VA API Decoding
+- * @ingroup lavc_codec_hwaccel
+- * @{
+- */
+-
+-/**
+- * This structure is used to share data between the FFmpeg library and
+- * the client video application.
+- * This shall be zero-allocated and available as
+- * AVCodecContext.hwaccel_context. All user members can be set once
+- * during initialization or through each AVCodecContext.get_buffer()
+- * function call. In any case, they must be valid prior to calling
+- * decoding functions.
+- *
+- * Deprecated: use AVCodecContext.hw_frames_ctx instead.
+- */
+-struct attribute_deprecated vaapi_context {
+-    /**
+-     * Window system dependent data
+-     *
+-     * - encoding: unused
+-     * - decoding: Set by user
+-     */
+-    void *display;
+-
+-    /**
+-     * Configuration ID
+-     *
+-     * - encoding: unused
+-     * - decoding: Set by user
+-     */
+-    uint32_t config_id;
+-
+-    /**
+-     * Context ID (video decode pipeline)
+-     *
+-     * - encoding: unused
+-     * - decoding: Set by user
+-     */
+-    uint32_t context_id;
+-};
+-
+-/* @} */
+-
+-#endif /* FF_API_STRUCT_VAAPI_CONTEXT */
+-
+-#endif /* AVCODEC_VAAPI_H */
+diff --git a/media/ffvpx/libavcodec/vaapi_decode.c b/media/ffvpx/libavcodec/vaapi_decode.c
+--- a/media/ffvpx/libavcodec/vaapi_decode.c
++++ b/media/ffvpx/libavcodec/vaapi_decode.c
+@@ -15,16 +15,17 @@
+  * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #include "config_components.h"
+ 
+ #include "libavutil/avassert.h"
+ #include "libavutil/common.h"
++#include "libavutil/mem.h"
+ #include "libavutil/pixdesc.h"
+ 
+ #include "avcodec.h"
+ #include "codec_desc.h"
+ #include "decode.h"
+ #include "internal.h"
+ #include "vaapi_decode.h"
+ #include "vaapi_hevc.h"
+@@ -67,27 +68,24 @@ int ff_vaapi_decode_make_slice_buffer(AV
+                                       size_t slice_size)
+ {
+     VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
+     VAStatus vas;
+     int index;
+ 
+     av_assert0(pic->nb_slices <= pic->slices_allocated);
+     if (pic->nb_slices == pic->slices_allocated) {
+-        if (pic->slices_allocated > 0)
+-            pic->slices_allocated *= 2;
+-        else
+-            pic->slices_allocated = 64;
+-
+         pic->slice_buffers =
+             av_realloc_array(pic->slice_buffers,
+-                             pic->slices_allocated,
++                             pic->slices_allocated ? pic->slices_allocated * 2 : 64,
+                              2 * sizeof(*pic->slice_buffers));
+         if (!pic->slice_buffers)
+             return AVERROR(ENOMEM);
++
++        pic->slices_allocated = pic->slices_allocated ? pic->slices_allocated * 2 : 64;
+     }
+     av_assert0(pic->nb_slices + 1 <= pic->slices_allocated);
+ 
+     index = 2 * pic->nb_slices;
+ 
+     vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
+                          VASliceParameterBufferType,
+                          params_size, 1, (void*)params_data,
+diff --git a/media/ffvpx/libavcodec/version.c b/media/ffvpx/libavcodec/version.c
+--- a/media/ffvpx/libavcodec/version.c
++++ b/media/ffvpx/libavcodec/version.c
+@@ -13,32 +13,38 @@
+  * 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
+  */
+ 
++#include <assert.h>
++
+ #include "config.h"
+ 
+-#include "libavutil/avassert.h"
+ #include "avcodec.h"
+ #include "codec_id.h"
+ #include "version.h"
+ 
+ #include "libavutil/ffversion.h"
+ const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
+ 
+ unsigned avcodec_version(void)
+ {
+-    av_assert0(AV_CODEC_ID_PCM_S8_PLANAR==65563);
+-    av_assert0(AV_CODEC_ID_ADPCM_G722==69660);
+-    av_assert0(AV_CODEC_ID_SRT==94216);
+-    av_assert0(LIBAVCODEC_VERSION_MICRO >= 100);
++    static_assert(AV_CODEC_ID_LEAD         ==   269 &&
++                  AV_CODEC_ID_PCM_SGA      == 65572 &&
++                  AV_CODEC_ID_ADPCM_XMD    == 69683 &&
++                  AV_CODEC_ID_CBD2_DPCM    == 81928 &&
++                  AV_CODEC_ID_QOA          == 86121 &&
++                  AV_CODEC_ID_ARIB_CAPTION == 94233 &&
++                  AV_CODEC_ID_SMPTE_2038   == 98315,
++                  "Don't insert new codec ids in the middle of a list");
++    static_assert(LIBAVCODEC_VERSION_MICRO >= 100, "micro version starts at 100");
+ 
+     return LIBAVCODEC_VERSION_INT;
+ }
+ 
+ const char *avcodec_configuration(void)
+ {
+     return FFMPEG_CONFIGURATION;
+ }
+diff --git a/media/ffvpx/libavcodec/version.h b/media/ffvpx/libavcodec/version.h
+--- a/media/ffvpx/libavcodec/version.h
++++ b/media/ffvpx/libavcodec/version.h
+@@ -24,18 +24,18 @@
+  * @ingroup libavc
+  * Libavcodec version macros.
+  */
+ 
+ #include "libavutil/version.h"
+ 
+ #include "version_major.h"
+ 
+-#define LIBAVCODEC_VERSION_MINOR  38
+-#define LIBAVCODEC_VERSION_MICRO 100
++#define LIBAVCODEC_VERSION_MINOR   5
++#define LIBAVCODEC_VERSION_MICRO 101
+ 
+ #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
+                                                LIBAVCODEC_VERSION_MINOR, \
+                                                LIBAVCODEC_VERSION_MICRO)
+ #define LIBAVCODEC_VERSION      AV_VERSION(LIBAVCODEC_VERSION_MAJOR,    \
+                                            LIBAVCODEC_VERSION_MINOR,    \
+                                            LIBAVCODEC_VERSION_MICRO)
+ #define LIBAVCODEC_BUILD        LIBAVCODEC_VERSION_INT
+diff --git a/media/ffvpx/libavcodec/version_major.h b/media/ffvpx/libavcodec/version_major.h
+--- a/media/ffvpx/libavcodec/version_major.h
++++ b/media/ffvpx/libavcodec/version_major.h
+@@ -20,40 +20,33 @@
+ #define AVCODEC_VERSION_MAJOR_H
+ 
+ /**
+  * @file
+  * @ingroup libavc
+  * Libavcodec version macros.
+  */
+ 
+-#define LIBAVCODEC_VERSION_MAJOR  60
++#define LIBAVCODEC_VERSION_MAJOR  61
+ 
+ /**
+  * FF_API_* defines may be placed below to indicate public API that will be
+  * dropped at a future version bump. The defines themselves are not part of
+  * the public API and may change, break or disappear at any time.
+  *
+  * @note, when bumping the major version it is recommended to manually
+  * disable each FF_API_* in its own commit instead of disabling them all
+  * at once through the bump. This improves the git bisect-ability of the change.
+  */
+ 
+-#define FF_API_INIT_PACKET         (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_IDCT_NONE           (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_SVTAV1_OPTS         (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_AYUV_CODECID        (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_VT_OUTPUT_CALLBACK  (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_AVCODEC_CHROMA_POS  (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_VT_HWACCEL_CONTEXT  (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_AVCTX_FRAME_NUMBER  (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_SLICE_OFFSET        (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_SUBFRAMES           (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_TICKS_PER_FRAME     (LIBAVCODEC_VERSION_MAJOR < 61)
+-#define FF_API_DROPCHANGED         (LIBAVCODEC_VERSION_MAJOR < 61)
++#define FF_API_INIT_PACKET         (LIBAVCODEC_VERSION_MAJOR < 62)
++#define FF_API_SUBFRAMES           (LIBAVCODEC_VERSION_MAJOR < 62)
++#define FF_API_TICKS_PER_FRAME     (LIBAVCODEC_VERSION_MAJOR < 62)
++#define FF_API_DROPCHANGED         (LIBAVCODEC_VERSION_MAJOR < 62)
+ 
+ #define FF_API_AVFFT               (LIBAVCODEC_VERSION_MAJOR < 62)
+ #define FF_API_FF_PROFILE_LEVEL    (LIBAVCODEC_VERSION_MAJOR < 62)
+-
+-// reminder to remove CrystalHD decoders on next major bump
+-#define FF_CODEC_CRYSTAL_HD        (LIBAVCODEC_VERSION_MAJOR < 61)
++#define FF_API_AVCODEC_CLOSE       (LIBAVCODEC_VERSION_MAJOR < 62)
++#define FF_API_BUFFER_MIN_SIZE     (LIBAVCODEC_VERSION_MAJOR < 62)
++#define FF_API_VDPAU_ALLOC_GET_SET (LIBAVCODEC_VERSION_MAJOR < 62)
++#define FF_API_QUALITY_FACTOR      (LIBAVCODEC_VERSION_MAJOR < 62)
+ 
+ #endif /* AVCODEC_VERSION_MAJOR_H */
+diff --git a/media/ffvpx/libavcodec/vlc.c b/media/ffvpx/libavcodec/vlc.c
+--- a/media/ffvpx/libavcodec/vlc.c
++++ b/media/ffvpx/libavcodec/vlc.c
+@@ -435,18 +435,18 @@ static void add_level(VLC_MULTI_ELEM *ta
+             uint32_t code;
+ 
+             sym = buf[t].symbol;
+             if (l >= curlimit)
+                 return;
+             code = curcode + (buf[t].code >> curlen);
+             newlimit = curlimit - l;
+             l  += curlen;
+-            if (is16bit) AV_WN16(info.val+2*curlevel, sym);
+-            else info.val[curlevel] = sym&0xFF;
++            if (is16bit) info.val16[curlevel] = sym;
++            else info.val8[curlevel] = sym&0xFF;
+ 
+             if (curlevel) { // let's not add single entries
+                 uint32_t val = code >> (32 - numbits);
+                 uint32_t  nb = val + (1U << (numbits - l));
+                 info.len = l;
+                 info.num = curlevel+1;
+                 for (; val < nb; val++)
+                     AV_COPY64(table+val, &info);
+@@ -463,17 +463,17 @@ static void add_level(VLC_MULTI_ELEM *ta
+ }
+ 
+ static int vlc_multi_gen(VLC_MULTI_ELEM *table, const VLC *single,
+                          const int is16bit, const int nb_codes, const int numbits,
+                          VLCcode *buf, void *logctx)
+ {
+     int minbits, maxbits, max;
+     unsigned count[VLC_MULTI_MAX_SYMBOLS-1] = { 0, };
+-    VLC_MULTI_ELEM info = { { 0, }, 0, 0, };
++    VLC_MULTI_ELEM info = { 0 };
+     int count0 = 0;
+ 
+     for (int j = 0; j < 1<<numbits; j++) {
+         if (single->table[j].len > 0) {
+             count0 ++;
+             j += (1 << (numbits - single->table[j].len)) - 1;
+         }
+     }
+@@ -494,17 +494,20 @@ static int vlc_multi_gen(VLC_MULTI_ELEM 
+         // If we have not a single useable vlc we end with max = nb_codes
+         if (buf[max - 1].bits+minbits > numbits)
+             break;
+     }
+ 
+     for (int j = 0; j < 1<<numbits; j++) {
+         table[j].len = single->table[j].len;
+         table[j].num = single->table[j].len > 0 ? 1 : 0;
+-        AV_WN16(table[j].val, single->table[j].sym);
++        if (is16bit)
++            table[j].val16[0] = single->table[j].sym;
++        else
++            table[j].val8[0]  = single->table[j].sym;
+     }
+ 
+     add_level(table, is16bit, nb_codes, numbits, buf,
+               0, 0, FFMIN(maxbits, numbits), 0, minbits, max, count, info);
+ 
+     av_log(logctx, AV_LOG_DEBUG, "Joint: %d/%d/%d/%d/%d codes min=%ubits max=%u\n",
+            count[0], count[1], count[2], count[3], count[4], minbits, max);
+ 
+diff --git a/media/ffvpx/libavcodec/vlc.h b/media/ffvpx/libavcodec/vlc.h
+--- a/media/ffvpx/libavcodec/vlc.h
++++ b/media/ffvpx/libavcodec/vlc.h
+@@ -35,17 +35,20 @@ typedef struct VLCElem {
+ 
+ typedef struct VLC {
+     int bits;
+     VLCElem *table;
+     int table_size, table_allocated;
+ } VLC;
+ 
+ typedef struct VLC_MULTI_ELEM {
+-    uint8_t val[VLC_MULTI_MAX_SYMBOLS];
++    union {
++        uint8_t   val8[VLC_MULTI_MAX_SYMBOLS];
++        uint16_t val16[VLC_MULTI_MAX_SYMBOLS / 2];
++    };
+     int8_t len; // -31,32
+     uint8_t num;
+ } VLC_MULTI_ELEM;
+ 
+ typedef struct VLC_MULTI {
+     VLC_MULTI_ELEM *table;
+     int table_size, table_allocated;
+ } VLC_MULTI;
+@@ -180,57 +183,16 @@ void ff_vlc_free(VLC *vlc);
+ #define VLC_INIT_STATIC_OVERLONG (2 | VLC_INIT_USE_STATIC)
+ /* If VLC_INIT_INPUT_LE is set, the LSB bit of the codes used to
+  * initialize the VLC table is the first bit to be read. */
+ #define VLC_INIT_INPUT_LE       4
+ /* If set the VLC is intended for a little endian bitstream reader. */
+ #define VLC_INIT_OUTPUT_LE      8
+ #define VLC_INIT_LE             (VLC_INIT_INPUT_LE | VLC_INIT_OUTPUT_LE)
+ 
+-#define VLC_INIT_CUSTOM_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g,      \
+-                                      h, i, j, flags, static_size)         \
+-    do {                                                                   \
+-        static VLCElem table[static_size];                                 \
+-        (vlc)->table           = table;                                    \
+-        (vlc)->table_allocated = static_size;                              \
+-        ff_vlc_init_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j,        \
+-                           flags | VLC_INIT_USE_STATIC);                   \
+-    } while (0)
+-
+-#define VLC_INIT_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \
+-    VLC_INIT_CUSTOM_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g,          \
+-                                  h, i, j, 0, static_size)
+-
+-#define VLC_INIT_LE_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \
+-    VLC_INIT_CUSTOM_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g,          \
+-                                  h, i, j, VLC_INIT_LE, static_size)
+-
+-#define VLC_INIT_CUSTOM_STATIC(vlc, bits, a, b, c, d, e, f, g, flags, static_size) \
+-    VLC_INIT_CUSTOM_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g,          \
+-                                  NULL, 0, 0, flags, static_size)
+-
+-#define VLC_INIT_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size)       \
+-    VLC_INIT_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size)
+-
+-#define VLC_INIT_LE_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \
+-    VLC_INIT_LE_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size)
+-
+-#define VLC_INIT_STATIC_FROM_LENGTHS(vlc, bits, nb_codes, lens, len_wrap,  \
+-                                     symbols, symbols_wrap, symbols_size,  \
+-                                     offset, flags, static_size)           \
+-    do {                                                                   \
+-        static VLCElem table[static_size];                                 \
+-        (vlc)->table           = table;                                    \
+-        (vlc)->table_allocated = static_size;                              \
+-        ff_vlc_init_from_lengths(vlc, bits, nb_codes, lens, len_wrap,      \
+-                                 symbols, symbols_wrap, symbols_size,      \
+-                                 offset, flags | VLC_INIT_USE_STATIC,      \
+-                                 NULL);                                    \
+-    } while (0)
+-
+ /**
+  * For static VLCs, the number of bits can often be hardcoded
+  * at each get_vlc2() callsite. Then using a full VLC would be uneconomical,
+  * because only VLC.table would ever be accessed after initialization.
+  * The following functions provide wrappers around the relevant ff_vlc_init_*
+  * functions suitable for said task.
+  *
+  * The ff_vlc_init_tables_* functions are intended to be used for initializing
+diff --git a/media/ffvpx/libavcodec/vorbis_data.c b/media/ffvpx/libavcodec/vorbis_data.c
+--- a/media/ffvpx/libavcodec/vorbis_data.c
++++ b/media/ffvpx/libavcodec/vorbis_data.c
+@@ -29,30 +29,16 @@ const uint8_t ff_vorbis_channel_layout_o
+     { 0, 2, 1 },
+     { 0, 1, 2, 3 },
+     { 0, 2, 1, 3, 4 },
+     { 0, 2, 1, 5, 3, 4 },
+     { 0, 2, 1, 6, 5, 3, 4 },
+     { 0, 2, 1, 7, 5, 6, 3, 4 },
+ };
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-const uint64_t ff_vorbis_channel_layouts[9] = {
+-    AV_CH_LAYOUT_MONO,
+-    AV_CH_LAYOUT_STEREO,
+-    AV_CH_LAYOUT_SURROUND,
+-    AV_CH_LAYOUT_QUAD,
+-    AV_CH_LAYOUT_5POINT0_BACK,
+-    AV_CH_LAYOUT_5POINT1_BACK,
+-    AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER,
+-    AV_CH_LAYOUT_7POINT1,
+-    0
+-};
+-#endif
+-
+ const AVChannelLayout ff_vorbis_ch_layouts[9] = {
+     AV_CHANNEL_LAYOUT_MONO,
+     AV_CHANNEL_LAYOUT_STEREO,
+     AV_CHANNEL_LAYOUT_SURROUND,
+     AV_CHANNEL_LAYOUT_QUAD,
+     AV_CHANNEL_LAYOUT_5POINT0_BACK,
+     AV_CHANNEL_LAYOUT_5POINT1_BACK,
+     {
+diff --git a/media/ffvpx/libavcodec/vorbis_data.h b/media/ffvpx/libavcodec/vorbis_data.h
+--- a/media/ffvpx/libavcodec/vorbis_data.h
++++ b/media/ffvpx/libavcodec/vorbis_data.h
+@@ -16,19 +16,19 @@
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #ifndef AVCODEC_VORBIS_DATA_H
+ #define AVCODEC_VORBIS_DATA_H
+ 
+ #include <stdint.h>
+ 
++#include "libavutil/attributes_internal.h"
+ #include "libavutil/channel_layout.h"
+ 
++FF_VISIBILITY_PUSH_HIDDEN
+ extern const float ff_vorbis_floor1_inverse_db_table[256];
+ extern const float * const ff_vorbis_vwin[8];
+ extern const uint8_t ff_vorbis_channel_layout_offsets[8][8];
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-extern const uint64_t ff_vorbis_channel_layouts[9];
+-#endif
+ extern const AVChannelLayout ff_vorbis_ch_layouts[9];
++FF_VISIBILITY_POP_HIDDEN
+ 
+ #endif /* AVCODEC_VORBIS_DATA_H */
+diff --git a/media/ffvpx/libavcodec/vorbis_parser.c b/media/ffvpx/libavcodec/vorbis_parser.c
+--- a/media/ffvpx/libavcodec/vorbis_parser.c
++++ b/media/ffvpx/libavcodec/vorbis_parser.c
+@@ -23,19 +23,19 @@
+  * Vorbis audio parser
+  *
+  * Determines the duration for each packet.
+  */
+ 
+ #include "config_components.h"
+ 
+ #include "libavutil/log.h"
++#include "libavutil/mem.h"
+ 
+ #include "get_bits.h"
+-#include "parser.h"
+ #include "xiph.h"
+ #include "vorbis_parser_internal.h"
+ 
+ static const AVClass vorbis_parser_class = {
+     .class_name = "Vorbis parser",
+     .item_name  = av_default_item_name,
+     .version    = LIBAVUTIL_VERSION_INT,
+ };
+diff --git a/media/ffvpx/libavcodec/vp8.c b/media/ffvpx/libavcodec/vp8.c
+--- a/media/ffvpx/libavcodec/vp8.c
++++ b/media/ffvpx/libavcodec/vp8.c
+@@ -21,16 +21,17 @@
+  *
+  * 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
+  */
+ 
+ #include "config_components.h"
+ 
++#include "libavutil/mem.h"
+ #include "libavutil/mem_internal.h"
+ 
+ #include "avcodec.h"
+ #include "codec_internal.h"
+ #include "decode.h"
+ #include "hwaccel_internal.h"
+ #include "hwconfig.h"
+ #include "mathops.h"
+@@ -2660,17 +2661,21 @@ int vp78_decode_frame(AVCodecContext *av
+     if (is_vp7)
+         ret = vp7_decode_frame_header(s, avpkt->data, avpkt->size);
+     else
+         ret = vp8_decode_frame_header(s, avpkt->data, avpkt->size);
+ 
+     if (ret < 0)
+         goto err;
+ 
+-    if (s->actually_webp) {
++    if (!is_vp7 && s->actually_webp) {
++        // VP8 in WebP is supposed to be intra-only. Enforce this here
++        // to ensure that output is reproducible with frame-threading.
++        if (!s->keyframe)
++            return AVERROR_INVALIDDATA;
+         // avctx->pix_fmt already set in caller.
+     } else if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) {
+         s->pix_fmt = get_pixel_format(s);
+         if (s->pix_fmt < 0) {
+             ret = AVERROR(EINVAL);
+             goto err;
+         }
+         avctx->pix_fmt = s->pix_fmt;
+@@ -2745,17 +2750,17 @@ int vp78_decode_frame(AVCodecContext *av
+ 
+     if (s->update_last)
+         s->next_framep[VP8_FRAME_PREVIOUS] = curframe;
+     else
+         s->next_framep[VP8_FRAME_PREVIOUS] = s->framep[VP8_FRAME_PREVIOUS];
+ 
+     s->next_framep[VP8_FRAME_CURRENT] = curframe;
+ 
+-    if (ffcodec(avctx->codec)->update_thread_context)
++    if (!is_vp7 && !s->actually_webp)
+         ff_thread_finish_setup(avctx);
+ 
+     if (avctx->hwaccel) {
+         const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
+         ret = hwaccel->start_frame(avctx, avpkt->data, avpkt->size);
+         if (ret < 0)
+             goto err;
+ 
+@@ -2878,17 +2883,16 @@ static av_cold int vp8_init_frames(VP8Co
+ 
+ static av_always_inline
+ int vp78_decode_init(AVCodecContext *avctx, int is_vp7)
+ {
+     VP8Context *s = avctx->priv_data;
+     int ret;
+ 
+     s->avctx = avctx;
+-    s->vp7   = avctx->codec->id == AV_CODEC_ID_VP7;
+     s->pix_fmt = AV_PIX_FMT_NONE;
+     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ 
+     ff_videodsp_init(&s->vdsp, 8);
+ 
+     ff_vp78dsp_init(&s->vp8dsp);
+     if (CONFIG_VP7_DECODER && is_vp7) {
+         ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP7, 8, 1);
+diff --git a/media/ffvpx/libavcodec/vp8.h b/media/ffvpx/libavcodec/vp8.h
+--- a/media/ffvpx/libavcodec/vp8.h
++++ b/media/ffvpx/libavcodec/vp8.h
+@@ -326,18 +326,16 @@ typedef struct VP8Context {
+      * 0 -> Only width+height*2+1 macroblocks allocated (frame/single thread).
+      * 1 -> Macroblocks for entire frame allocated (sliced thread).
+      */
+     int mb_layout;
+ 
+     int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
+     void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
+ 
+-    int vp7;
+-
+     /**
+      * Interframe DC prediction (VP7)
+      * [0] VP8_FRAME_PREVIOUS
+      * [1] VP8_FRAME_GOLDEN
+      */
+     uint16_t inter_dc_pred[2][2];
+ 
+     /**
+diff --git a/media/ffvpx/libavcodec/vp8dsp.c b/media/ffvpx/libavcodec/vp8dsp.c
+--- a/media/ffvpx/libavcodec/vp8dsp.c
++++ b/media/ffvpx/libavcodec/vp8dsp.c
+@@ -737,16 +737,18 @@ av_cold void ff_vp8dsp_init(VP8DSPContex
+ 
+     dsp->vp8_v_loop_filter_simple = vp8_v_loop_filter_simple_c;
+     dsp->vp8_h_loop_filter_simple = vp8_h_loop_filter_simple_c;
+ 
+ #if ARCH_AARCH64
+     ff_vp8dsp_init_aarch64(dsp);
+ #elif ARCH_ARM
+     ff_vp8dsp_init_arm(dsp);
++#elif ARCH_RISCV
++    ff_vp8dsp_init_riscv(dsp);
+ #elif ARCH_X86
+     ff_vp8dsp_init_x86(dsp);
+ #elif ARCH_MIPS
+     ff_vp8dsp_init_mips(dsp);
+ #elif ARCH_LOONGARCH
+     ff_vp8dsp_init_loongarch(dsp);
+ #endif
+ }
+diff --git a/media/ffvpx/libavcodec/vp8dsp.h b/media/ffvpx/libavcodec/vp8dsp.h
+--- a/media/ffvpx/libavcodec/vp8dsp.h
++++ b/media/ffvpx/libavcodec/vp8dsp.h
+@@ -87,16 +87,17 @@ void ff_vp78dsp_init(VP8DSPContext *c);
+ void ff_vp78dsp_init_aarch64(VP8DSPContext *c);
+ void ff_vp78dsp_init_arm(VP8DSPContext *c);
+ void ff_vp78dsp_init_ppc(VP8DSPContext *c);
+ void ff_vp78dsp_init_x86(VP8DSPContext *c);
+ 
+ void ff_vp8dsp_init(VP8DSPContext *c);
+ void ff_vp8dsp_init_aarch64(VP8DSPContext *c);
+ void ff_vp8dsp_init_arm(VP8DSPContext *c);
++void ff_vp8dsp_init_riscv(VP8DSPContext *c);
+ void ff_vp8dsp_init_x86(VP8DSPContext *c);
+ void ff_vp8dsp_init_mips(VP8DSPContext *c);
+ void ff_vp8dsp_init_loongarch(VP8DSPContext *c);
+ 
+ #define IS_VP7 1
+ #define IS_VP8 0
+ 
+ #endif /* AVCODEC_VP8DSP_H */
+diff --git a/media/ffvpx/libavcodec/vp9.c b/media/ffvpx/libavcodec/vp9.c
+--- a/media/ffvpx/libavcodec/vp9.c
++++ b/media/ffvpx/libavcodec/vp9.c
+@@ -37,16 +37,17 @@
+ 
+ #include "videodsp.h"
+ #include "vp89_rac.h"
+ #include "vp9.h"
+ #include "vp9data.h"
+ #include "vp9dec.h"
+ #include "vpx_rac.h"
+ #include "libavutil/avassert.h"
++#include "libavutil/mem.h"
+ #include "libavutil/pixdesc.h"
+ #include "libavutil/video_enc_params.h"
+ 
+ #define VP9_SYNCCODE 0x498342
+ 
+ #if HAVE_THREADS
+ DEFINE_OFFSET_ARRAY(VP9Context, vp9_context, pthread_init_cnt,
+                     (offsetof(VP9Context, progress_mutex)),
+diff --git a/media/ffvpx/libavcodec/x86/h264_intrapred.asm b/media/ffvpx/libavcodec/x86/h264_intrapred.asm
+--- a/media/ffvpx/libavcodec/x86/h264_intrapred.asm
++++ b/media/ffvpx/libavcodec/x86/h264_intrapred.asm
+@@ -81,29 +81,27 @@ cglobal pred16x16_horizontal_8, 2,3
+ %if cpuflag(ssse3)
+     pshufb    m0, m2
+     pshufb    m1, m2
+ %else
+     punpcklbw m0, m0
+     punpcklbw m1, m1
+     SPLATW    m0, m0, 3
+     SPLATW    m1, m1, 3
+-    mova [r0+r1*0+8], m0
+-    mova [r0+r1*1+8], m1
+ %endif
+ 
+     mova [r0+r1*0], m0
+     mova [r0+r1*1], m1
+     lea       r0, [r0+r1*2]
+     dec       r2
+     jg .loop
+     RET
+ %endmacro
+ 
+-INIT_MMX mmxext
++INIT_XMM sse2
+ PRED16x16_H
+ INIT_XMM ssse3
+ PRED16x16_H
+ 
+ ;-----------------------------------------------------------------------------
+ ; void ff_pred16x16_dc_8(uint8_t *src, ptrdiff_t stride)
+ ;-----------------------------------------------------------------------------
+ 
+@@ -563,27 +561,27 @@ INIT_XMM sse2
+ H264_PRED8x8_PLANE
+ INIT_XMM ssse3
+ H264_PRED8x8_PLANE
+ 
+ ;-----------------------------------------------------------------------------
+ ; void ff_pred8x8_vertical_8(uint8_t *src, ptrdiff_t stride)
+ ;-----------------------------------------------------------------------------
+ 
+-INIT_MMX mmx
++INIT_XMM sse2
+ cglobal pred8x8_vertical_8, 2,2
+     sub    r0, r1
+-    movq  mm0, [r0]
++    movq   m0, [r0]
+ %rep 3
+-    movq [r0+r1*1], mm0
+-    movq [r0+r1*2], mm0
++    movq [r0+r1*1], m0
++    movq [r0+r1*2], m0
+     lea    r0, [r0+r1*2]
+ %endrep
+-    movq [r0+r1*1], mm0
+-    movq [r0+r1*2], mm0
++    movq [r0+r1*1], m0
++    movq [r0+r1*2], m0
+     RET
+ 
+ ;-----------------------------------------------------------------------------
+ ; void ff_pred8x8_horizontal_8(uint8_t *src, ptrdiff_t stride)
+ ;-----------------------------------------------------------------------------
+ 
+ %macro PRED8x8_H 0
+ cglobal pred8x8_horizontal_8, 2,3
+@@ -1308,20 +1306,17 @@ INIT_MMX ssse3
+ PRED8x8L_DOWN_RIGHT
+ 
+ ;-----------------------------------------------------------------------------
+ ; void ff_pred8x8l_vertical_right_8(uint8_t *src, int has_topleft,
+ ;                                   int has_topright, ptrdiff_t stride)
+ ;-----------------------------------------------------------------------------
+ 
+ %macro PRED8x8L_VERTICAL_RIGHT 0
+-cglobal pred8x8l_vertical_right_8, 4,5,7
+-    ; manually spill XMM registers for Win64 because
+-    ; the code here is initialized with INIT_MMX
+-    WIN64_SPILL_XMM 7
++cglobal pred8x8l_vertical_right_8, 4,5,6
+     sub          r0, r3
+     lea          r4, [r0+r3*2]
+     movq        mm0, [r0+r3*1-8]
+     punpckhbw   mm0, [r0+r3*0-8]
+     movq        mm1, [r4+r3*1-8]
+     punpckhbw   mm1, [r0+r3*2-8]
+     mov          r4, r0
+     punpckhwd   mm1, mm0
+@@ -1381,35 +1376,35 @@ cglobal pred8x8l_vertical_right_8, 4,5,7
+     test        r2d, r2d
+     jz .fix_tr_1
+ .do_top:
+     PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5
+     lea           r1, [r0+r3*2]
+     movq2dq     xmm4, mm6
+     pslldq      xmm4, 8
+     por         xmm0, xmm4
+-    movdqa      xmm6, [pw_ff00]
+     movdqa      xmm1, xmm0
+     lea           r2, [r1+r3*2]
+     movdqa      xmm2, xmm0
+     movdqa      xmm3, xmm0
+     pslldq      xmm0, 1
+     pslldq      xmm1, 2
+     pavgb       xmm2, xmm0
+ INIT_XMM cpuname
+     PRED4x4_LOWPASS xmm4, xmm3, xmm1, xmm0, xmm5
+-    pandn       xmm6, xmm4
++    movdqa      xmm0, [pw_ff00]
++    pandn       xmm0, xmm4
+     movdqa      xmm5, xmm4
+     psrlw       xmm4, 8
+-    packuswb    xmm6, xmm4
+-    movhlps     xmm4, xmm6
++    packuswb    xmm0, xmm4
++    movhlps     xmm4, xmm0
+     movhps [r0+r3*2], xmm5
+     movhps [r0+r3*1], xmm2
+     psrldq      xmm5, 4
+-    movss       xmm5, xmm6
++    movss       xmm5, xmm0
+     psrldq      xmm2, 4
+     movss       xmm2, xmm4
+     lea           r0, [r2+r3*2]
+     psrldq      xmm5, 1
+     psrldq      xmm2, 1
+     movq        [r0+r3*2], xmm5
+     movq        [r0+r3*1], xmm2
+     psrldq      xmm5, 1
+diff --git a/media/ffvpx/libavcodec/x86/h264_intrapred_init.c b/media/ffvpx/libavcodec/x86/h264_intrapred_init.c
+--- a/media/ffvpx/libavcodec/x86/h264_intrapred_init.c
++++ b/media/ffvpx/libavcodec/x86/h264_intrapred_init.c
+@@ -95,33 +95,33 @@ PRED16x16(dc, 10, sse2)
+ PRED16x16(top_dc, 10, sse2)
+ PRED16x16(128_dc, 10, sse2)
+ PRED16x16(left_dc, 10, sse2)
+ PRED16x16(vertical, 10, sse2)
+ PRED16x16(horizontal, 10, sse2)
+ 
+ /* 8-bit versions */
+ PRED16x16(vertical, 8, sse)
+-PRED16x16(horizontal, 8, mmxext)
++PRED16x16(horizontal, 8, sse2)
+ PRED16x16(horizontal, 8, ssse3)
+ PRED16x16(dc, 8, sse2)
+ PRED16x16(dc, 8, ssse3)
+ PRED16x16(plane_h264, 8, sse2)
+ PRED16x16(plane_h264, 8, ssse3)
+ PRED16x16(plane_rv40, 8, sse2)
+ PRED16x16(plane_rv40, 8, ssse3)
+ PRED16x16(plane_svq3, 8, sse2)
+ PRED16x16(plane_svq3, 8, ssse3)
+ PRED16x16(tm_vp8, 8, sse2)
+ PRED16x16(tm_vp8, 8, avx2)
+ 
+ PRED8x8(top_dc, 8, mmxext)
+ PRED8x8(dc_rv40, 8, mmxext)
+ PRED8x8(dc, 8, mmxext)
+-PRED8x8(vertical, 8, mmx)
++PRED8x8(vertical, 8, sse2)
+ PRED8x8(horizontal, 8, mmxext)
+ PRED8x8(horizontal, 8, ssse3)
+ PRED8x8(plane, 8, sse2)
+ PRED8x8(plane, 8, ssse3)
+ PRED8x8(tm_vp8, 8, sse2)
+ PRED8x8(tm_vp8, 8, ssse3)
+ 
+ PRED8x8L(top_dc, 8, mmxext)
+@@ -158,24 +158,17 @@ PRED4x4(vertical_vp8, 8, mmxext)
+ 
+ av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id,
+                                    const int bit_depth,
+                                    const int chroma_format_idc)
+ {
+     int cpu_flags = av_get_cpu_flags();
+ 
+     if (bit_depth == 8) {
+-        if (EXTERNAL_MMX(cpu_flags)) {
+-            if (chroma_format_idc <= 1) {
+-                h->pred8x8  [VERT_PRED8x8     ] = ff_pred8x8_vertical_8_mmx;
+-            }
+-        }
+-
+         if (EXTERNAL_MMXEXT(cpu_flags)) {
+-            h->pred16x16[HOR_PRED8x8            ] = ff_pred16x16_horizontal_8_mmxext;
+             if (chroma_format_idc <= 1)
+                 h->pred8x8[HOR_PRED8x8          ] = ff_pred8x8_horizontal_8_mmxext;
+             h->pred8x8l [TOP_DC_PRED            ] = ff_pred8x8l_top_dc_8_mmxext;
+             h->pred8x8l [DC_PRED                ] = ff_pred8x8l_dc_8_mmxext;
+             h->pred8x8l [HOR_PRED               ] = ff_pred8x8l_horizontal_8_mmxext;
+             h->pred8x8l [VERT_PRED              ] = ff_pred8x8l_vertical_8_mmxext;
+             h->pred8x8l [HOR_UP_PRED            ] = ff_pred8x8l_horizontal_up_8_mmxext;
+             h->pred4x4  [DIAG_DOWN_RIGHT_PRED   ] = ff_pred4x4_down_right_8_mmxext;
+@@ -205,22 +198,25 @@ av_cold void ff_h264_pred_init_x86(H264P
+             }
+         }
+ 
+         if (EXTERNAL_SSE(cpu_flags)) {
+             h->pred16x16[VERT_PRED8x8] = ff_pred16x16_vertical_8_sse;
+         }
+ 
+         if (EXTERNAL_SSE2(cpu_flags)) {
++            h->pred16x16[HOR_PRED8x8          ] = ff_pred16x16_horizontal_8_sse2;
+             h->pred16x16[DC_PRED8x8           ] = ff_pred16x16_dc_8_sse2;
+             h->pred8x8l [DIAG_DOWN_LEFT_PRED  ] = ff_pred8x8l_down_left_8_sse2;
+             h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_sse2;
+             h->pred8x8l [VERT_RIGHT_PRED      ] = ff_pred8x8l_vertical_right_8_sse2;
+             h->pred8x8l [VERT_LEFT_PRED       ] = ff_pred8x8l_vertical_left_8_sse2;
+             h->pred8x8l [HOR_DOWN_PRED        ] = ff_pred8x8l_horizontal_down_8_sse2;
++            if (chroma_format_idc <= 1)
++                h->pred8x8  [VERT_PRED8x8     ] = ff_pred8x8_vertical_8_sse2;
+             if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) {
+                 h->pred16x16[PLANE_PRED8x8    ] = ff_pred16x16_tm_vp8_8_sse2;
+                 h->pred8x8  [PLANE_PRED8x8    ] = ff_pred8x8_tm_vp8_8_sse2;
+             } else {
+                 if (chroma_format_idc <= 1)
+                     h->pred8x8  [PLANE_PRED8x8] = ff_pred8x8_plane_8_sse2;
+                 if (codec_id == AV_CODEC_ID_SVQ3) {
+                     h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_sse2;
+diff --git a/media/ffvpx/libavcodec/x86/moz.build b/media/ffvpx/libavcodec/x86/moz.build
+--- a/media/ffvpx/libavcodec/x86/moz.build
++++ b/media/ffvpx/libavcodec/x86/moz.build
+@@ -32,16 +32,18 @@ SOURCES += [
+     'vp9itxfm.asm',
+     'vp9itxfm_16bpp.asm',
+     'vp9lpf.asm',
+     'vp9lpf_16bpp.asm',
+     'vp9mc.asm',
+     'vp9mc_16bpp.asm',
+ ]
+ 
++LOCAL_INCLUDES += [ "../" ]
++
+ if CONFIG['TARGET_CPU'] == 'x86':
+     SOURCES += [ 'simple_idct.asm' ]
+ 
+ if CONFIG['TARGET_CPU'] == 'x86_64':
+     SOURCES += [ 'simple_idct10.asm' ]
+ 
+ FINAL_LIBRARY = 'mozavcodec'
+ 
+diff --git a/media/ffvpx/libavcodec/x86/simple_idct.asm b/media/ffvpx/libavcodec/x86/simple_idct.asm
+--- a/media/ffvpx/libavcodec/x86/simple_idct.asm
++++ b/media/ffvpx/libavcodec/x86/simple_idct.asm
+@@ -778,78 +778,43 @@ SECTION .text
+     IDCT8 rsp + 16, rsp + 80, rsp + 48, rsp + 112, blockq +  8, 20
+ 
+     %%9:
+ %endmacro
+ 
+ %macro PUT_PIXELS_CLAMPED_HALF 1
+     mova     m0, [blockq+mmsize*0+%1]
+     mova     m1, [blockq+mmsize*2+%1]
+-%if mmsize == 8
+-    mova     m2, [blockq+mmsize*4+%1]
+-    mova     m3, [blockq+mmsize*6+%1]
+-%endif
+     packuswb m0, [blockq+mmsize*1+%1]
+     packuswb m1, [blockq+mmsize*3+%1]
+-%if mmsize == 8
+-    packuswb m2, [blockq+mmsize*5+%1]
+-    packuswb m3, [blockq+mmsize*7+%1]
+-    movq           [pixelsq], m0
+-    movq    [lsizeq+pixelsq], m1
+-    movq  [2*lsizeq+pixelsq], m2
+-    movq   [lsize3q+pixelsq], m3
+-%else
+     movq           [pixelsq], m0
+     movhps  [lsizeq+pixelsq], m0
+     movq  [2*lsizeq+pixelsq], m1
+     movhps [lsize3q+pixelsq], m1
+-%endif
+ %endmacro
+ 
+ %macro ADD_PIXELS_CLAMPED 1
+     mova       m0, [blockq+mmsize*0+%1]
+     mova       m1, [blockq+mmsize*1+%1]
+-%if mmsize == 8
+-    mova       m5, [blockq+mmsize*2+%1]
+-    mova       m6, [blockq+mmsize*3+%1]
+-%endif
+     movq       m2, [pixelsq]
+     movq       m3, [pixelsq+lsizeq]
+-%if mmsize == 8
+-    mova       m7, m2
+-    punpcklbw  m2, m4
+-    punpckhbw  m7, m4
+-    paddsw     m0, m2
+-    paddsw     m1, m7
+-    mova       m7, m3
+-    punpcklbw  m3, m4
+-    punpckhbw  m7, m4
+-    paddsw     m5, m3
+-    paddsw     m6, m7
+-%else
+     punpcklbw  m2, m4
+     punpcklbw  m3, m4
+     paddsw     m0, m2
+     paddsw     m1, m3
+-%endif
+     packuswb   m0, m1
+-%if mmsize == 8
+-    packuswb   m5, m6
+-    movq       [pixelsq], m0
+-    movq       [pixelsq+lsizeq], m5
+-%else
+     movq       [pixelsq], m0
+     movhps     [pixelsq+lsizeq], m0
+-%endif
+ %endmacro
+ 
+ INIT_MMX mmx
+ 
+ cglobal simple_idct, 1, 2, 8, 128, block, t0
+     IDCT
++    emms
+ RET
+ 
+ INIT_XMM sse2
+ 
+ cglobal simple_idct_put, 3, 5, 8, 128, pixels, lsize, block, lsize3, t0
+     IDCT
+     lea lsize3q, [lsizeq*3]
+     PUT_PIXELS_CLAMPED_HALF 0
+diff --git a/media/ffvpx/libavcodec/x86/vp56_arith.h b/media/ffvpx/libavcodec/x86/vp56_arith.h
+deleted file mode 100644
+--- a/media/ffvpx/libavcodec/x86/vp56_arith.h
++++ /dev/null
+@@ -1,53 +0,0 @@
+-/**
+- * VP5 and VP6 compatible video decoder (arith decoder)
+- *
+- * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
+- * Copyright (C) 2010  Eli Friedman
+- *
+- * 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
+- */
+-
+-#ifndef AVCODEC_X86_VP56_ARITH_H
+-#define AVCODEC_X86_VP56_ARITH_H
+-
+-#if HAVE_INLINE_ASM && HAVE_FAST_CMOV && HAVE_6REGS
+-#include "libavutil/attributes.h"
+-
+-#define vp56_rac_get_prob vp56_rac_get_prob
+-static av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob)
+-{
+-    unsigned int code_word = vp56_rac_renorm(c);
+-    unsigned int low = 1 + (((c->high - 1) * prob) >> 8);
+-    unsigned int low_shift = low << 16;
+-    int bit = 0;
+-    c->code_word = code_word;
+-
+-    __asm__(
+-        "subl  %4, %1      \n\t"
+-        "subl  %3, %2      \n\t"
+-        "setae %b0         \n\t"
+-        "cmovb %4, %1      \n\t"
+-        "cmovb %5, %2      \n\t"
+-        : "+q"(bit), "+&r"(c->high), "+&r"(c->code_word)
+-        : "r"(low_shift), "r"(low), "r"(code_word)
+-    );
+-
+-    return bit;
+-}
+-#endif
+-
+-#endif /* AVCODEC_X86_VP56_ARITH_H */
+diff --git a/media/ffvpx/libavcodec/x86/vp8dsp.asm b/media/ffvpx/libavcodec/x86/vp8dsp.asm
+--- a/media/ffvpx/libavcodec/x86/vp8dsp.asm
++++ b/media/ffvpx/libavcodec/x86/vp8dsp.asm
+@@ -109,17 +109,17 @@ bilinear_filter_vw_m: times 8 dw 1
+ bilinear_filter_vb_m: times 8 db 7, 1
+                       times 8 db 6, 2
+                       times 8 db 5, 3
+                       times 8 db 4, 4
+                       times 8 db 3, 5
+                       times 8 db 2, 6
+                       times 8 db 1, 7
+ 
+-%ifdef PIC
++%if PIC
+ %define fourtap_filter_hw  picregq
+ %define sixtap_filter_hw   picregq
+ %define fourtap_filter_hb  picregq
+ %define sixtap_filter_hb   picregq
+ %define fourtap_filter_v   picregq
+ %define sixtap_filter_v    picregq
+ %define bilinear_filter_vw picregq
+ %define bilinear_filter_vb picregq
+@@ -161,17 +161,17 @@ SECTION .text
+ ;                                                 int height,   int mx, int my);
+ ;-------------------------------------------------------------------------------
+ 
+ %macro FILTER_SSSE3 1
+ cglobal put_vp8_epel%1_h6, 6, 6 + npicregs, 8, dst, dststride, src, srcstride, height, mx, picreg
+     lea      mxd, [mxq*3]
+     mova      m3, [filter_h6_shuf2]
+     mova      m4, [filter_h6_shuf3]
+-%ifdef PIC
++%if PIC
+     lea  picregq, [sixtap_filter_hb_m]
+ %endif
+     mova      m5, [sixtap_filter_hb+mxq*8-48] ; set up 6tap filter in bytes
+     mova      m6, [sixtap_filter_hb+mxq*8-32]
+     mova      m7, [sixtap_filter_hb+mxq*8-16]
+ 
+ .nextrow:
+     movu      m0, [srcq-2]
+@@ -202,17 +202,17 @@ cglobal put_vp8_epel%1_h6, 6, 6 + npicre
+     jg .nextrow
+     RET
+ 
+ cglobal put_vp8_epel%1_h4, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, height, mx, picreg
+     shl      mxd, 4
+     mova      m2, [pw_256]
+     mova      m3, [filter_h2_shuf]
+     mova      m4, [filter_h4_shuf]
+-%ifdef PIC
++%if PIC
+     lea  picregq, [fourtap_filter_hb_m]
+ %endif
+     mova      m5, [fourtap_filter_hb+mxq-16] ; set up 4tap filter in bytes
+     mova      m6, [fourtap_filter_hb+mxq]
+ 
+ .nextrow:
+     movu      m0, [srcq-1]
+     mova      m1, m0
+@@ -229,17 +229,17 @@ cglobal put_vp8_epel%1_h4, 6, 6 + npicre
+     add     dstq, dststrideq
+     add     srcq, srcstrideq
+     dec  heightd            ; next row
+     jg .nextrow
+     RET
+ 
+ cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my
+     shl      myd, 4
+-%ifdef PIC
++%if PIC
+     lea  picregq, [fourtap_filter_hb_m]
+ %endif
+     mova      m5, [fourtap_filter_hb+myq-16]
+     mova      m6, [fourtap_filter_hb+myq]
+     mova      m7, [pw_256]
+ 
+     ; read 3 lines
+     sub     srcq, srcstrideq
+@@ -267,17 +267,17 @@ cglobal put_vp8_epel%1_v4, 7, 7, 8, dst,
+     add      dstq, dststrideq
+     add      srcq, srcstrideq
+     dec   heightd                          ; next row
+     jg .nextrow
+     RET
+ 
+ cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my
+     lea      myd, [myq*3]
+-%ifdef PIC
++%if PIC
+     lea  picregq, [sixtap_filter_hb_m]
+ %endif
+     lea      myq, [sixtap_filter_hb+myq*8]
+ 
+     ; read 5 lines
+     sub     srcq, srcstrideq
+     sub     srcq, srcstrideq
+     movh      m0, [srcq]
+@@ -321,17 +321,17 @@ INIT_MMX ssse3
+ FILTER_SSSE3 4
+ INIT_XMM ssse3
+ FILTER_SSSE3 8
+ 
+ ; 4x4 block, H-only 4-tap filter
+ INIT_MMX mmxext
+ cglobal put_vp8_epel4_h4, 6, 6 + npicregs, 0, dst, dststride, src, srcstride, height, mx, picreg
+     shl       mxd, 4
+-%ifdef PIC
++%if PIC
+     lea   picregq, [fourtap_filter_hw_m]
+ %endif
+     movq      mm4, [fourtap_filter_hw+mxq-16] ; set up 4tap filter in words
+     movq      mm5, [fourtap_filter_hw+mxq]
+     movq      mm7, [pw_64]
+     pxor      mm6, mm6
+ 
+ .nextrow:
+@@ -369,17 +369,17 @@ cglobal put_vp8_epel4_h4, 6, 6 + npicreg
+     dec   heightd                          ; next row
+     jg .nextrow
+     RET
+ 
+ ; 4x4 block, H-only 6-tap filter
+ INIT_MMX mmxext
+ cglobal put_vp8_epel4_h6, 6, 6 + npicregs, 0, dst, dststride, src, srcstride, height, mx, picreg
+     lea       mxd, [mxq*3]
+-%ifdef PIC
++%if PIC
+     lea   picregq, [sixtap_filter_hw_m]
+ %endif
+     movq      mm4, [sixtap_filter_hw+mxq*8-48] ; set up 4tap filter in words
+     movq      mm5, [sixtap_filter_hw+mxq*8-32]
+     movq      mm6, [sixtap_filter_hw+mxq*8-16]
+     movq      mm7, [pw_64]
+     pxor      mm3, mm3
+ 
+@@ -426,17 +426,17 @@ cglobal put_vp8_epel4_h6, 6, 6 + npicreg
+     add      srcq, srcstrideq
+     dec   heightd                          ; next row
+     jg .nextrow
+     RET
+ 
+ INIT_XMM sse2
+ cglobal put_vp8_epel8_h4, 6, 6 + npicregs, 10, dst, dststride, src, srcstride, height, mx, picreg
+     shl      mxd, 5
+-%ifdef PIC
++%if PIC
+     lea  picregq, [fourtap_filter_v_m]
+ %endif
+     lea      mxq, [fourtap_filter_v+mxq-32]
+     pxor      m7, m7
+     mova      m4, [pw_64]
+     mova      m5, [mxq+ 0]
+     mova      m6, [mxq+16]
+ %ifdef m8
+@@ -475,17 +475,17 @@ cglobal put_vp8_epel8_h4, 6, 6 + npicreg
+     dec  heightd            ; next row
+     jg .nextrow
+     RET
+ 
+ INIT_XMM sse2
+ cglobal put_vp8_epel8_h6, 6, 6 + npicregs, 14, dst, dststride, src, srcstride, height, mx, picreg
+     lea      mxd, [mxq*3]
+     shl      mxd, 4
+-%ifdef PIC
++%if PIC
+     lea  picregq, [sixtap_filter_v_m]
+ %endif
+     lea      mxq, [sixtap_filter_v+mxq-96]
+     pxor      m7, m7
+     mova      m6, [pw_64]
+ %ifdef m8
+     mova      m8, [mxq+ 0]
+     mova      m9, [mxq+16]
+@@ -538,17 +538,17 @@ cglobal put_vp8_epel8_h6, 6, 6 + npicreg
+     dec  heightd            ; next row
+     jg .nextrow
+     RET
+ 
+ %macro FILTER_V 1
+ ; 4x4 block, V-only 4-tap filter
+ cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my
+     shl      myd, 5
+-%ifdef PIC
++%if PIC
+     lea  picregq, [fourtap_filter_v_m]
+ %endif
+     lea      myq, [fourtap_filter_v+myq-32]
+     mova      m6, [pw_64]
+     pxor      m7, m7
+     mova      m5, [myq+48]
+ 
+     ; read 3 lines
+@@ -592,17 +592,17 @@ cglobal put_vp8_epel%1_v4, 7, 7, 8, dst,
+     jg .nextrow
+     RET
+ 
+ 
+ ; 4x4 block, V-only 6-tap filter
+ cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my
+     shl      myd, 4
+     lea      myq, [myq*3]
+-%ifdef PIC
++%if PIC
+     lea  picregq, [sixtap_filter_v_m]
+ %endif
+     lea      myq, [sixtap_filter_v+myq-96]
+     pxor      m7, m7
+ 
+     ; read 5 lines
+     sub     srcq, srcstrideq
+     sub     srcq, srcstrideq
+@@ -662,17 +662,17 @@ INIT_MMX mmxext
+ FILTER_V 4
+ INIT_XMM sse2
+ FILTER_V 8
+ 
+ %macro FILTER_BILINEAR 1
+ %if cpuflag(ssse3)
+ cglobal put_vp8_bilinear%1_v, 7, 7, 5, dst, dststride, src, srcstride, height, picreg, my
+     shl      myd, 4
+-%ifdef PIC
++%if PIC
+     lea  picregq, [bilinear_filter_vb_m]
+ %endif
+     pxor      m4, m4
+     mova      m3, [bilinear_filter_vb+myq-16]
+ .nextrow:
+     movh      m0, [srcq+srcstrideq*0]
+     movh      m1, [srcq+srcstrideq*1]
+     movh      m2, [srcq+srcstrideq*2]
+@@ -692,17 +692,17 @@ cglobal put_vp8_bilinear%1_v, 7, 7, 5, d
+ %else
+     packuswb  m0, m1
+     movh   [dstq+dststrideq*0], m0
+     movhps [dstq+dststrideq*1], m0
+ %endif
+ %else ; cpuflag(ssse3)
+ cglobal put_vp8_bilinear%1_v, 7, 7, 7, dst, dststride, src, srcstride, height, picreg, my
+     shl      myd, 4
+-%ifdef PIC
++%if PIC
+     lea  picregq, [bilinear_filter_vw_m]
+ %endif
+     pxor      m6, m6
+     mova      m5, [bilinear_filter_vw+myq-1*16]
+     neg      myq
+     mova      m4, [bilinear_filter_vw+myq+7*16]
+ .nextrow:
+     movh      m0, [srcq+srcstrideq*0]
+@@ -738,17 +738,17 @@ cglobal put_vp8_bilinear%1_v, 7, 7, 7, d
+     lea     srcq, [srcq+srcstrideq*2]
+     sub  heightd, 2
+     jg .nextrow
+     RET
+ 
+ %if cpuflag(ssse3)
+ cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 5, dst, dststride, src, srcstride, height, mx, picreg
+     shl      mxd, 4
+-%ifdef PIC
++%if PIC
+     lea  picregq, [bilinear_filter_vb_m]
+ %endif
+     pxor      m4, m4
+     mova      m2, [filter_h2_shuf]
+     mova      m3, [bilinear_filter_vb+mxq-16]
+ .nextrow:
+     movu      m0, [srcq+srcstrideq*0]
+     movu      m1, [srcq+srcstrideq*1]
+@@ -768,17 +768,17 @@ cglobal put_vp8_bilinear%1_h, 6, 6 + npi
+ %else
+     packuswb  m0, m1
+     movh   [dstq+dststrideq*0], m0
+     movhps [dstq+dststrideq*1], m0
+ %endif
+ %else ; cpuflag(ssse3)
+ cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, height, mx, picreg
+     shl      mxd, 4
+-%ifdef PIC
++%if PIC
+     lea  picregq, [bilinear_filter_vw_m]
+ %endif
+     pxor      m6, m6
+     mova      m5, [bilinear_filter_vw+mxq-1*16]
+     neg      mxq
+     mova      m4, [bilinear_filter_vw+mxq+7*16]
+ .nextrow:
+     movh      m0, [srcq+srcstrideq*0+0]
+diff --git a/media/ffvpx/libavcodec/x86/vp9itxfm.asm b/media/ffvpx/libavcodec/x86/vp9itxfm.asm
+--- a/media/ffvpx/libavcodec/x86/vp9itxfm.asm
++++ b/media/ffvpx/libavcodec/x86/vp9itxfm.asm
+@@ -325,17 +325,19 @@ IDCT_4x4_FN ssse3
+ ;-------------------------------------------------------------------------------------------
+ ; void vp9_iadst_iadst_4x4_add_<opt>(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
+ ;-------------------------------------------------------------------------------------------
+ 
+ %macro IADST4_FN 5
+ INIT_MMX %5
+ cglobal vp9_%1_%3_4x4_add, 3, 3, 0, dst, stride, block, eob
+ %if WIN64 && notcpuflag(ssse3)
++INIT_XMM cpuname
+     WIN64_SPILL_XMM 8
++INIT_MMX cpuname
+ %endif
+     movdqa            xmm5, [pd_8192]
+     mova                m0, [blockq+ 0]
+     mova                m1, [blockq+ 8]
+     mova                m2, [blockq+16]
+     mova                m3, [blockq+24]
+ %if cpuflag(ssse3)
+     mova                m6, [pw_11585x2]
+diff --git a/media/ffvpx/libavcodec/x86/vp9itxfm_16bpp.asm b/media/ffvpx/libavcodec/x86/vp9itxfm_16bpp.asm
+--- a/media/ffvpx/libavcodec/x86/vp9itxfm_16bpp.asm
++++ b/media/ffvpx/libavcodec/x86/vp9itxfm_16bpp.asm
+@@ -298,17 +298,19 @@ cglobal vp9_idct_idct_4x4_add_10, 4, 4, 
+ INIT_MMX mmxext
+ IDCT4_10_FN
+ INIT_MMX ssse3
+ IDCT4_10_FN
+ 
+ %macro IADST4_FN 4
+ cglobal vp9_%1_%3_4x4_add_10, 3, 3, 0, dst, stride, block, eob
+ %if WIN64 && notcpuflag(ssse3)
++INIT_XMM cpuname
+     WIN64_SPILL_XMM 8
++INIT_MMX cpuname
+ %endif
+     movdqa            xmm5, [pd_8192]
+     mova                m0, [blockq+0*16+0]
+     mova                m1, [blockq+1*16+0]
+     packssdw            m0, [blockq+0*16+8]
+     packssdw            m1, [blockq+1*16+8]
+     mova                m2, [blockq+2*16+0]
+     mova                m3, [blockq+3*16+0]
+@@ -667,17 +669,17 @@ cglobal vp9_idct_idct_8x8_add_10, 4, 6 +
+ 
+ .idctfull:
+     SCRATCH              0, 12, rsp+16*mmsize, max
+     DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak
+ %if ARCH_X86_64
+     mov            dstbakq, dstq
+     movsxd            cntq, cntd
+ %endif
+-%ifdef PIC
++%if PIC
+     lea               ptrq, [default_8x8]
+     movzx             cntd, byte [ptrq+cntq-1]
+ %else
+     movzx             cntd, byte [default_8x8+cntq-1]
+ %endif
+     mov              skipd, 2
+     sub              skipd, cntd
+     mov               ptrq, rsp
+@@ -916,17 +918,17 @@ cglobal vp9_%1_%3_8x8_add_10, 4, 6 + ARC
+ 
+ .body:
+     SCRATCH              0, 13, rsp+16*mmsize, max
+     DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak
+ %if ARCH_X86_64
+     mov            dstbakq, dstq
+     movsxd            cntq, cntd
+ %endif
+-%ifdef PIC
++%if PIC
+     lea               ptrq, [%5_8x8]
+     movzx             cntd, byte [ptrq+cntq-1]
+ %else
+     movzx             cntd, byte [%5_8x8+cntq-1]
+ %endif
+     mov              skipd, 2
+     sub              skipd, cntd
+     mov               ptrq, rsp
+@@ -1123,17 +1125,17 @@ cglobal vp9_idct_idct_16x16_add_10, 4, 6
+ 
+ .idctfull:
+     mova   [rsp+64*mmsize], m0
+     DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak
+ %if ARCH_X86_64
+     mov            dstbakq, dstq
+     movsxd            cntq, cntd
+ %endif
+-%ifdef PIC
++%if PIC
+     lea               ptrq, [default_16x16]
+     movzx             cntd, byte [ptrq+cntq-1]
+ %else
+     movzx             cntd, byte [default_16x16+cntq-1]
+ %endif
+     mov              skipd, 4
+     sub              skipd, cntd
+     mov               ptrq, rsp
+@@ -1440,17 +1442,17 @@ cglobal vp9_%1_%4_16x16_add_10, 4, 6 + A
+ 
+ .body:
+     mova   [rsp+64*mmsize], m0
+     DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak
+ %if ARCH_X86_64
+     mov            dstbakq, dstq
+     movsxd            cntq, cntd
+ %endif
+-%ifdef PIC
++%if PIC
+     lea               ptrq, [%7_16x16]
+     movzx             cntd, byte [ptrq+cntq-1]
+ %else
+     movzx             cntd, byte [%7_16x16+cntq-1]
+ %endif
+     mov              skipd, 4
+     sub              skipd, cntd
+     mov               ptrq, rsp
+@@ -1953,17 +1955,17 @@ cglobal vp9_idct_idct_32x32_add_10, 4, 6
+ 
+ .idctfull:
+     mova  [rsp+256*mmsize], m0
+     DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak
+ %if ARCH_X86_64
+     mov            dstbakq, dstq
+     movsxd            cntq, cntd
+ %endif
+-%ifdef PIC
++%if PIC
+     lea               ptrq, [default_32x32]
+     movzx             cntd, byte [ptrq+cntq-1]
+ %else
+     movzx             cntd, byte [default_32x32+cntq-1]
+ %endif
+     mov              skipd, 8
+     sub              skipd, cntd
+     mov               ptrq, rsp
+diff --git a/media/ffvpx/libavutil/aarch64/cpu.c b/media/ffvpx/libavutil/aarch64/cpu.c
+--- a/media/ffvpx/libavutil/aarch64/cpu.c
++++ b/media/ffvpx/libavutil/aarch64/cpu.c
+@@ -19,44 +19,30 @@
+ #include "libavutil/cpu.h"
+ #include "libavutil/cpu_internal.h"
+ #include "config.h"
+ 
+ #if (defined(__linux__) || defined(__ANDROID__)) && HAVE_GETAUXVAL
+ #include <stdint.h>
+ #include <sys/auxv.h>
+ 
+-#define get_cpu_feature_reg(reg, val) \
+-        __asm__("mrs %0, " #reg : "=r" (val))
++#define HWCAP_AARCH64_ASIMDDP (1 << 20)
++#define HWCAP2_AARCH64_I8MM   (1 << 13)
+ 
+ static int detect_flags(void)
+ {
+     int flags = 0;
+ 
+-#if defined(HWCAP_CPUID) && HAVE_INLINE_ASM
+     unsigned long hwcap = getauxval(AT_HWCAP);
+-    // We can check for DOTPROD and I8MM using HWCAP_ASIMDDP and
+-    // HWCAP2_I8MM too, avoiding to read the CPUID registers (which triggers
+-    // a trap, handled by the kernel). However the HWCAP_* defines for these
+-    // extensions are added much later than HWCAP_CPUID, so the userland
+-    // headers might lack support for them even if the binary later is run
+-    // on hardware that does support it (and where the kernel might support
+-    // HWCAP_CPUID).
+-    // See https://www.kernel.org/doc/html/latest/arm64/cpu-feature-registers.html
+-    if (hwcap & HWCAP_CPUID) {
+-        uint64_t tmp;
++    unsigned long hwcap2 = getauxval(AT_HWCAP2);
+ 
+-        get_cpu_feature_reg(ID_AA64ISAR0_EL1, tmp);
+-        if (((tmp >> 44) & 0xf) == 0x1)
+-            flags |= AV_CPU_FLAG_DOTPROD;
+-        get_cpu_feature_reg(ID_AA64ISAR1_EL1, tmp);
+-        if (((tmp >> 52) & 0xf) == 0x1)
+-            flags |= AV_CPU_FLAG_I8MM;
+-    }
+-#endif
++    if (hwcap & HWCAP_AARCH64_ASIMDDP)
++        flags |= AV_CPU_FLAG_DOTPROD;
++    if (hwcap2 & HWCAP2_AARCH64_I8MM)
++        flags |= AV_CPU_FLAG_I8MM;
+ 
+     return flags;
+ }
+ 
+ #elif defined(__APPLE__) && HAVE_SYSCTLBYNAME
+ #include <sys/sysctl.h>
+ 
+ static int detect_flags(void)
+diff --git a/media/ffvpx/libavutil/arm/float_dsp_init_vfp.c b/media/ffvpx/libavutil/arm/float_dsp_init_vfp.c
+--- a/media/ffvpx/libavutil/arm/float_dsp_init_vfp.c
++++ b/media/ffvpx/libavutil/arm/float_dsp_init_vfp.c
+@@ -27,17 +27,17 @@ void ff_vector_fmul_vfp(float *dst, cons
+                         int len);
+ 
+ void ff_vector_fmul_window_vfp(float *dst, const float *src0,
+                                const float *src1, const float *win, int len);
+ 
+ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
+                                 const float *src1, int len);
+ 
+-void ff_butterflies_float_vfp(float *av_restrict v1, float *av_restrict v2, int len);
++void ff_butterflies_float_vfp(float *restrict v1, float *restrict v2, int len);
+ 
+ av_cold void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags)
+ {
+     if (have_vfp_vm(cpu_flags)) {
+         fdsp->vector_fmul = ff_vector_fmul_vfp;
+         fdsp->vector_fmul_window = ff_vector_fmul_window_vfp;
+     }
+     fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
+diff --git a/media/ffvpx/libavutil/avstring.c b/media/ffvpx/libavutil/avstring.c
+--- a/media/ffvpx/libavutil/avstring.c
++++ b/media/ffvpx/libavutil/avstring.c
+@@ -340,17 +340,17 @@ int av_escape(char **dst, const char *sr
+     if ((ret = av_bprint_finalize(&dstbuf, dst)) < 0)
+         return ret;
+     return dstbuf.len;
+ }
+ 
+ int av_match_name(const char *name, const char *names)
+ {
+     const char *p;
+-    int len, namelen;
++    size_t len, namelen;
+ 
+     if (!name || !names)
+         return 0;
+ 
+     namelen = strlen(name);
+     while (*names) {
+         int negate = '-' == *names;
+         p = strchr(names, ',');
+diff --git a/media/ffvpx/libavutil/avutil.h b/media/ffvpx/libavutil/avutil.h
+--- a/media/ffvpx/libavutil/avutil.h
++++ b/media/ffvpx/libavutil/avutil.h
+@@ -330,29 +330,16 @@ unsigned av_int_list_length_for_size(uns
+  *
+  * @param term  list terminator (usually 0 or -1)
+  * @param list  pointer to the list
+  * @return  length of the list, in elements, not counting the terminator
+  */
+ #define av_int_list_length(list, term) \
+     av_int_list_length_for_size(sizeof(*(list)), list, term)
+ 
+-#if FF_API_AV_FOPEN_UTF8
+-/**
+- * Open a file using a UTF-8 filename.
+- * The API of this function matches POSIX fopen(), errors are returned through
+- * errno.
+- * @deprecated Avoid using it, as on Windows, the FILE* allocated by this
+- *             function may be allocated with a different CRT than the caller
+- *             who uses the FILE*. No replacement provided in public API.
+- */
+-attribute_deprecated
+-FILE *av_fopen_utf8(const char *path, const char *mode);
+-#endif
+-
+ /**
+  * Return the fractional representation of the internal time base.
+  */
+ AVRational av_get_time_base_q(void);
+ 
+ #define AV_FOURCC_MAX_STRING_SIZE 32
+ 
+ #define av_fourcc2str(fourcc) av_fourcc_make_string((char[AV_FOURCC_MAX_STRING_SIZE]){0}, fourcc)
+diff --git a/media/ffvpx/libavutil/avutil.symbols b/media/ffvpx/libavutil/avutil.symbols
+--- a/media/ffvpx/libavutil/avutil.symbols
++++ b/media/ffvpx/libavutil/avutil.symbols
+@@ -3,17 +3,16 @@ av_add_stable
+ av_append_path_component
+ av_asprintf
+ av_basename
+ #ifndef MOZ_FFVPX_AUDIOONLY
+ av_base64_decode
+ av_base64_encode
+ #endif
+ av_bprint_append_data
+-av_bprint_channel_layout
+ av_bprint_chars
+ av_bprint_clear
+ av_bprint_escape
+ av_bprint_finalize
+ av_bprint_get_buffer
+ av_bprint_init
+ av_bprint_init_for_buffer
+ av_bprint_strftime
+@@ -34,32 +33,29 @@ av_buffer_replace
+ av_buffer_ref
+ av_buffer_unref
+ av_calloc
+ av_channel_layout_check
+ av_channel_layout_compare
+ av_channel_layout_copy
+ av_channel_layout_default
+ av_channel_layout_describe
+-av_channel_layout_extract_channel
+ av_channel_layout_from_mask
+ av_channel_layout_from_mask
+ av_channel_layout_uninit
+ av_chroma_location_name
+ av_chroma_location_enum_to_pos
+ av_chroma_location_pos_to_enum
+ av_color_primaries_name
+ av_color_range_name
+ av_color_space_name
+ av_color_transfer_name
+ av_compare_mod
+ av_compare_ts
+-#ifndef MOZ_FFVPX_AUDIOONLY
+ av_content_light_metadata_create_side_data
+-#endif
+ av_cpu_count
+ av_crc
+ av_crc_get_table
+ av_crc_init
+ av_d2q
+ av_default_get_category
+ av_default_item_name
+ av_dict_copy
+@@ -83,50 +79,39 @@ av_dynarray_add_nofree
+ av_escape
+ av_expr_eval
+ av_expr_free
+ av_expr_parse
+ av_expr_parse_and_eval
+ av_fast_malloc
+ av_fast_mallocz
+ av_fast_realloc
+-av_fifo_alloc
+ av_fifo_alloc2
+-av_fifo_alloc_array
+ av_fifo_can_read
+ av_fifo_can_write
+-av_fifo_drain
+ av_fifo_drain2
+-av_fifo_free
+-av_fifo_freep
+ av_fifo_freep2
+-av_fifo_generic_peek
+-av_fifo_generic_read
+-av_fifo_generic_write
+-av_fifo_grow
+ av_fifo_peek
+-av_fifo_realloc2
+ av_fifo_read
+-av_fifo_reset
+-av_fifo_size
+-av_fifo_space
+ av_fifo_write
+ av_find_best_pix_fmt_of_2
+ av_find_info_tag
+ av_find_nearest_q_idx
+ #ifndef MOZ_FFVPX_AUDIOONLY
+ av_film_grain_params_create_side_data
+ #endif
+ av_force_cpu_flags
+ av_fourcc_make_string
+ av_frame_alloc
+ av_frame_apply_cropping
+ av_frame_clone
+ av_frame_copy
+ av_frame_copy_props
++av_frame_side_data_free
++av_frame_side_data_get_c
+ av_frame_free
+ av_frame_get_buffer
+ av_frame_get_plane_buffer
+ av_frame_get_side_data
+ av_frame_is_writable
+ av_frame_make_writable
+ av_frame_move_ref
+ av_frame_new_side_data
+@@ -137,37 +122,29 @@ av_frame_replace
+ av_frame_side_data_name
+ av_frame_unref
+ av_free
+ av_freep
+ av_gcd
+ av_get_alt_sample_fmt
+ av_get_bits_per_pixel
+ av_get_bytes_per_sample
+-av_get_channel_description
+-av_get_channel_layout
+-av_get_channel_layout_channel_index
+-av_get_channel_layout_nb_channels
+-av_get_channel_layout_string
+-av_get_channel_name
+ av_get_cpu_flags
+-av_get_default_channel_layout
+ av_get_known_color_name
+ av_get_media_type_string
+ av_get_packed_sample_fmt
+ av_get_padded_bits_per_pixel
+ av_get_picture_type_char
+ av_get_pix_fmt
+ av_get_pix_fmt_loss
+ av_get_pix_fmt_name
+ av_get_pix_fmt_string
+ av_get_planar_sample_fmt
+ av_get_sample_fmt
+ av_get_sample_fmt_string
+-av_get_standard_channel_layout
+ av_get_time_base_q
+ av_get_token
+ av_gettime
+ av_gettime_relative
+ av_gettime_relative_is_monotonic
+ av_hwdevice_get_hwframe_constraints
+ av_hwdevice_hwconfig_alloc
+ av_hwframe_constraints_free
+@@ -196,19 +173,17 @@ av_log_default_callback
+ av_log_format_line
+ av_log_get_flags
+ av_log_get_level
+ av_log_set_callback
+ av_log_set_flags
+ av_log_set_level
+ av_mallocz
+ av_malloc
+-#ifndef MOZ_FFVPX_AUDIOONLY
+ av_mastering_display_metadata_create_side_data
+-#endif
+ av_match_list
+ av_match_name
+ av_max_alloc
+ av_memcpy_backptr
+ av_memdup
+ av_mul_q
+ av_nearer_q
+ av_opt_child_next
+@@ -220,17 +195,16 @@ av_opt_eval_int
+ av_opt_eval_int64
+ av_opt_eval_q
+ av_opt_find
+ av_opt_find2
+ av_opt_flag_is_set
+ av_opt_free
+ av_opt_freep_ranges
+ av_opt_get
+-av_opt_get_channel_layout
+ av_opt_get_dict_val
+ av_opt_get_double
+ av_opt_get_image_size
+ av_opt_get_int
+ av_opt_get_key_value
+ av_opt_get_pixel_fmt
+ av_opt_get_q
+ av_opt_get_sample_fmt
+@@ -239,17 +213,16 @@ av_opt_is_set_to_default
+ av_opt_is_set_to_default_by_name
+ av_opt_next
+ av_opt_ptr
+ av_opt_query_ranges
+ av_opt_query_ranges_default
+ av_opt_serialize
+ av_opt_set
+ av_opt_set_bin
+-av_opt_set_channel_layout
+ av_opt_set_defaults
+ av_opt_set_defaults2
+ av_opt_set_dict
+ av_opt_set_dict2
+ av_opt_set_dict_val
+ av_opt_set_double
+ av_opt_set_from_string
+ av_opt_set_image_size
+diff --git a/media/ffvpx/libavutil/bprint.h b/media/ffvpx/libavutil/bprint.h
+--- a/media/ffvpx/libavutil/bprint.h
++++ b/media/ffvpx/libavutil/bprint.h
+@@ -167,29 +167,29 @@ void av_vbprintf(AVBPrint *buf, const ch
+ /**
+  * Append char c n times to a print buffer.
+  */
+ void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
+ 
+ /**
+  * Append data to a print buffer.
+  *
+- * param buf  bprint buffer to use
+- * param data pointer to data
+- * param size size of data
++ * @param buf  bprint buffer to use
++ * @param data pointer to data
++ * @param size size of data
+  */
+ void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size);
+ 
+ struct tm;
+ /**
+  * Append a formatted date and time to a print buffer.
+  *
+- * param buf  bprint buffer to use
+- * param fmt  date and time format string, see strftime()
+- * param tm   broken-down time structure to translate
++ * @param buf  bprint buffer to use
++ * @param fmt  date and time format string, see strftime()
++ * @param tm   broken-down time structure to translate
+  *
+  * @note due to poor design of the standard strftime function, it may
+  * produce poor results if the format string expands to a very long text and
+  * the bprint buffer is near the limit stated by the size_max option.
+  */
+ void av_bprint_strftime(AVBPrint *buf, const char *fmt, const struct tm *tm);
+ 
+ /**
+diff --git a/media/ffvpx/libavutil/channel_layout.c b/media/ffvpx/libavutil/channel_layout.c
+--- a/media/ffvpx/libavutil/channel_layout.c
++++ b/media/ffvpx/libavutil/channel_layout.c
+@@ -28,16 +28,17 @@
+ #include <string.h>
+ 
+ #include "avassert.h"
+ #include "channel_layout.h"
+ #include "bprint.h"
+ #include "common.h"
+ #include "error.h"
+ #include "macros.h"
++#include "mem.h"
+ #include "opt.h"
+ 
+ #define CHAN_IS_AMBI(x) ((x) >= AV_CHAN_AMBISONIC_BASE &&\
+                          (x) <= AV_CHAN_AMBISONIC_END)
+ 
+ struct channel_name {
+     const char *name;
+     const char *description;
+@@ -71,34 +72,30 @@ static const struct channel_name channel
+     [AV_CHAN_LOW_FREQUENCY_2      ] = { "LFE2",      "low frequency 2"       },
+     [AV_CHAN_TOP_SIDE_LEFT        ] = { "TSL",       "top side left"         },
+     [AV_CHAN_TOP_SIDE_RIGHT       ] = { "TSR",       "top side right"        },
+     [AV_CHAN_BOTTOM_FRONT_CENTER  ] = { "BFC",       "bottom front center"   },
+     [AV_CHAN_BOTTOM_FRONT_LEFT    ] = { "BFL",       "bottom front left"     },
+     [AV_CHAN_BOTTOM_FRONT_RIGHT   ] = { "BFR",       "bottom front right"    },
+ };
+ 
+-static const char *get_channel_name(enum AVChannel channel_id)
+-{
+-    if ((unsigned) channel_id >= FF_ARRAY_ELEMS(channel_names) ||
+-        !channel_names[channel_id].name)
+-        return NULL;
+-    return channel_names[channel_id].name;
+-}
+-
+ void av_channel_name_bprint(AVBPrint *bp, enum AVChannel channel_id)
+ {
+     if (channel_id >= AV_CHAN_AMBISONIC_BASE &&
+         channel_id <= AV_CHAN_AMBISONIC_END)
+         av_bprintf(bp, "AMBI%d", channel_id - AV_CHAN_AMBISONIC_BASE);
+     else if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names) &&
+              channel_names[channel_id].name)
+         av_bprintf(bp, "%s", channel_names[channel_id].name);
+     else if (channel_id == AV_CHAN_NONE)
+         av_bprintf(bp, "NONE");
++    else if (channel_id == AV_CHAN_UNKNOWN)
++        av_bprintf(bp, "UNK");
++    else if (channel_id == AV_CHAN_UNUSED)
++        av_bprintf(bp, "UNSD");
+     else
+         av_bprintf(bp, "USR%d", channel_id);
+ }
+ 
+ int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id)
+ {
+     AVBPrint bp;
+ 
+@@ -118,16 +115,20 @@ void av_channel_description_bprint(AVBPr
+     if (channel_id >= AV_CHAN_AMBISONIC_BASE &&
+         channel_id <= AV_CHAN_AMBISONIC_END)
+         av_bprintf(bp, "ambisonic ACN %d", channel_id - AV_CHAN_AMBISONIC_BASE);
+     else if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names) &&
+              channel_names[channel_id].description)
+         av_bprintf(bp, "%s", channel_names[channel_id].description);
+     else if (channel_id == AV_CHAN_NONE)
+         av_bprintf(bp, "none");
++    else if (channel_id == AV_CHAN_UNKNOWN)
++        av_bprintf(bp, "unknown");
++    else if (channel_id == AV_CHAN_UNUSED)
++        av_bprintf(bp, "unused");
+     else
+         av_bprintf(bp, "user %d", channel_id);
+ }
+ 
+ int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel_id)
+ {
+     AVBPrint bp;
+ 
+@@ -154,16 +155,21 @@ enum AVChannel av_channel_from_string(co
+             return AV_CHAN_NONE;
+         return AV_CHAN_AMBISONIC_BASE + i;
+     }
+ 
+     for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
+         if (channel_names[i].name && !strcmp(str, channel_names[i].name))
+             return i;
+     }
++    if (!strcmp(str, "UNK"))
++        return AV_CHAN_UNKNOWN;
++    if (!strcmp(str, "UNSD"))
++        return AV_CHAN_UNUSED;
++
+     if (!strncmp(str, "USR", 3)) {
+         const char *p = str + 3;
+         id = strtol(p, &endptr, 0);
+     }
+     if (id >= 0 && !*endptr)
+         return id;
+ 
+     return AV_CHAN_NONE;
+@@ -209,231 +215,116 @@ static const struct channel_layout_name 
+     { "7.1.4",          AV_CHANNEL_LAYOUT_7POINT1POINT4_BACK  },
+     { "7.2.3",          AV_CHANNEL_LAYOUT_7POINT2POINT3       },
+     { "9.1.4",          AV_CHANNEL_LAYOUT_9POINT1POINT4_BACK  },
+     { "hexadecagonal",  AV_CHANNEL_LAYOUT_HEXADECAGONAL       },
+     { "downmix",        AV_CHANNEL_LAYOUT_STEREO_DOWNMIX,     },
+     { "22.2",           AV_CHANNEL_LAYOUT_22POINT2,           },
+ };
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-static uint64_t get_channel_layout_single(const char *name, int name_len)
+-{
+-    int i;
+-    char *end;
+-    int64_t layout;
+-
+-    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
+-        if (strlen(channel_layout_map[i].name) == name_len &&
+-            !memcmp(channel_layout_map[i].name, name, name_len))
+-            return channel_layout_map[i].layout.u.mask;
+-    }
+-    for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
+-        if (channel_names[i].name &&
+-            strlen(channel_names[i].name) == name_len &&
+-            !memcmp(channel_names[i].name, name, name_len))
+-            return (int64_t)1 << i;
+-
+-    errno = 0;
+-    i = strtol(name, &end, 10);
+-
+-    if (!errno && (end + 1 - name == name_len && *end  == 'c'))
+-        return av_get_default_channel_layout(i);
+-
+-    errno = 0;
+-    layout = strtoll(name, &end, 0);
+-    if (!errno && end - name == name_len)
+-        return FFMAX(layout, 0);
+-    return 0;
+-}
+-
+-uint64_t av_get_channel_layout(const char *name)
++int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels)
+ {
+-    const char *n, *e;
+-    const char *name_end = name + strlen(name);
+-    int64_t layout = 0, layout_single;
+-
+-    for (n = name; n < name_end; n = e + 1) {
+-        for (e = n; e < name_end && *e != '+' && *e != '|'; e++);
+-        layout_single = get_channel_layout_single(n, e - n);
+-        if (!layout_single)
+-            return 0;
+-        layout |= layout_single;
+-    }
+-    return layout;
+-}
+-
+-int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels)
+-{
+-    int nb = 0;
+-    char *end;
+-    uint64_t layout = av_get_channel_layout(name);
+-
+-    if (layout) {
+-        *channel_layout = layout;
+-        *nb_channels = av_get_channel_layout_nb_channels(layout);
+-        return 0;
+-    }
+-
+-    nb = strtol(name, &end, 10);
+-    if (!errno && *end  == 'C' && *(end + 1) == '\0' && nb > 0 && nb < 64) {
+-        *channel_layout = 0;
+-        *nb_channels = nb;
+-        return 0;
+-    }
+-
+-    return AVERROR(EINVAL);
+-}
+-
+-void av_bprint_channel_layout(struct AVBPrint *bp,
+-                              int nb_channels, uint64_t channel_layout)
+-{
+-    int i;
++    AVChannelCustom *map;
+ 
+     if (nb_channels <= 0)
+-        nb_channels = av_get_channel_layout_nb_channels(channel_layout);
+-
+-    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
+-        if (nb_channels    == channel_layout_map[i].layout.nb_channels &&
+-            channel_layout == channel_layout_map[i].layout.u.mask) {
+-            av_bprintf(bp, "%s", channel_layout_map[i].name);
+-            return;
+-        }
++        return AVERROR(EINVAL);
+ 
+-    av_bprintf(bp, "%d channels", nb_channels);
+-    if (channel_layout) {
+-        int i, ch;
+-        av_bprintf(bp, " (");
+-        for (i = 0, ch = 0; i < 64; i++) {
+-            if ((channel_layout & (UINT64_C(1) << i))) {
+-                const char *name = get_channel_name(i);
+-                if (name) {
+-                    if (ch > 0)
+-                        av_bprintf(bp, "+");
+-                    av_bprintf(bp, "%s", name);
+-                }
+-                ch++;
+-            }
+-        }
+-        av_bprintf(bp, ")");
+-    }
+-}
++    map = av_calloc(nb_channels, sizeof(*channel_layout->u.map));
++    if (!map)
++        return AVERROR(ENOMEM);
++    for (int i = 0; i < nb_channels; i++)
++        map[i].id = AV_CHAN_UNKNOWN;
+ 
+-void av_get_channel_layout_string(char *buf, int buf_size,
+-                                  int nb_channels, uint64_t channel_layout)
+-{
+-    AVBPrint bp;
+-
+-    av_bprint_init_for_buffer(&bp, buf, buf_size);
+-    av_bprint_channel_layout(&bp, nb_channels, channel_layout);
+-}
++    channel_layout->order       = AV_CHANNEL_ORDER_CUSTOM;
++    channel_layout->nb_channels = nb_channels;
++    channel_layout->u.map       = map;
+ 
+-int av_get_channel_layout_nb_channels(uint64_t channel_layout)
+-{
+-    return av_popcount64(channel_layout);
+-}
+-
+-int64_t av_get_default_channel_layout(int nb_channels) {
+-    int i;
+-    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
+-        if (nb_channels == channel_layout_map[i].layout.nb_channels)
+-            return channel_layout_map[i].layout.u.mask;
+     return 0;
+ }
+ 
+-int av_get_channel_layout_channel_index(uint64_t channel_layout,
+-                                        uint64_t channel)
+-{
+-    if (!(channel_layout & channel) ||
+-        av_get_channel_layout_nb_channels(channel) != 1)
+-        return AVERROR(EINVAL);
+-    channel_layout &= channel - 1;
+-    return av_get_channel_layout_nb_channels(channel_layout);
+-}
+-
+-const char *av_get_channel_name(uint64_t channel)
+-{
+-    int i;
+-    if (av_get_channel_layout_nb_channels(channel) != 1)
+-        return NULL;
+-    for (i = 0; i < 64; i++)
+-        if ((1ULL<<i) & channel)
+-            return get_channel_name(i);
+-    return NULL;
+-}
+-
+-const char *av_get_channel_description(uint64_t channel)
+-{
+-    int i;
+-    if (av_get_channel_layout_nb_channels(channel) != 1)
+-        return NULL;
+-    for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
+-        if ((1ULL<<i) & channel)
+-            return channel_names[i].description;
+-    return NULL;
+-}
+-
+-uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
+-{
+-    int i;
+-
+-    if (av_get_channel_layout_nb_channels(channel_layout) <= index)
+-        return 0;
+-
+-    for (i = 0; i < 64; i++) {
+-        if ((1ULL << i) & channel_layout && !index--)
+-            return 1ULL << i;
+-    }
+-    return 0;
+-}
+-
+-int av_get_standard_channel_layout(unsigned index, uint64_t *layout,
+-                                   const char **name)
+-{
+-    if (index >= FF_ARRAY_ELEMS(channel_layout_map))
+-        return AVERROR_EOF;
+-    if (layout) *layout = channel_layout_map[index].layout.u.mask;
+-    if (name)   *name   = channel_layout_map[index].name;
+-    return 0;
+-}
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+ int av_channel_layout_from_mask(AVChannelLayout *channel_layout,
+                                 uint64_t mask)
+ {
+     if (!mask)
+         return AVERROR(EINVAL);
+ 
+     channel_layout->order       = AV_CHANNEL_ORDER_NATIVE;
+     channel_layout->nb_channels = av_popcount64(mask);
+     channel_layout->u.mask      = mask;
+ 
+     return 0;
+ }
+ 
++static int parse_channel_list(AVChannelLayout *ch_layout, const char *str)
++{
++    int ret;
++    int nb_channels = 0;
++    AVChannelCustom *map = NULL;
++    AVChannelCustom custom = {0};
++
++    while (*str) {
++        char *channel, *chname;
++        int ret = av_opt_get_key_value(&str, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname);
++        if (ret < 0) {
++            av_freep(&map);
++            return ret;
++        }
++        if (*str)
++            str++; // skip separator
++        if (!channel) {
++            channel = chname;
++            chname = NULL;
++        }
++        av_strlcpy(custom.name, chname ? chname : "", sizeof(custom.name));
++        custom.id = av_channel_from_string(channel);
++        av_free(channel);
++        av_free(chname);
++        if (custom.id == AV_CHAN_NONE) {
++            av_freep(&map);
++            return AVERROR(EINVAL);
++        }
++
++        av_dynarray2_add((void **)&map, &nb_channels, sizeof(custom), (void *)&custom);
++        if (!map)
++            return AVERROR(ENOMEM);
++    }
++
++    if (!nb_channels)
++        return AVERROR(EINVAL);
++
++    ch_layout->order = AV_CHANNEL_ORDER_CUSTOM;
++    ch_layout->u.map = map;
++    ch_layout->nb_channels = nb_channels;
++
++    ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
++    av_assert0(ret == 0);
++
++    return 0;
++}
++
+ int av_channel_layout_from_string(AVChannelLayout *channel_layout,
+                                   const char *str)
+ {
+-    int i;
+-    int channels = 0, nb_channels = 0, native = 1;
+-    enum AVChannel highest_channel = AV_CHAN_NONE;
+-    const char *dup;
++    int i, matches, ret;
++    int channels = 0, nb_channels = 0;
+     char *chlist, *end;
+     uint64_t mask = 0;
+ 
+     /* channel layout names */
+     for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
+         if (channel_layout_map[i].name && !strcmp(str, channel_layout_map[i].name)) {
+             *channel_layout = channel_layout_map[i].layout;
+             return 0;
+         }
+     }
+ 
++    /* This function is a channel layout initializer, so we have to
++     * zero-initialize before we start setting fields individually. */
++    memset(channel_layout, 0, sizeof(*channel_layout));
++
+     /* ambisonic */
+     if (!strncmp(str, "ambisonic ", 10)) {
+         const char *p = str + 10;
+         char *endptr;
+         AVChannelLayout extra = {0};
+         int order;
+ 
+         order = strtol(p, &endptr, 0);
+@@ -465,16 +356,17 @@ int av_channel_layout_from_string(AVChan
+                     return AVERROR(ENOMEM);
+                 }
+ 
+                 for (i = 0; i < channel_layout->nb_channels; i++)
+                     channel_layout->u.map[i].id = AV_CHAN_AMBISONIC_BASE + i;
+                 for (i = 0; i < extra.nb_channels; i++) {
+                     enum AVChannel ch = av_channel_layout_channel_from_index(&extra, i);
+                     if (CHAN_IS_AMBI(ch)) {
++                        av_channel_layout_uninit(channel_layout);
+                         av_channel_layout_uninit(&extra);
+                         return AVERROR(EINVAL);
+                     }
+                     channel_layout->u.map[channel_layout->nb_channels + i].id = ch;
+                     if (extra.order == AV_CHANNEL_ORDER_CUSTOM &&
+                         extra.u.map[i].name[0])
+                         av_strlcpy(channel_layout->u.map[channel_layout->nb_channels + i].name,
+                                    extra.u.map[i].name,
+@@ -488,132 +380,31 @@ int av_channel_layout_from_string(AVChan
+         return 0;
+     }
+ 
+     chlist = av_strdup(str);
+     if (!chlist)
+         return AVERROR(ENOMEM);
+ 
+     /* channel names */
+-    av_sscanf(str, "%d channels (%[^)]", &nb_channels, chlist);
+-    end = strchr(str, ')');
+-
+-    dup = chlist;
+-    while (*dup) {
+-        char *channel, *chname;
+-        int ret = av_opt_get_key_value(&dup, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname);
+-        if (ret < 0) {
+-            av_free(chlist);
+-            return ret;
+-        }
+-        if (*dup)
+-            dup++; // skip separator
+-        if (channel && !*channel)
+-            av_freep(&channel);
+-        for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
+-            if (channel_names[i].name && !strcmp(channel ? channel : chname, channel_names[i].name)) {
+-                if (channel || i < highest_channel || mask & (1ULL << i))
+-                    native = 0; // Not a native layout, use a custom one
+-                highest_channel = i;
+-                mask |= 1ULL << i;
+-                break;
+-            }
+-        }
+-
+-        if (!channel && i >= FF_ARRAY_ELEMS(channel_names)) {
+-            char *endptr = chname;
+-            enum AVChannel id = AV_CHAN_NONE;
++    matches = av_sscanf(str, "%d channels (%[^)]", &nb_channels, chlist);
++    ret = parse_channel_list(channel_layout, chlist);
++    av_freep(&chlist);
++    if (ret < 0 && ret != AVERROR(EINVAL))
++        return ret;
+ 
+-            if (!strncmp(chname, "USR", 3)) {
+-                const char *p = chname + 3;
+-                id = strtol(p, &endptr, 0);
+-            }
+-            if (id < 0 || *endptr) {
+-                native = 0; // Unknown channel name
+-                channels = 0;
+-                mask = 0;
+-                av_free(chname);
+-                break;
+-            }
+-            if (id > 63)
+-                native = 0; // Not a native layout, use a custom one
+-            else {
+-                if (id < highest_channel || mask & (1ULL << id))
+-                    native = 0; // Not a native layout, use a custom one
+-                highest_channel = id;
+-                mask |= 1ULL << id;
+-            }
++    if (ret >= 0) {
++        end = strchr(str, ')');
++        if (matches == 2 && (nb_channels != channel_layout->nb_channels || !end || *++end)) {
++            av_channel_layout_uninit(channel_layout);
++            return AVERROR(EINVAL);
+         }
+-        channels++;
+-        av_free(channel);
+-        av_free(chname);
+-    }
+-
+-    if (mask && native) {
+-        av_free(chlist);
+-        if (nb_channels && ((nb_channels != channels) || (!end || *++end)))
+-            return AVERROR(EINVAL);
+-        av_channel_layout_from_mask(channel_layout, mask);
+         return 0;
+     }
+ 
+-    /* custom layout of channel names */
+-    if (channels && !native) {
+-        int idx = 0;
+-
+-        if (nb_channels && ((nb_channels != channels) || (!end || *++end))) {
+-            av_free(chlist);
+-            return AVERROR(EINVAL);
+-        }
+-
+-        channel_layout->u.map = av_calloc(channels, sizeof(*channel_layout->u.map));
+-        if (!channel_layout->u.map) {
+-            av_free(chlist);
+-            return AVERROR(ENOMEM);
+-        }
+-
+-        channel_layout->order = AV_CHANNEL_ORDER_CUSTOM;
+-        channel_layout->nb_channels = channels;
+-
+-        dup = chlist;
+-        while (*dup) {
+-            char *channel, *chname;
+-            int ret = av_opt_get_key_value(&dup, "@", "+", AV_OPT_FLAG_IMPLICIT_KEY, &channel, &chname);
+-            if (ret < 0) {
+-                av_freep(&channel_layout->u.map);
+-                av_free(chlist);
+-                return ret;
+-            }
+-            if (*dup)
+-                dup++; // skip separator
+-            for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
+-                if (channel_names[i].name && !strcmp(channel ? channel : chname, channel_names[i].name)) {
+-                    channel_layout->u.map[idx].id = i;
+-                    if (channel)
+-                        av_strlcpy(channel_layout->u.map[idx].name, chname, sizeof(channel_layout->u.map[idx].name));
+-                    idx++;
+-                    break;
+-                }
+-            }
+-            if (i >= FF_ARRAY_ELEMS(channel_names)) {
+-                const char *p = (channel ? channel : chname) + 3;
+-                channel_layout->u.map[idx].id = strtol(p, NULL, 0);
+-                if (channel)
+-                    av_strlcpy(channel_layout->u.map[idx].name, chname, sizeof(channel_layout->u.map[idx].name));
+-                idx++;
+-            }
+-            av_free(channel);
+-            av_free(chname);
+-        }
+-        av_free(chlist);
+-
+-        return 0;
+-    }
+-    av_freep(&chlist);
+-
+     errno = 0;
+     mask = strtoull(str, &end, 0);
+ 
+     /* channel layout mask */
+     if (!errno && !*end && !strchr(str, '-') && mask) {
+         av_channel_layout_from_mask(channel_layout, mask);
+         return 0;
+     }
+@@ -654,16 +445,39 @@ int av_channel_layout_copy(AVChannelLayo
+         dst->u.map = av_malloc_array(src->nb_channels, sizeof(*dst->u.map));
+         if (!dst->u.map)
+             return AVERROR(ENOMEM);
+         memcpy(dst->u.map, src->u.map, src->nb_channels * sizeof(*src->u.map));
+     }
+     return 0;
+ }
+ 
++static int64_t masked_description(const AVChannelLayout *channel_layout, int start_channel)
++{
++    uint64_t mask = 0;
++    for (int i = start_channel; i < channel_layout->nb_channels; i++) {
++        enum AVChannel ch = channel_layout->u.map[i].id;
++        if (ch >= 0 && ch < 63 && mask < (1ULL << ch))
++            mask |= (1ULL << ch);
++        else
++            return AVERROR(EINVAL);
++    }
++    return mask;
++}
++
++static int has_channel_names(const AVChannelLayout *channel_layout)
++{
++    if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM)
++        return 0;
++    for (int i = 0; i < channel_layout->nb_channels; i++)
++        if (channel_layout->u.map[i].name[0])
++            return 1;
++    return 0;
++}
++
+ /**
+  * If the layout is n-th order standard-order ambisonic, with optional
+  * extra non-diegetic channels at the end, return the order.
+  * Return a negative error code otherwise.
+  */
+ static int ambisonic_order(const AVChannelLayout *channel_layout)
+ {
+     int i, highest_ambi, order;
+@@ -697,16 +511,43 @@ static int ambisonic_order(const AVChann
+     order = floor(sqrt(highest_ambi));
+     /* incomplete order - some harmonics are missing */
+     if ((order + 1) * (order + 1) != highest_ambi + 1)
+         return AVERROR(EINVAL);
+ 
+     return order;
+ }
+ 
++static enum AVChannelOrder canonical_order(AVChannelLayout *channel_layout)
++{
++    int has_known_channel = 0;
++    int order;
++
++    if (channel_layout->order != AV_CHANNEL_ORDER_CUSTOM)
++        return channel_layout->order;
++
++    if (has_channel_names(channel_layout))
++        return AV_CHANNEL_ORDER_CUSTOM;
++
++    for (int i = 0; i < channel_layout->nb_channels && !has_known_channel; i++)
++        if (channel_layout->u.map[i].id != AV_CHAN_UNKNOWN)
++            has_known_channel = 1;
++    if (!has_known_channel)
++        return AV_CHANNEL_ORDER_UNSPEC;
++
++    if (masked_description(channel_layout, 0) > 0)
++        return AV_CHANNEL_ORDER_NATIVE;
++
++    order = ambisonic_order(channel_layout);
++    if (order >= 0 && masked_description(channel_layout, (order + 1) * (order + 1)) >= 0)
++        return AV_CHANNEL_ORDER_AMBISONIC;
++
++    return AV_CHANNEL_ORDER_CUSTOM;
++}
++
+ /**
+  * If the custom layout is n-th order standard-order ambisonic, with optional
+  * extra non-diegetic channels at the end, write its string description in bp.
+  * Return a negative error code otherwise.
+  */
+ static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout)
+ {
+     int nb_ambi_channels;
+@@ -721,19 +562,27 @@ static int try_describe_ambisonic(AVBPri
+     if (nb_ambi_channels < channel_layout->nb_channels) {
+         AVChannelLayout extra = { 0 };
+ 
+         if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) {
+             extra.order       = AV_CHANNEL_ORDER_NATIVE;
+             extra.nb_channels = av_popcount64(channel_layout->u.mask);
+             extra.u.mask      = channel_layout->u.mask;
+         } else {
+-            extra.order       = AV_CHANNEL_ORDER_CUSTOM;
+-            extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels;
+-            extra.u.map       = channel_layout->u.map + nb_ambi_channels;
++            int64_t mask;
++            if (!has_channel_names(channel_layout) &&
++                (mask = masked_description(channel_layout, nb_ambi_channels)) > 0) {
++                extra.order       = AV_CHANNEL_ORDER_NATIVE;
++                extra.nb_channels = av_popcount64(mask);
++                extra.u.mask      = mask;
++            } else {
++                extra.order       = AV_CHANNEL_ORDER_CUSTOM;
++                extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels;
++                extra.u.map       = channel_layout->u.map + nb_ambi_channels;
++            }
+         }
+ 
+         av_bprint_chars(bp, '+', 1);
+         av_channel_layout_describe_bprint(&extra, bp);
+         /* Not calling uninit here on extra because we don't own the u.map pointer */
+     }
+ 
+     return 0;
+@@ -749,19 +598,27 @@ int av_channel_layout_describe_bprint(co
+         for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
+             if (channel_layout->u.mask == channel_layout_map[i].layout.u.mask) {
+                 av_bprintf(bp, "%s", channel_layout_map[i].name);
+                 return 0;
+             }
+         // fall-through
+     case AV_CHANNEL_ORDER_CUSTOM:
+         if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
++            int64_t mask;
+             int res = try_describe_ambisonic(bp, channel_layout);
+             if (res >= 0)
+                 return 0;
++            if (!has_channel_names(channel_layout) &&
++                (mask = masked_description(channel_layout, 0)) > 0) {
++                AVChannelLayout native = { .order       = AV_CHANNEL_ORDER_NATIVE,
++                                           .nb_channels = av_popcount64(mask),
++                                           .u.mask      = mask };
++                return av_channel_layout_describe_bprint(&native, bp);
++            }
+         }
+         if (channel_layout->nb_channels)
+             av_bprintf(bp, "%d channels (", channel_layout->nb_channels);
+         for (i = 0; i < channel_layout->nb_channels; i++) {
+             enum AVChannel ch = av_channel_layout_channel_from_index(channel_layout, i);
+ 
+             if (i)
+                 av_bprintf(bp, "+");
+@@ -1011,8 +868,102 @@ uint64_t av_channel_layout_subset(const 
+         for (i = 0; i < 64; i++)
+             if (mask & (1ULL << i) && av_channel_layout_index_from_channel(channel_layout, i) >= 0)
+                 ret |= (1ULL << i);
+         break;
+     }
+ 
+     return ret;
+ }
++
++int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags)
++{
++    int allow_lossy = !(flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS);
++    int lossy;
++
++    if (!av_channel_layout_check(channel_layout))
++        return AVERROR(EINVAL);
++
++    if (flags & AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL)
++        order = canonical_order(channel_layout);
++
++    if (channel_layout->order == order)
++        return 0;
++
++    switch (order) {
++    case AV_CHANNEL_ORDER_UNSPEC: {
++        int nb_channels = channel_layout->nb_channels;
++        if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
++            lossy = 0;
++            for (int i = 0; i < nb_channels; i++) {
++                if (channel_layout->u.map[i].id != AV_CHAN_UNKNOWN || channel_layout->u.map[i].name[0]) {
++                    lossy = 1;
++                    break;
++                }
++            }
++        } else {
++            lossy = 1;
++        }
++        if (!lossy || allow_lossy) {
++            void *opaque = channel_layout->opaque;
++            av_channel_layout_uninit(channel_layout);
++            channel_layout->order       = AV_CHANNEL_ORDER_UNSPEC;
++            channel_layout->nb_channels = nb_channels;
++            channel_layout->opaque      = opaque;
++            return lossy;
++        }
++        return AVERROR(ENOSYS);
++        }
++    case AV_CHANNEL_ORDER_NATIVE:
++        if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
++            int64_t mask = masked_description(channel_layout, 0);
++            if (mask < 0)
++                return AVERROR(ENOSYS);
++            lossy = has_channel_names(channel_layout);
++            if (!lossy || allow_lossy) {
++                void *opaque = channel_layout->opaque;
++                av_channel_layout_uninit(channel_layout);
++                av_channel_layout_from_mask(channel_layout, mask);
++                channel_layout->opaque = opaque;
++                return lossy;
++            }
++        }
++        return AVERROR(ENOSYS);
++    case AV_CHANNEL_ORDER_CUSTOM: {
++        AVChannelLayout custom = { 0 };
++        int ret = av_channel_layout_custom_init(&custom, channel_layout->nb_channels);
++        void *opaque = channel_layout->opaque;
++        if (ret < 0)
++            return ret;
++        if (channel_layout->order != AV_CHANNEL_ORDER_UNSPEC)
++            for (int i = 0; i < channel_layout->nb_channels; i++)
++                custom.u.map[i].id = av_channel_layout_channel_from_index(channel_layout, i);
++        av_channel_layout_uninit(channel_layout);
++        *channel_layout = custom;
++        channel_layout->opaque = opaque;
++        return 0;
++        }
++    case AV_CHANNEL_ORDER_AMBISONIC:
++        if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
++            int64_t mask;
++            int nb_channels = channel_layout->nb_channels;
++            int order = ambisonic_order(channel_layout);
++            if (order < 0)
++                return AVERROR(ENOSYS);
++            mask = masked_description(channel_layout, (order + 1) * (order + 1));
++            if (mask < 0)
++                return AVERROR(ENOSYS);
++            lossy = has_channel_names(channel_layout);
++            if (!lossy || allow_lossy) {
++                void *opaque = channel_layout->opaque;
++                av_channel_layout_uninit(channel_layout);
++                channel_layout->order       = AV_CHANNEL_ORDER_AMBISONIC;
++                channel_layout->nb_channels = nb_channels;
++                channel_layout->u.mask      = mask;
++                channel_layout->opaque      = opaque;
++                return lossy;
++            }
++        }
++        return AVERROR(ENOSYS);
++    default:
++        return AVERROR(EINVAL);
++    }
++}
+diff --git a/media/ffvpx/libavutil/channel_layout.h b/media/ffvpx/libavutil/channel_layout.h
+--- a/media/ffvpx/libavutil/channel_layout.h
++++ b/media/ffvpx/libavutil/channel_layout.h
+@@ -114,17 +114,17 @@ enum AVChannelOrder {
+      * The native channel order, i.e. the channels are in the same order in
+      * which they are defined in the AVChannel enum. This supports up to 63
+      * different channels.
+      */
+     AV_CHANNEL_ORDER_NATIVE,
+     /**
+      * The channel order does not correspond to any other predefined order and
+      * is stored as an explicit map. For example, this could be used to support
+-     * layouts with 64 or more channels, or with empty/skipped (AV_CHAN_SILENCE)
++     * layouts with 64 or more channels, or with empty/skipped (AV_CHAN_UNUSED)
+      * channels at arbitrary positions.
+      */
+     AV_CHANNEL_ORDER_CUSTOM,
+     /**
+      * The audio is represented as the decomposition of the sound field into
+      * spherical harmonics. Each channel corresponds to a single expansion
+      * component. Channels are ordered according to ACN (Ambisonic Channel
+      * Number).
+@@ -141,16 +141,20 @@ enum AVChannelOrder {
+      * @code{.unparsed}
+      *   n = l * (l + 1) + m.
+      * @endcode
+      *
+      * Normalization is assumed to be SN3D (Schmidt Semi-Normalization)
+      * as defined in AmbiX format $ 2.1.
+      */
+     AV_CHANNEL_ORDER_AMBISONIC,
++    /**
++     * Number of channel orders, not part of ABI/API
++     */
++    FF_CHANNEL_ORDER_NB
+ };
+ 
+ 
+ /**
+  * @defgroup channel_masks Audio channel masks
+  *
+  * A channel layout is a 64-bits integer with a bit set for every channel.
+  * The number of bits set must be equal to the number of channels.
+@@ -187,26 +191,16 @@ enum AVChannelOrder {
+ #define AV_CH_SURROUND_DIRECT_RIGHT  (1ULL << AV_CHAN_SURROUND_DIRECT_RIGHT)
+ #define AV_CH_LOW_FREQUENCY_2        (1ULL << AV_CHAN_LOW_FREQUENCY_2      )
+ #define AV_CH_TOP_SIDE_LEFT          (1ULL << AV_CHAN_TOP_SIDE_LEFT        )
+ #define AV_CH_TOP_SIDE_RIGHT         (1ULL << AV_CHAN_TOP_SIDE_RIGHT       )
+ #define AV_CH_BOTTOM_FRONT_CENTER    (1ULL << AV_CHAN_BOTTOM_FRONT_CENTER  )
+ #define AV_CH_BOTTOM_FRONT_LEFT      (1ULL << AV_CHAN_BOTTOM_FRONT_LEFT    )
+ #define AV_CH_BOTTOM_FRONT_RIGHT     (1ULL << AV_CHAN_BOTTOM_FRONT_RIGHT   )
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-/** Channel mask value used for AVCodecContext.request_channel_layout
+-    to indicate that the user requests the channel order of the decoder output
+-    to be the native codec channel order.
+-    @deprecated channel order is now indicated in a special field in
+-                AVChannelLayout
+-    */
+-#define AV_CH_LAYOUT_NATIVE          0x8000000000000000ULL
+-#endif
+-
+ /**
+  * @}
+  * @defgroup channel_mask_c Audio channel layouts
+  * @{
+  * */
+ #define AV_CH_LAYOUT_MONO              (AV_CH_FRONT_CENTER)
+ #define AV_CH_LAYOUT_STEREO            (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)
+ #define AV_CH_LAYOUT_2POINT1           (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY)
+@@ -425,156 +419,16 @@ typedef struct AVChannelLayout {
+     { /* .order */ AV_CHANNEL_ORDER_AMBISONIC, \
+       /* .nb_channels */ 4, \
+       /* .u.mask */ { 0 }, \
+       /* .opaque */ NULL }
+ /** @} */
+ 
+ struct AVBPrint;
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-/**
+- * @name Deprecated Functions
+- * @{
+- */
+-
+-/**
+- * Return a channel layout id that matches name, or 0 if no match is found.
+- *
+- * name can be one or several of the following notations,
+- * separated by '+' or '|':
+- * - the name of an usual channel layout (mono, stereo, 4.0, quad, 5.0,
+- *   5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix);
+- * - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC,
+- *   SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR);
+- * - a number of channels, in decimal, followed by 'c', yielding
+- *   the default channel layout for that number of channels (@see
+- *   av_get_default_channel_layout);
+- * - a channel layout mask, in hexadecimal starting with "0x" (see the
+- *   AV_CH_* macros).
+- *
+- * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7"
+- *
+- * @deprecated use av_channel_layout_from_string()
+- */
+-attribute_deprecated
+-uint64_t av_get_channel_layout(const char *name);
+-
+-/**
+- * Return a channel layout and the number of channels based on the specified name.
+- *
+- * This function is similar to (@see av_get_channel_layout), but can also parse
+- * unknown channel layout specifications.
+- *
+- * @param[in]  name             channel layout specification string
+- * @param[out] channel_layout   parsed channel layout (0 if unknown)
+- * @param[out] nb_channels      number of channels
+- *
+- * @return 0 on success, AVERROR(EINVAL) if the parsing fails.
+- * @deprecated use av_channel_layout_from_string()
+- */
+-attribute_deprecated
+-int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels);
+-
+-/**
+- * Return a description of a channel layout.
+- * If nb_channels is <= 0, it is guessed from the channel_layout.
+- *
+- * @param buf put here the string containing the channel layout
+- * @param buf_size size in bytes of the buffer
+- * @param nb_channels number of channels
+- * @param channel_layout channel layout bitset
+- * @deprecated use av_channel_layout_describe()
+- */
+-attribute_deprecated
+-void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout);
+-
+-/**
+- * Append a description of a channel layout to a bprint buffer.
+- * @deprecated use av_channel_layout_describe()
+- */
+-attribute_deprecated
+-void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout);
+-
+-/**
+- * Return the number of channels in the channel layout.
+- * @deprecated use AVChannelLayout.nb_channels
+- */
+-attribute_deprecated
+-int av_get_channel_layout_nb_channels(uint64_t channel_layout);
+-
+-/**
+- * Return default channel layout for a given number of channels.
+- *
+- * @deprecated use av_channel_layout_default()
+- */
+-attribute_deprecated
+-int64_t av_get_default_channel_layout(int nb_channels);
+-
+-/**
+- * Get the index of a channel in channel_layout.
+- *
+- * @param channel_layout channel layout bitset
+- * @param channel a channel layout describing exactly one channel which must be
+- *                present in channel_layout.
+- *
+- * @return index of channel in channel_layout on success, a negative AVERROR
+- *         on error.
+- *
+- * @deprecated use av_channel_layout_index_from_channel()
+- */
+-attribute_deprecated
+-int av_get_channel_layout_channel_index(uint64_t channel_layout,
+-                                        uint64_t channel);
+-
+-/**
+- * Get the channel with the given index in channel_layout.
+- * @deprecated use av_channel_layout_channel_from_index()
+- */
+-attribute_deprecated
+-uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index);
+-
+-/**
+- * Get the name of a given channel.
+- *
+- * @return channel name on success, NULL on error.
+- *
+- * @deprecated use av_channel_name()
+- */
+-attribute_deprecated
+-const char *av_get_channel_name(uint64_t channel);
+-
+-/**
+- * Get the description of a given channel.
+- *
+- * @param channel  a channel layout with a single channel
+- * @return  channel description on success, NULL on error
+- * @deprecated use av_channel_description()
+- */
+-attribute_deprecated
+-const char *av_get_channel_description(uint64_t channel);
+-
+-/**
+- * Get the value and name of a standard channel layout.
+- *
+- * @param[in]  index   index in an internal list, starting at 0
+- * @param[out] layout  channel layout mask
+- * @param[out] name    name of the layout
+- * @return  0  if the layout exists,
+- *          <0 if index is beyond the limits
+- * @deprecated use av_channel_layout_standard()
+- */
+-attribute_deprecated
+-int av_get_standard_channel_layout(unsigned index, uint64_t *layout,
+-                                   const char **name);
+-/**
+- * @}
+- */
+-#endif
+-
+ /**
+  * Get a human readable string in an abbreviated form describing a given channel.
+  * This is the inverse function of @ref av_channel_from_string().
+  *
+  * @param buf pre-allocated buffer where to put the generated string
+  * @param buf_size size in bytes of the buffer.
+  * @param channel the AVChannel whose name to get
+  * @return amount of bytes needed to hold the output string, or a negative AVERROR
+@@ -613,16 +467,33 @@ void av_channel_description_bprint(struc
+  * This is the inverse function of @ref av_channel_name().
+  *
+  * @return the channel with the given name
+  *         AV_CHAN_NONE when name does not identify a known channel
+  */
+ enum AVChannel av_channel_from_string(const char *name);
+ 
+ /**
++ * Initialize a custom channel layout with the specified number of channels.
++ * The channel map will be allocated and the designation of all channels will
++ * be set to AV_CHAN_UNKNOWN.
++ *
++ * This is only a convenience helper function, a custom channel layout can also
++ * be constructed without using this.
++ *
++ * @param channel_layout the layout structure to be initialized
++ * @param nb_channels the number of channels
++ *
++ * @return 0 on success
++ *         AVERROR(EINVAL) if the number of channels <= 0
++ *         AVERROR(ENOMEM) if the channel map could not be allocated
++ */
++int av_channel_layout_custom_init(AVChannelLayout *channel_layout, int nb_channels);
++
++/**
+  * Initialize a native channel layout from a bitmask indicating which channels
+  * are present.
+  *
+  * @param channel_layout the layout structure to be initialized
+  * @param mask bitmask describing the channel layout
+  *
+  * @return 0 on success
+  *         AVERROR(EINVAL) for invalid mask values
+@@ -636,20 +507,24 @@ int av_channel_layout_from_mask(AVChanne
+  *  - single or multiple channel names (returned by av_channel_name(), eg. "FL",
+  *    or concatenated with "+", each optionally containing a custom name after
+  *    a "@", eg. "FL@Left+FR@Right+LFE")
+  *  - a decimal or hexadecimal value of a native channel layout (eg. "4" or "0x4")
+  *  - the number of channels with default layout (eg. "4c")
+  *  - the number of unordered channels (eg. "4C" or "4 channels")
+  *  - the ambisonic order followed by optional non-diegetic channels (eg.
+  *    "ambisonic 2+stereo")
++ * On error, the channel layout will remain uninitialized, but not necessarily
++ * untouched.
+  *
+- * @param channel_layout input channel layout
++ * @param channel_layout uninitialized channel layout for the result
+  * @param str string describing the channel layout
+- * @return 0 channel layout was detected, AVERROR_INVALIDATATA otherwise
++ * @return 0 on success parsing the channel layout
++ *         AVERROR(EINVAL) if an invalid channel layout string was provided
++ *         AVERROR(ENOMEM) if there was not enough memory
+  */
+ int av_channel_layout_from_string(AVChannelLayout *channel_layout,
+                                   const char *str);
+ 
+ /**
+  * Get the default channel layout for a given number of channels.
+  *
+  * @param ch_layout the layout structure to be initialized
+@@ -800,12 +675,59 @@ int av_channel_layout_check(const AVChan
+  * @param chl input channel layout
+  * @param chl1 input channel layout
+  * @return 0 if chl and chl1 are equal, 1 if they are not equal. A negative
+  *         AVERROR code if one or both are invalid.
+  */
+ int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1);
+ 
+ /**
++ * The conversion must be lossless.
++ */
++#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS (1 << 0)
++
++/**
++ * The specified retype target order is ignored and the simplest possible
++ * (canonical) order is used for which the input layout can be losslessy
++ * represented.
++ */
++#define AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL (1 << 1)
++
++/**
++ * Change the AVChannelOrder of a channel layout.
++ *
++ * Change of AVChannelOrder can be either lossless or lossy. In case of a
++ * lossless conversion all the channel designations and the associated channel
++ * names (if any) are kept. On a lossy conversion the channel names and channel
++ * designations might be lost depending on the capabilities of the desired
++ * AVChannelOrder. Note that some conversions are simply not possible in which
++ * case this function returns AVERROR(ENOSYS).
++ *
++ * The following conversions are supported:
++ *
++ * Any       -> Custom     : Always possible, always lossless.
++ * Any       -> Unspecified: Always possible, lossless if channel designations
++ *   are all unknown and channel names are not used, lossy otherwise.
++ * Custom    -> Ambisonic  : Possible if it contains ambisonic channels with
++ *   optional non-diegetic channels in the end. Lossy if the channels have
++ *   custom names, lossless otherwise.
++ * Custom    -> Native     : Possible if it contains native channels in native
++ *     order. Lossy if the channels have custom names, lossless otherwise.
++ *
++ * On error this function keeps the original channel layout untouched.
++ *
++ * @param channel_layout channel layout which will be changed
++ * @param order the desired channel layout order
++ * @param flags a combination of AV_CHANNEL_LAYOUT_RETYPE_FLAG_* constants
++ * @return 0 if the conversion was successful and lossless or if the channel
++ *           layout was already in the desired order
++ *         >0 if the conversion was successful but lossy
++ *         AVERROR(ENOSYS) if the conversion was not possible (or would be
++ *           lossy and AV_CHANNEL_LAYOUT_RETYPE_FLAG_LOSSLESS was specified)
++ *         AVERROR(EINVAL), AVERROR(ENOMEM) on error
++ */
++int av_channel_layout_retype(AVChannelLayout *channel_layout, enum AVChannelOrder order, int flags);
++
++/**
+  * @}
+  */
+ 
+ #endif /* AVUTIL_CHANNEL_LAYOUT_H */
+diff --git a/media/ffvpx/libavutil/color_utils.c b/media/ffvpx/libavutil/color_utils.c
+deleted file mode 100644
+--- a/media/ffvpx/libavutil/color_utils.c
++++ /dev/null
+@@ -1,234 +0,0 @@
+-/*
+- * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
+- *
+- * 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
+- */
+-
+-#include <stddef.h>
+-#include <math.h>
+-
+-#include "libavutil/color_utils.h"
+-#include "libavutil/pixfmt.h"
+-
+-double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
+-{
+-    double gamma;
+-    switch (trc) {
+-        case AVCOL_TRC_BT709:
+-        case AVCOL_TRC_SMPTE170M:
+-        case AVCOL_TRC_SMPTE240M:
+-        case AVCOL_TRC_BT1361_ECG:
+-        case AVCOL_TRC_BT2020_10:
+-        case AVCOL_TRC_BT2020_12:
+-            /* these share a segmented TRC, but gamma 1.961 is a close
+-              approximation, and also more correct for decoding content */
+-            gamma = 1.961;
+-            break;
+-        case AVCOL_TRC_GAMMA22:
+-        case AVCOL_TRC_IEC61966_2_1:
+-            gamma = 2.2;
+-            break;
+-        case AVCOL_TRC_GAMMA28:
+-            gamma = 2.8;
+-            break;
+-        case AVCOL_TRC_LINEAR:
+-            gamma = 1.0;
+-            break;
+-        default:
+-            gamma = 0.0; // Unknown value representation
+-    }
+-    return gamma;
+-}
+-
+-#define BT709_alpha 1.099296826809442
+-#define BT709_beta 0.018053968510807
+-
+-static double avpriv_trc_bt709(double Lc)
+-{
+-    const double a = BT709_alpha;
+-    const double b = BT709_beta;
+-
+-    return (0.0 > Lc) ? 0.0
+-         : (  b > Lc) ? 4.500 * Lc
+-         :              a * pow(Lc, 0.45) - (a - 1.0);
+-}
+-
+-static double avpriv_trc_gamma22(double Lc)
+-{
+-    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.2);
+-}
+-
+-static double avpriv_trc_gamma28(double Lc)
+-{
+-    return (0.0 > Lc) ? 0.0 : pow(Lc, 1.0/ 2.8);
+-}
+-
+-static double avpriv_trc_smpte240M(double Lc)
+-{
+-    const double a = 1.1115;
+-    const double b = 0.0228;
+-
+-    return (0.0 > Lc) ? 0.0
+-         : (  b > Lc) ? 4.000 * Lc
+-         :              a * pow(Lc, 0.45) - (a - 1.0);
+-}
+-
+-static double avpriv_trc_linear(double Lc)
+-{
+-    return Lc;
+-}
+-
+-static double avpriv_trc_log(double Lc)
+-{
+-    return (0.01 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.0;
+-}
+-
+-static double avpriv_trc_log_sqrt(double Lc)
+-{
+-    // sqrt(10) / 1000
+-    return (0.00316227766 > Lc) ? 0.0 : 1.0 + log10(Lc) / 2.5;
+-}
+-
+-static double avpriv_trc_iec61966_2_4(double Lc)
+-{
+-    const double a = BT709_alpha;
+-    const double b = BT709_beta;
+-
+-    return (-b >= Lc) ? -a * pow(-Lc, 0.45) + (a - 1.0)
+-         : ( b >  Lc) ? 4.500 * Lc
+-         :               a * pow( Lc, 0.45) - (a - 1.0);
+-}
+-
+-static double avpriv_trc_bt1361(double Lc)
+-{
+-    const double a = BT709_alpha;
+-    const double b = BT709_beta;
+-
+-    return (-0.0045 >= Lc) ? -(a * pow(-4.0 * Lc, 0.45) + (a - 1.0)) / 4.0
+-         : ( b >  Lc) ? 4.500 * Lc
+-         :               a * pow( Lc, 0.45) - (a - 1.0);
+-}
+-
+-static double avpriv_trc_iec61966_2_1(double Lc)
+-{
+-    const double a = 1.055;
+-    const double b = 0.0031308;
+-
+-    return (0.0 > Lc) ? 0.0
+-         : (  b > Lc) ? 12.92 * Lc
+-         :              a * pow(Lc, 1.0  / 2.4) - (a - 1.0);
+-}
+-
+-static double avpriv_trc_smpte_st2084(double Lc)
+-{
+-    const double c1 =         3424.0 / 4096.0; // c3-c2 + 1
+-    const double c2 =  32.0 * 2413.0 / 4096.0;
+-    const double c3 =  32.0 * 2392.0 / 4096.0;
+-    const double m  = 128.0 * 2523.0 / 4096.0;
+-    const double n  =  0.25 * 2610.0 / 4096.0;
+-    const double L  = Lc / 10000.0;
+-    const double Ln = pow(L, n);
+-
+-    return (0.0 > Lc) ? 0.0
+-         :              pow((c1 + c2 * Ln) / (1.0 + c3 * Ln), m);
+-
+-}
+-
+-static double avpriv_trc_smpte_st428_1(double Lc)
+-{
+-    return (0.0 > Lc) ? 0.0
+-         :              pow(48.0 * Lc / 52.37, 1.0 / 2.6);
+-}
+-
+-
+-static double avpriv_trc_arib_std_b67(double Lc) {
+-    // The function uses the definition from HEVC, which assumes that the peak
+-    // white is input level = 1. (this is equivalent to scaling E = Lc * 12 and
+-    // using the definition from the ARIB STD-B67 spec)
+-    const double a = 0.17883277;
+-    const double b = 0.28466892;
+-    const double c = 0.55991073;
+-    return (0.0 > Lc) ? 0.0 :
+-        (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
+-}
+-
+-avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc)
+-{
+-    avpriv_trc_function func = NULL;
+-    switch (trc) {
+-        case AVCOL_TRC_BT709:
+-        case AVCOL_TRC_SMPTE170M:
+-        case AVCOL_TRC_BT2020_10:
+-        case AVCOL_TRC_BT2020_12:
+-            func = avpriv_trc_bt709;
+-            break;
+-
+-        case AVCOL_TRC_GAMMA22:
+-            func = avpriv_trc_gamma22;
+-            break;
+-        case AVCOL_TRC_GAMMA28:
+-            func = avpriv_trc_gamma28;
+-            break;
+-
+-        case AVCOL_TRC_SMPTE240M:
+-            func = avpriv_trc_smpte240M;
+-            break;
+-
+-        case AVCOL_TRC_LINEAR:
+-            func = avpriv_trc_linear;
+-            break;
+-
+-        case AVCOL_TRC_LOG:
+-            func = avpriv_trc_log;
+-            break;
+-
+-        case AVCOL_TRC_LOG_SQRT:
+-            func = avpriv_trc_log_sqrt;
+-            break;
+-
+-        case AVCOL_TRC_IEC61966_2_4:
+-            func = avpriv_trc_iec61966_2_4;
+-            break;
+-
+-        case AVCOL_TRC_BT1361_ECG:
+-            func = avpriv_trc_bt1361;
+-            break;
+-
+-        case AVCOL_TRC_IEC61966_2_1:
+-            func = avpriv_trc_iec61966_2_1;
+-            break;
+-
+-        case AVCOL_TRC_SMPTEST2084:
+-            func = avpriv_trc_smpte_st2084;
+-            break;
+-
+-        case AVCOL_TRC_SMPTEST428_1:
+-            func = avpriv_trc_smpte_st428_1;
+-            break;
+-
+-        case AVCOL_TRC_ARIB_STD_B67:
+-            func = avpriv_trc_arib_std_b67;
+-            break;
+-
+-        case AVCOL_TRC_RESERVED0:
+-        case AVCOL_TRC_UNSPECIFIED:
+-        case AVCOL_TRC_RESERVED:
+-        default:
+-            break;
+-    }
+-    return func;
+-}
+diff --git a/media/ffvpx/libavutil/color_utils.h b/media/ffvpx/libavutil/color_utils.h
+deleted file mode 100644
+--- a/media/ffvpx/libavutil/color_utils.h
++++ /dev/null
+@@ -1,56 +0,0 @@
+-/*
+- * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
+- *
+- * 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
+- */
+-
+-#ifndef AVUTIL_COLOR_UTILS_H
+-#define AVUTIL_COLOR_UTILS_H
+-
+-
+-#include "libavutil/pixfmt.h"
+-
+-/**
+- * Determine a suitable 'gamma' value to match the supplied
+- * AVColorTransferCharacteristic.
+- *
+- * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
+- *
+- * @return Will return an approximation to the simple gamma function matching
+- *         the supplied Transfer Characteristic, Will return 0.0 for any
+- *         we cannot reasonably match against.
+- */
+-double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc);
+-
+-
+-typedef double (*avpriv_trc_function)(double);
+-
+-/**
+- * Determine the function needed to apply the given
+- * AVColorTransferCharacteristic to linear input.
+- *
+- * The function returned should expect a nominal domain and range of [0.0-1.0]
+- * values outside of this range maybe valid depending on the chosen
+- * characteristic function.
+- *
+- * @return Will return pointer to the function matching the
+- *         supplied Transfer Characteristic. If unspecified will
+- *         return NULL:
+- */
+-avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc);
+-
+-#endif
+diff --git a/media/ffvpx/libavutil/common.h b/media/ffvpx/libavutil/common.h
+--- a/media/ffvpx/libavutil/common.h
++++ b/media/ffvpx/libavutil/common.h
+@@ -38,16 +38,24 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ #include "attributes.h"
+ #include "error.h"
+ #include "macros.h"
+ 
++#ifdef HAVE_AV_CONFIG_H
++#   include "config.h"
++#   include "intmath.h"
++#   include "internal.h"
++#else
++#   include "mem.h"
++#endif /* HAVE_AV_CONFIG_H */
++
+ //rounded division & shift
+ #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
+ /* assume b>0 */
+ #define ROUNDED_DIV(a,b) (((a)>=0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
+ /* Fast a/(1<<b) rounded toward +inf. Assume a>=0 and b>=0 */
+ #define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \
+                                                        : ((a) + (1<<(b)) - 1) >> (b))
+ /* Backwards compat. */
+@@ -79,21 +87,16 @@
+  * This also works with INT_MIN which would otherwise not be representable
+  * As with many macros, this evaluates its argument twice.
+  */
+ #define FFABSU(a) ((a) <= 0 ? -(unsigned)(a) : (unsigned)(a))
+ #define FFABS64U(a) ((a) <= 0 ? -(uint64_t)(a) : (uint64_t)(a))
+ 
+ /* misc math functions */
+ 
+-#ifdef HAVE_AV_CONFIG_H
+-#   include "config.h"
+-#   include "intmath.h"
+-#endif
+-
+ #ifndef av_ceil_log2
+ #   define av_ceil_log2     av_ceil_log2_c
+ #endif
+ #ifndef av_clip
+ #   define av_clip          av_clip_c
+ #endif
+ #ifndef av_clip64
+ #   define av_clip64        av_clip64_c
+@@ -563,17 +566,9 @@ static av_always_inline av_const int av_
+         } else {\
+             tmp = 0xD800 | ((in - 0x10000) >> 10);\
+             PUT_16BIT\
+             tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\
+             PUT_16BIT\
+         }\
+     }\
+ 
+-
+-
+-#include "mem.h"
+-
+-#ifdef HAVE_AV_CONFIG_H
+-#    include "internal.h"
+-#endif /* HAVE_AV_CONFIG_H */
+-
+ #endif /* AVUTIL_COMMON_H */
+diff --git a/media/ffvpx/libavutil/cpu.c b/media/ffvpx/libavutil/cpu.c
+--- a/media/ffvpx/libavutil/cpu.c
++++ b/media/ffvpx/libavutil/cpu.c
+@@ -44,18 +44,18 @@
+ #endif
+ #include <sys/types.h>
+ #include <sys/sysctl.h>
+ #endif
+ #if HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ 
+-static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1);
+-static atomic_int cpu_count = ATOMIC_VAR_INIT(-1);
++static atomic_int cpu_flags = -1;
++static atomic_int cpu_count = -1;
+ 
+ static int get_cpu_flags(void)
+ {
+ #if ARCH_MIPS
+     return ff_get_cpu_flags_mips();
+ #elif ARCH_AARCH64
+     return ff_get_cpu_flags_aarch64();
+ #elif ARCH_ARM
+@@ -203,17 +203,17 @@ int av_parse_cpu_caps(unsigned *flags, c
+     };
+     const AVClass *pclass = &class;
+ 
+     return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, flags);
+ }
+ 
+ int av_cpu_count(void)
+ {
+-    static atomic_int printed = ATOMIC_VAR_INIT(0);
++    static atomic_int printed = 0;
+ 
+     int nb_cpus = 1;
+     int count   = 0;
+ #if HAVE_WINRT
+     SYSTEM_INFO sysinfo;
+ #endif
+ #if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
+     cpu_set_t cpuset;
+diff --git a/media/ffvpx/libavutil/csp.h b/media/ffvpx/libavutil/csp.h
+new file mode 100644
+--- /dev/null
++++ b/media/ffvpx/libavutil/csp.h
+@@ -0,0 +1,150 @@
++/*
++ * Copyright (c) 2015 Kevin Wheatley <kevin.j.wheatley@gmail.com>
++ * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.com>
++ * Copyright (c) 2023 Leo Izen <leo.izen@gmail.com>
++ *
++ * 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
++ */
++
++#ifndef AVUTIL_CSP_H
++#define AVUTIL_CSP_H
++
++#include "pixfmt.h"
++#include "rational.h"
++
++/**
++ * @file
++ * Colorspace value utility functions for libavutil.
++ * @ingroup lavu_math_csp
++ * @author Ronald S. Bultje <rsbultje@gmail.com>
++ * @author Leo Izen <leo.izen@gmail.com>
++ * @author Kevin Wheatley <kevin.j.wheatley@gmail.com>
++ */
++
++/**
++ * @defgroup lavu_math_csp Colorspace Utility
++ * @ingroup lavu_math
++ * @{
++ */
++
++/**
++ * Struct containing luma coefficients to be used for RGB to YUV/YCoCg, or similar
++ * calculations.
++ */
++typedef struct AVLumaCoefficients {
++    AVRational cr, cg, cb;
++} AVLumaCoefficients;
++
++/**
++ * Struct containing chromaticity x and y values for the standard CIE 1931
++ * chromaticity definition.
++ */
++typedef struct AVCIExy {
++    AVRational x, y;
++} AVCIExy;
++
++/**
++ * Struct defining the red, green, and blue primary locations in terms of CIE
++ * 1931 chromaticity x and y.
++ */
++typedef struct AVPrimaryCoefficients {
++    AVCIExy r, g, b;
++} AVPrimaryCoefficients;
++
++/**
++ * Struct defining white point location in terms of CIE 1931 chromaticity x
++ * and y.
++ */
++typedef AVCIExy AVWhitepointCoefficients;
++
++/**
++ * Struct that contains both white point location and primaries location, providing
++ * the complete description of a color gamut.
++ */
++typedef struct AVColorPrimariesDesc {
++    AVWhitepointCoefficients wp;
++    AVPrimaryCoefficients prim;
++} AVColorPrimariesDesc;
++
++/**
++ * Function pointer representing a double -> double transfer function that performs
++ * an EOTF transfer inversion. This function outputs linear light.
++ */
++typedef double (*av_csp_trc_function)(double);
++
++/**
++ * Retrieves the Luma coefficients necessary to construct a conversion matrix
++ * from an enum constant describing the colorspace.
++ * @param csp An enum constant indicating YUV or similar colorspace.
++ * @return The Luma coefficients associated with that colorspace, or NULL
++ *     if the constant is unknown to libavutil.
++ */
++const AVLumaCoefficients *av_csp_luma_coeffs_from_avcsp(enum AVColorSpace csp);
++
++/**
++ * Retrieves a complete gamut description from an enum constant describing the
++ * color primaries.
++ * @param prm An enum constant indicating primaries
++ * @return A description of the colorspace gamut associated with that enum
++ *     constant, or NULL if the constant is unknown to libavutil.
++ */
++const AVColorPrimariesDesc *av_csp_primaries_desc_from_id(enum AVColorPrimaries prm);
++
++/**
++ * Detects which enum AVColorPrimaries constant corresponds to the given complete
++ * gamut description.
++ * @see enum AVColorPrimaries
++ * @param prm A description of the colorspace gamut
++ * @return The enum constant associated with this gamut, or
++ *     AVCOL_PRI_UNSPECIFIED if no clear match can be idenitified.
++ */
++enum AVColorPrimaries av_csp_primaries_id_from_desc(const AVColorPrimariesDesc *prm);
++
++/**
++ * Determine a suitable 'gamma' value to match the supplied
++ * AVColorTransferCharacteristic.
++ *
++ * See Apple Technical Note TN2257 (https://developer.apple.com/library/mac/technotes/tn2257/_index.html)
++ *
++ * This function returns the gamma exponent for the OETF. For example, sRGB is approximated
++ * by gamma 2.2, not by gamma 0.45455.
++ *
++ * @return Will return an approximation to the simple gamma function matching
++ *         the supplied Transfer Characteristic, Will return 0.0 for any
++ *         we cannot reasonably match against.
++ */
++double av_csp_approximate_trc_gamma(enum AVColorTransferCharacteristic trc);
++
++/**
++ * Determine the function needed to apply the given
++ * AVColorTransferCharacteristic to linear input.
++ *
++ * The function returned should expect a nominal domain and range of [0.0-1.0]
++ * values outside of this range maybe valid depending on the chosen
++ * characteristic function.
++ *
++ * @return Will return pointer to the function matching the
++ *         supplied Transfer Characteristic. If unspecified will
++ *         return NULL:
++ */
++av_csp_trc_function av_csp_trc_func_from_id(enum AVColorTransferCharacteristic trc);
++
++/**
++ * @}
++ */
++
++#endif /* AVUTIL_CSP_H */
+diff --git a/media/ffvpx/libavutil/dict.c b/media/ffvpx/libavutil/dict.c
+--- a/media/ffvpx/libavutil/dict.c
++++ b/media/ffvpx/libavutil/dict.c
+@@ -140,34 +140,32 @@ int av_dict_set(AVDictionary **pm, const
+             goto enomem;
+         m->elems = tmp;
+     }
+     if (copy_value) {
+         m->elems[m->count].key = copy_key;
+         m->elems[m->count].value = copy_value;
+         m->count++;
+     } else {
+-        if (!m->count) {
+-            av_freep(&m->elems);
+-            av_freep(pm);
+-        }
+-        av_freep(&copy_key);
++        err = 0;
++        goto end;
+     }
+ 
+     return 0;
+ 
+ enomem:
+     err = AVERROR(ENOMEM);
+ err_out:
++    av_free(copy_value);
++end:
+     if (m && !m->count) {
+         av_freep(&m->elems);
+         av_freep(pm);
+     }
+     av_free(copy_key);
+-    av_free(copy_value);
+     return err;
+ }
+ 
+ int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value,
+                 int flags)
+ {
+     char valuestr[22];
+     snprintf(valuestr, sizeof(valuestr), "%"PRId64, value);
+diff --git a/media/ffvpx/libavutil/eval.c b/media/ffvpx/libavutil/eval.c
+--- a/media/ffvpx/libavutil/eval.c
++++ b/media/ffvpx/libavutil/eval.c
+@@ -27,23 +27,22 @@
+  */
+ 
+ #include <float.h>
+ #include "attributes.h"
+ #include "avutil.h"
+ #include "common.h"
+ #include "eval.h"
+ #include "ffmath.h"
+-#include "internal.h"
+ #include "log.h"
+ #include "mathematics.h"
++#include "mem.h"
+ #include "sfc64.h"
+ #include "fftime.h"
+ #include "avstring.h"
+-#include "timer.h"
+ #include "reverse.h"
+ 
+ typedef struct Parser {
+     const AVClass *class;
+     int stack_index;
+     char *s;
+     const double *const_values;
+     const char * const *const_names;          // NULL terminated
+diff --git a/media/ffvpx/libavutil/fftime.h b/media/ffvpx/libavutil/fftime.h
+--- a/media/ffvpx/libavutil/fftime.h
++++ b/media/ffvpx/libavutil/fftime.h
+@@ -17,17 +17,16 @@
+  * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #ifndef AVUTIL_TIME_H
+ #define AVUTIL_TIME_H
+ 
+ #include <stdint.h>
+-#include <time.h>
+ 
+ /**
+  * Get the current time in microseconds.
+  */
+ int64_t av_gettime(void);
+ 
+ /**
+  * Get the current time in microseconds since some unspecified starting point.
+diff --git a/media/ffvpx/libavutil/ffversion.h b/media/ffvpx/libavutil/ffversion.h
+--- a/media/ffvpx/libavutil/ffversion.h
++++ b/media/ffvpx/libavutil/ffversion.h
+@@ -1,5 +1,5 @@
+ /* Automatically generated by version.sh, do not manually edit! */
+ #ifndef AVUTIL_FFVERSION_H
+ #define AVUTIL_FFVERSION_H
+-#define FFMPEG_VERSION "N-111736-gd9d5695390"
++#define FFMPEG_VERSION "N-114439-gf0ee4bbc6b"
+ #endif /* AVUTIL_FFVERSION_H */
+diff --git a/media/ffvpx/libavutil/fifo.c b/media/ffvpx/libavutil/fifo.c
+--- a/media/ffvpx/libavutil/fifo.c
++++ b/media/ffvpx/libavutil/fifo.c
+@@ -285,227 +285,8 @@ void av_fifo_reset2(AVFifo *f)
+ 
+ void av_fifo_freep2(AVFifo **f)
+ {
+     if (*f) {
+         av_freep(&(*f)->buffer);
+         av_freep(f);
+     }
+ }
+-
+-
+-#if FF_API_FIFO_OLD_API
+-#include "internal.h"
+-FF_DISABLE_DEPRECATION_WARNINGS
+-#define OLD_FIFO_SIZE_MAX (size_t)FFMIN3(INT_MAX, UINT32_MAX, SIZE_MAX)
+-
+-AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size)
+-{
+-    AVFifoBuffer *f;
+-    void *buffer;
+-
+-    if (nmemb > OLD_FIFO_SIZE_MAX / size)
+-        return NULL;
+-
+-    buffer = av_realloc_array(NULL, nmemb, size);
+-    if (!buffer)
+-        return NULL;
+-    f = av_mallocz(sizeof(AVFifoBuffer));
+-    if (!f) {
+-        av_free(buffer);
+-        return NULL;
+-    }
+-    f->buffer = buffer;
+-    f->end    = f->buffer + nmemb * size;
+-    av_fifo_reset(f);
+-    return f;
+-}
+-
+-AVFifoBuffer *av_fifo_alloc(unsigned int size)
+-{
+-    return av_fifo_alloc_array(size, 1);
+-}
+-
+-void av_fifo_free(AVFifoBuffer *f)
+-{
+-    if (f) {
+-        av_freep(&f->buffer);
+-        av_free(f);
+-    }
+-}
+-
+-void av_fifo_freep(AVFifoBuffer **f)
+-{
+-    if (f) {
+-        av_fifo_free(*f);
+-        *f = NULL;
+-    }
+-}
+-
+-void av_fifo_reset(AVFifoBuffer *f)
+-{
+-    f->wptr = f->rptr = f->buffer;
+-    f->wndx = f->rndx = 0;
+-}
+-
+-int av_fifo_size(const AVFifoBuffer *f)
+-{
+-    return (uint32_t)(f->wndx - f->rndx);
+-}
+-
+-int av_fifo_space(const AVFifoBuffer *f)
+-{
+-    return f->end - f->buffer - av_fifo_size(f);
+-}
+-
+-int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
+-{
+-    unsigned int old_size = f->end - f->buffer;
+-
+-    if (new_size > OLD_FIFO_SIZE_MAX)
+-        return AVERROR(EINVAL);
+-
+-    if (old_size < new_size) {
+-        size_t offset_r = f->rptr - f->buffer;
+-        size_t offset_w = f->wptr - f->buffer;
+-        uint8_t *tmp;
+-
+-        tmp = av_realloc(f->buffer, new_size);
+-        if (!tmp)
+-            return AVERROR(ENOMEM);
+-
+-        // move the data from the beginning of the ring buffer
+-        // to the newly allocated space
+-        // the second condition distinguishes full vs empty fifo
+-        if (offset_w <= offset_r && av_fifo_size(f)) {
+-            const size_t copy = FFMIN(new_size - old_size, offset_w);
+-            memcpy(tmp + old_size, tmp, copy);
+-            if (copy < offset_w) {
+-                memmove(tmp, tmp + copy , offset_w - copy);
+-                offset_w -= copy;
+-            } else
+-                offset_w = old_size + copy;
+-        }
+-
+-        f->buffer = tmp;
+-        f->end    = f->buffer + new_size;
+-        f->rptr   = f->buffer + offset_r;
+-        f->wptr   = f->buffer + offset_w;
+-    }
+-    return 0;
+-}
+-
+-int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
+-{
+-    unsigned int old_size = f->end - f->buffer;
+-    if(size + (unsigned)av_fifo_size(f) < size)
+-        return AVERROR(EINVAL);
+-
+-    size += av_fifo_size(f);
+-
+-    if (old_size < size)
+-        return av_fifo_realloc2(f, FFMAX(size, 2*old_size));
+-    return 0;
+-}
+-
+-/* src must NOT be const as it can be a context for func that may need
+- * updating (like a pointer or byte counter) */
+-int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size,
+-                          int (*func)(void *, void *, int))
+-{
+-    int total = size;
+-    uint32_t wndx= f->wndx;
+-    uint8_t *wptr= f->wptr;
+-
+-    if (size > av_fifo_space(f))
+-        return AVERROR(ENOSPC);
+-
+-    do {
+-        int len = FFMIN(f->end - wptr, size);
+-        if (func) {
+-            len = func(src, wptr, len);
+-            if (len <= 0)
+-                break;
+-        } else {
+-            memcpy(wptr, src, len);
+-            src = (uint8_t *)src + len;
+-        }
+-        wptr += len;
+-        if (wptr >= f->end)
+-            wptr = f->buffer;
+-        wndx    += len;
+-        size    -= len;
+-    } while (size > 0);
+-    f->wndx= wndx;
+-    f->wptr= wptr;
+-    return total - size;
+-}
+-
+-int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int))
+-{
+-    uint8_t *rptr = f->rptr;
+-
+-    if (offset < 0 || buf_size > av_fifo_size(f) - offset)
+-        return AVERROR(EINVAL);
+-
+-    if (offset >= f->end - rptr)
+-        rptr += offset - (f->end - f->buffer);
+-    else
+-        rptr += offset;
+-
+-    while (buf_size > 0) {
+-        int len;
+-
+-        if (rptr >= f->end)
+-            rptr -= f->end - f->buffer;
+-
+-        len = FFMIN(f->end - rptr, buf_size);
+-        if (func)
+-            func(dest, rptr, len);
+-        else {
+-            memcpy(dest, rptr, len);
+-            dest = (uint8_t *)dest + len;
+-        }
+-
+-        buf_size -= len;
+-        rptr     += len;
+-    }
+-
+-    return 0;
+-}
+-
+-int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size,
+-                         void (*func)(void *, void *, int))
+-{
+-    return av_fifo_generic_peek_at(f, dest, 0, buf_size, func);
+-}
+-
+-int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size,
+-                         void (*func)(void *, void *, int))
+-{
+-    if (buf_size > av_fifo_size(f))
+-        return AVERROR(EINVAL);
+-
+-    do {
+-        int len = FFMIN(f->end - f->rptr, buf_size);
+-        if (func)
+-            func(dest, f->rptr, len);
+-        else {
+-            memcpy(dest, f->rptr, len);
+-            dest = (uint8_t *)dest + len;
+-        }
+-        av_fifo_drain(f, len);
+-        buf_size -= len;
+-    } while (buf_size > 0);
+-    return 0;
+-}
+-
+-/** Discard data from the FIFO. */
+-void av_fifo_drain(AVFifoBuffer *f, int size)
+-{
+-    av_assert2(av_fifo_size(f) >= size);
+-    f->rptr += size;
+-    if (f->rptr >= f->end)
+-        f->rptr -= f->end - f->buffer;
+-    f->rndx += size;
+-}
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+diff --git a/media/ffvpx/libavutil/fifo.h b/media/ffvpx/libavutil/fifo.h
+--- a/media/ffvpx/libavutil/fifo.h
++++ b/media/ffvpx/libavutil/fifo.h
+@@ -21,20 +21,16 @@
+  * @ingroup lavu_fifo
+  * A generic FIFO API
+  */
+ 
+ #ifndef AVUTIL_FIFO_H
+ #define AVUTIL_FIFO_H
+ 
+ #include <stddef.h>
+-#include <stdint.h>
+-
+-#include "attributes.h"
+-#include "version.h"
+ 
+ /**
+  * @defgroup lavu_fifo AVFifo
+  * @ingroup lavu_data
+  *
+  * @{
+  * A generic FIFO API
+  */
+@@ -234,215 +230,13 @@ void av_fifo_drain2(AVFifo *f, size_t si
+ void av_fifo_reset2(AVFifo *f);
+ 
+ /**
+  * Free an AVFifo and reset pointer to NULL.
+  * @param f Pointer to an AVFifo to free. *f == NULL is allowed.
+  */
+ void av_fifo_freep2(AVFifo **f);
+ 
+-
+-#if FF_API_FIFO_OLD_API
+-typedef struct AVFifoBuffer {
+-    uint8_t *buffer;
+-    uint8_t *rptr, *wptr, *end;
+-    uint32_t rndx, wndx;
+-} AVFifoBuffer;
+-
+-/**
+- * Initialize an AVFifoBuffer.
+- * @param size of FIFO
+- * @return AVFifoBuffer or NULL in case of memory allocation failure
+- * @deprecated use av_fifo_alloc2()
+- */
+-attribute_deprecated
+-AVFifoBuffer *av_fifo_alloc(unsigned int size);
+-
+-/**
+- * Initialize an AVFifoBuffer.
+- * @param nmemb number of elements
+- * @param size  size of the single element
+- * @return AVFifoBuffer or NULL in case of memory allocation failure
+- * @deprecated use av_fifo_alloc2()
+- */
+-attribute_deprecated
+-AVFifoBuffer *av_fifo_alloc_array(size_t nmemb, size_t size);
+-
+-/**
+- * Free an AVFifoBuffer.
+- * @param f AVFifoBuffer to free
+- * @deprecated use the AVFifo API with av_fifo_freep2()
+- */
+-attribute_deprecated
+-void av_fifo_free(AVFifoBuffer *f);
+-
+-/**
+- * Free an AVFifoBuffer and reset pointer to NULL.
+- * @param f AVFifoBuffer to free
+- * @deprecated use the AVFifo API with av_fifo_freep2()
+- */
+-attribute_deprecated
+-void av_fifo_freep(AVFifoBuffer **f);
+-
+-/**
+- * Reset the AVFifoBuffer to the state right after av_fifo_alloc, in particular it is emptied.
+- * @param f AVFifoBuffer to reset
+- * @deprecated use av_fifo_reset2() with the new AVFifo-API
+- */
+-attribute_deprecated
+-void av_fifo_reset(AVFifoBuffer *f);
+-
+-/**
+- * Return the amount of data in bytes in the AVFifoBuffer, that is the
+- * amount of data you can read from it.
+- * @param f AVFifoBuffer to read from
+- * @return size
+- * @deprecated use av_fifo_can_read() with the new AVFifo-API
+- */
+-attribute_deprecated
+-int av_fifo_size(const AVFifoBuffer *f);
+-
+-/**
+- * Return the amount of space in bytes in the AVFifoBuffer, that is the
+- * amount of data you can write into it.
+- * @param f AVFifoBuffer to write into
+- * @return size
+- * @deprecated use av_fifo_can_write() with the new AVFifo-API
+- */
+-attribute_deprecated
+-int av_fifo_space(const AVFifoBuffer *f);
+-
+-/**
+- * Feed data at specific position from an AVFifoBuffer to a user-supplied callback.
+- * Similar as av_fifo_gereric_read but without discarding data.
+- * @param f AVFifoBuffer to read from
+- * @param offset offset from current read position
+- * @param buf_size number of bytes to read
+- * @param func generic read function
+- * @param dest data destination
+- *
+- * @return a non-negative number on success, a negative error code on failure
+- *
+- * @deprecated use the new AVFifo-API with av_fifo_peek() when func == NULL,
+- *             av_fifo_peek_to_cb() otherwise
+- */
+-attribute_deprecated
+-int av_fifo_generic_peek_at(AVFifoBuffer *f, void *dest, int offset, int buf_size, void (*func)(void*, void*, int));
+-
+-/**
+- * Feed data from an AVFifoBuffer to a user-supplied callback.
+- * Similar as av_fifo_gereric_read but without discarding data.
+- * @param f AVFifoBuffer to read from
+- * @param buf_size number of bytes to read
+- * @param func generic read function
+- * @param dest data destination
+- *
+- * @return a non-negative number on success, a negative error code on failure
+- *
+- * @deprecated use the new AVFifo-API with av_fifo_peek() when func == NULL,
+- *             av_fifo_peek_to_cb() otherwise
+- */
+-attribute_deprecated
+-int av_fifo_generic_peek(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int));
+-
+-/**
+- * Feed data from an AVFifoBuffer to a user-supplied callback.
+- * @param f AVFifoBuffer to read from
+- * @param buf_size number of bytes to read
+- * @param func generic read function
+- * @param dest data destination
+- *
+- * @return a non-negative number on success, a negative error code on failure
+- *
+- * @deprecated use the new AVFifo-API with av_fifo_read() when func == NULL,
+- *             av_fifo_read_to_cb() otherwise
+- */
+-attribute_deprecated
+-int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int));
+-
+-/**
+- * Feed data from a user-supplied callback to an AVFifoBuffer.
+- * @param f AVFifoBuffer to write to
+- * @param src data source; non-const since it may be used as a
+- * modifiable context by the function defined in func
+- * @param size number of bytes to write
+- * @param func generic write function; the first parameter is src,
+- * the second is dest_buf, the third is dest_buf_size.
+- * func must return the number of bytes written to dest_buf, or <= 0 to
+- * indicate no more data available to write.
+- * If func is NULL, src is interpreted as a simple byte array for source data.
+- * @return the number of bytes written to the FIFO or a negative error code on failure
+- *
+- * @deprecated use the new AVFifo-API with av_fifo_write() when func == NULL,
+- *             av_fifo_write_from_cb() otherwise
+- */
+-attribute_deprecated
+-int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int));
+-
+-/**
+- * Resize an AVFifoBuffer.
+- * In case of reallocation failure, the old FIFO is kept unchanged.
+- *
+- * @param f AVFifoBuffer to resize
+- * @param size new AVFifoBuffer size in bytes
+- * @return <0 for failure, >=0 otherwise
+- *
+- * @deprecated use the new AVFifo-API with av_fifo_grow2() to increase FIFO size,
+- *             decreasing FIFO size is not supported
+- */
+-attribute_deprecated
+-int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size);
+-
+-/**
+- * Enlarge an AVFifoBuffer.
+- * In case of reallocation failure, the old FIFO is kept unchanged.
+- * The new fifo size may be larger than the requested size.
+- *
+- * @param f AVFifoBuffer to resize
+- * @param additional_space the amount of space in bytes to allocate in addition to av_fifo_size()
+- * @return <0 for failure, >=0 otherwise
+- *
+- * @deprecated use the new AVFifo-API with av_fifo_grow2(); note that unlike
+- * this function it adds to the allocated size, rather than to the used size
+- */
+-attribute_deprecated
+-int av_fifo_grow(AVFifoBuffer *f, unsigned int additional_space);
+-
+-/**
+- * Read and discard the specified amount of data from an AVFifoBuffer.
+- * @param f AVFifoBuffer to read from
+- * @param size amount of data to read in bytes
+- *
+- * @deprecated use the new AVFifo-API with av_fifo_drain2()
+- */
+-attribute_deprecated
+-void av_fifo_drain(AVFifoBuffer *f, int size);
+-
+-#if FF_API_FIFO_PEEK2
+-/**
+- * Return a pointer to the data stored in a FIFO buffer at a certain offset.
+- * The FIFO buffer is not modified.
+- *
+- * @param f    AVFifoBuffer to peek at, f must be non-NULL
+- * @param offs an offset in bytes, its absolute value must be less
+- *             than the used buffer size or the returned pointer will
+- *             point outside to the buffer data.
+- *             The used buffer size can be checked with av_fifo_size().
+- * @deprecated use the new AVFifo-API with av_fifo_peek() or av_fifo_peek_to_cb()
+- */
+-attribute_deprecated
+-static inline uint8_t *av_fifo_peek2(const AVFifoBuffer *f, int offs)
+-{
+-    uint8_t *ptr = f->rptr + offs;
+-    if (ptr >= f->end)
+-        ptr = f->buffer + (ptr - f->end);
+-    else if (ptr < f->buffer)
+-        ptr = f->end - (f->buffer - ptr);
+-    return ptr;
+-}
+-#endif
+-#endif
+-
+ /**
+  * @}
+  */
+ 
+ #endif /* AVUTIL_FIFO_H */
+diff --git a/media/ffvpx/libavutil/film_grain_params.c b/media/ffvpx/libavutil/film_grain_params.c
+--- a/media/ffvpx/libavutil/film_grain_params.c
++++ b/media/ffvpx/libavutil/film_grain_params.c
+@@ -12,31 +12,95 @@
+  * 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
+  */
+ 
+ #include "film_grain_params.h"
++#include "mem.h"
++#include "pixdesc.h"
+ 
+ AVFilmGrainParams *av_film_grain_params_alloc(size_t *size)
+ {
+     AVFilmGrainParams *params = av_mallocz(sizeof(AVFilmGrainParams));
+ 
+     if (size)
+         *size = sizeof(*params);
+ 
+     return params;
+ }
+ 
+ AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame)
+ {
++    AVFilmGrainParams *fgp;
+     AVFrameSideData *side_data = av_frame_new_side_data(frame,
+                                                         AV_FRAME_DATA_FILM_GRAIN_PARAMS,
+                                                         sizeof(AVFilmGrainParams));
+     if (!side_data)
+         return NULL;
+ 
+-    memset(side_data->data, 0, sizeof(AVFilmGrainParams));
++    fgp = (AVFilmGrainParams *) side_data->data;
++    *fgp = (AVFilmGrainParams) {
++        .color_range     = AVCOL_RANGE_UNSPECIFIED,
++        .color_primaries = AVCOL_PRI_UNSPECIFIED,
++        .color_trc       = AVCOL_TRC_UNSPECIFIED,
++        .color_space     = AVCOL_SPC_UNSPECIFIED,
++    };
++
++    return fgp;
++}
++
++const AVFilmGrainParams *av_film_grain_params_select(const AVFrame *frame)
++{
++    const AVFilmGrainParams *fgp, *best = NULL;
++    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
++    int bit_depth_luma, bit_depth_chroma;
++    if (!desc)
++        return NULL;
++
++    /* There are no YUV formats with different bit depth per component,
++     * so just check both against the first component for simplicity */
++    bit_depth_luma = bit_depth_chroma = desc->comp[0].depth;
++
++    for (int i = 0; i < frame->nb_side_data; i++) {
++        if (frame->side_data[i]->type != AV_FRAME_DATA_FILM_GRAIN_PARAMS)
++            continue;
++        fgp = (const AVFilmGrainParams*)frame->side_data[i]->data;
++        if (fgp->width  && fgp->width  > frame->width ||
++            fgp->height && fgp->height > frame->height)
++            continue;
+ 
+-    return (AVFilmGrainParams *)side_data->data;
++#define CHECK(a, b, unspec)                                     \
++        if ((a) != (unspec) && (b) != (unspec) && (a) != (b))   \
++            continue
++
++        CHECK(fgp->bit_depth_luma,   bit_depth_luma,         0);
++        CHECK(fgp->bit_depth_chroma, bit_depth_chroma,       0);
++        CHECK(fgp->color_range,      frame->color_range,     AVCOL_RANGE_UNSPECIFIED);
++        CHECK(fgp->color_primaries,  frame->color_primaries, AVCOL_PRI_UNSPECIFIED);
++        CHECK(fgp->color_trc,        frame->color_trc,       AVCOL_TRC_UNSPECIFIED);
++        CHECK(fgp->color_space,      frame->colorspace,      AVCOL_SPC_UNSPECIFIED);
++
++        switch (fgp->type) {
++        case AV_FILM_GRAIN_PARAMS_NONE:
++            continue;
++        case AV_FILM_GRAIN_PARAMS_AV1:
++            /* AOM FGS needs an exact match for the chroma resolution */
++            if (fgp->subsampling_x != desc->log2_chroma_w ||
++                fgp->subsampling_y != desc->log2_chroma_h)
++                continue;
++            break;
++        case AV_FILM_GRAIN_PARAMS_H274:
++            /* H.274 FGS can be adapted to any lower chroma resolution */
++            if (fgp->subsampling_x > desc->log2_chroma_w ||
++                fgp->subsampling_y > desc->log2_chroma_h)
++                continue;
++            break;
++        }
++
++        if (!best || best->width < fgp->width || best->height < fgp->height)
++            best = fgp;
++    }
++
++    return best;
+ }
+diff --git a/media/ffvpx/libavutil/film_grain_params.h b/media/ffvpx/libavutil/film_grain_params.h
+--- a/media/ffvpx/libavutil/film_grain_params.h
++++ b/media/ffvpx/libavutil/film_grain_params.h
+@@ -131,30 +131,52 @@ typedef struct AVFilmGrainAOMParams {
+  */
+ typedef struct AVFilmGrainH274Params {
+     /**
+      * Specifies the film grain simulation mode.
+      * 0 = Frequency filtering, 1 = Auto-regression
+      */
+     int model_id;
+ 
+-    /**
+-     * Specifies the bit depth used for the luma component.
+-     */
++#if FF_API_H274_FILM_GRAIN_VCS
++  /**
++   * TODO: On this ABI bump, please also re-order the fields in
++   * AVFilmGrainParams (see below)
++   */
++
++  /**
++   * Specifies the bit depth used for the luma component.
++   *
++   * @deprecated use AVFilmGrainParams.bit_depth_luma.
++   */
++    attribute_deprecated
+     int bit_depth_luma;
+ 
+     /**
+      * Specifies the bit depth used for the chroma components.
++     *
++     * @deprecated use AVFilmGrainParams.bit_depth_chroma.
+      */
++    attribute_deprecated
+     int bit_depth_chroma;
+ 
++    /**
++     * Specifies the video signal characteristics.
++     *
++     * @deprecated use AVFilmGrainParams.color_{range,primaries,trc,space}.
++     */
++    attribute_deprecated
+     enum AVColorRange                  color_range;
++    attribute_deprecated
+     enum AVColorPrimaries              color_primaries;
++    attribute_deprecated
+     enum AVColorTransferCharacteristic color_trc;
++    attribute_deprecated
+     enum AVColorSpace                  color_space;
++#endif
+ 
+     /**
+      * Specifies the blending mode used to blend the simulated film grain
+      * with the decoded images.
+      *
+      * 0 = Additive, 1 = Multiplicative
+      */
+     int blending_mode_id;
+@@ -226,21 +248,50 @@ typedef struct AVFilmGrainParams {
+      *       SMPTE RDD 5-2006.
+      */
+     uint64_t seed;
+ 
+     /**
+      * Additional fields may be added both here and in any structure included.
+      * If a codec's film grain structure differs slightly over another
+      * codec's, fields within may change meaning depending on the type.
++     *
++     * TODO: Move this to the end of the structure, at the next ABI bump.
+      */
+     union {
+         AVFilmGrainAOMParams aom;
+         AVFilmGrainH274Params h274;
+     } codec;
++
++    /**
++     * Intended display resolution. May be 0 if the codec does not specify
++     * any restrictions.
++     */
++
++    int width, height;
++
++    /**
++     * Intended subsampling ratio, or 0 for luma-only streams.
++     */
++    int subsampling_x, subsampling_y;
++
++    /**
++     * Intended video signal characteristics.
++     */
++    enum AVColorRange                  color_range;
++    enum AVColorPrimaries              color_primaries;
++    enum AVColorTransferCharacteristic color_trc;
++    enum AVColorSpace                  color_space;
++
++    /**
++     * Intended bit depth, or 0 for unknown/unspecified.
++     */
++    int bit_depth_luma;
++    int bit_depth_chroma;
++
+ } AVFilmGrainParams;
+ 
+ /**
+  * Allocate an AVFilmGrainParams structure and set its fields to
+  * default values. The resulting struct can be freed using av_freep().
+  * If size is not NULL it will be set to the number of bytes allocated.
+  *
+  * @return An AVFilmGrainParams filled with default values or NULL
+@@ -252,9 +303,20 @@ AVFilmGrainParams *av_film_grain_params_
+  * Allocate a complete AVFilmGrainParams and add it to the frame.
+  *
+  * @param frame The frame which side data is added to.
+  *
+  * @return The AVFilmGrainParams structure to be filled by caller.
+  */
+ AVFilmGrainParams *av_film_grain_params_create_side_data(AVFrame *frame);
+ 
++/**
++ * Select the most appropriate film grain parameters set for the frame,
++ * taking into account the frame's format, resolution and video signal
++ * characteristics.
++ *
++ * @note, for H.274, this may select a film grain parameter set with
++ * greater chroma resolution than the frame. Users should take care to
++ * correctly adjust the chroma grain frequency to the frame.
++ */
++const AVFilmGrainParams *av_film_grain_params_select(const AVFrame *frame);
++
+ #endif /* AVUTIL_FILM_GRAIN_PARAMS_H */
+diff --git a/media/ffvpx/libavutil/fixed_dsp.c b/media/ffvpx/libavutil/fixed_dsp.c
+--- a/media/ffvpx/libavutil/fixed_dsp.c
++++ b/media/ffvpx/libavutil/fixed_dsp.c
+@@ -42,16 +42,17 @@
+  *
+  * 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
+  */
+ 
+ #include "common.h"
+ #include "fixed_dsp.h"
++#include "mem.h"
+ 
+ static void vector_fmul_add_c(int *dst, const int *src0, const int *src1, const int *src2, int len){
+     int i;
+     int64_t accu;
+ 
+     for (i=0; i<len; i++) {
+         accu = (int64_t)src0[i] * src1[i];
+         dst[i] = src2[i] + (int)((accu + 0x40000000) >> 31);
+@@ -130,17 +131,17 @@ static int scalarproduct_fixed_c(const i
+     int i;
+ 
+     for (i = 0; i < len; i++)
+         p += (int64_t)v1[i] * v2[i];
+ 
+     return (int)(p >> 31);
+ }
+ 
+-static void butterflies_fixed_c(int *av_restrict v1s, int *av_restrict v2, int len)
++static void butterflies_fixed_c(int *restrict v1s, int *restrict v2, int len)
+ {
+     int i;
+     unsigned int *v1 = v1s;
+ 
+     for (i = 0; i < len; i++){
+         int t = v1[i] - v2[i];
+         v1[i] += v2[i];
+         v2[i] = t;
+diff --git a/media/ffvpx/libavutil/fixed_dsp.h b/media/ffvpx/libavutil/fixed_dsp.h
+--- a/media/ffvpx/libavutil/fixed_dsp.h
++++ b/media/ffvpx/libavutil/fixed_dsp.h
+@@ -44,17 +44,16 @@
+  * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ 
+ #ifndef AVUTIL_FIXED_DSP_H
+ #define AVUTIL_FIXED_DSP_H
+ 
+ #include <stdint.h>
+-#include "config.h"
+ #include "attributes.h"
+ #include "libavcodec/mathops.h"
+ 
+ typedef struct AVFixedDSPContext {
+     /* Assume len is a multiple of 16, and arrays are 32-byte aligned */
+     /* Results of multiplications are scaled down by 31 bit (and rounded) if not
+      * stated otherwise */
+ 
+@@ -145,17 +144,17 @@ typedef struct AVFixedDSPContext {
+ 
+     /**
+      * Calculate the sum and difference of two vectors of integers.
+      *
+      * @param v1  first input vector, sum output, 16-byte aligned
+      * @param v2  second input vector, difference output, 16-byte aligned
+      * @param len length of vectors, multiple of 4
+      */
+-    void (*butterflies_fixed)(int *av_restrict v1, int *av_restrict v2, int len);
++    void (*butterflies_fixed)(int *restrict v1, int *restrict v2, int len);
+ } AVFixedDSPContext;
+ 
+ /**
+  * Allocate and initialize a fixed DSP context.
+  * note: should be freed with a av_free call when no longer needed.
+  *
+  * @param strict  setting to non-zero avoids using functions which may not be IEEE-754 compliant
+  */
+diff --git a/media/ffvpx/libavutil/float_dsp.c b/media/ffvpx/libavutil/float_dsp.c
+--- a/media/ffvpx/libavutil/float_dsp.c
++++ b/media/ffvpx/libavutil/float_dsp.c
+@@ -104,17 +104,17 @@ static void vector_fmul_reverse_c(float 
+ {
+     int i;
+ 
+     src1 += len-1;
+     for (i = 0; i < len; i++)
+         dst[i] = src0[i] * src1[-i];
+ }
+ 
+-static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2,
++static void butterflies_float_c(float *restrict v1, float *restrict v2,
+                                 int len)
+ {
+     int i;
+ 
+     for (i = 0; i < len; i++) {
+         float t = v1[i] - v2[i];
+         v1[i] += v2[i];
+         v2[i] = t;
+diff --git a/media/ffvpx/libavutil/float_dsp.h b/media/ffvpx/libavutil/float_dsp.h
+--- a/media/ffvpx/libavutil/float_dsp.h
++++ b/media/ffvpx/libavutil/float_dsp.h
+@@ -14,18 +14,16 @@
+  * 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
+  */
+ 
+ #ifndef AVUTIL_FLOAT_DSP_H
+ #define AVUTIL_FLOAT_DSP_H
+ 
+-#include "config.h"
+-
+ typedef struct AVFloatDSPContext {
+     /**
+      * Calculate the entry wise product of two vectors of floats and store the result in
+      * a vector of floats.
+      *
+      * @param dst  output vector
+      *             constraints: 32-byte aligned
+      * @param src0 first input vector
+@@ -156,17 +154,17 @@ typedef struct AVFloatDSPContext {
+ 
+     /**
+      * Calculate the sum and difference of two vectors of floats.
+      *
+      * @param v1  first input vector, sum output, 16-byte aligned
+      * @param v2  second input vector, difference output, 16-byte aligned
+      * @param len length of vectors, multiple of 4
+      */
+-    void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len);
++    void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);
+ 
+     /**
+      * Calculate the scalar product of two vectors of floats.
+      *
+      * @param v1  first vector, 16-byte aligned
+      * @param v2  second vector, 16-byte aligned
+      * @param len length of vectors, multiple of 4
+      *
+diff --git a/media/ffvpx/libavutil/frame.c b/media/ffvpx/libavutil/frame.c
+--- a/media/ffvpx/libavutil/frame.c
++++ b/media/ffvpx/libavutil/frame.c
+@@ -23,36 +23,54 @@
+ #include "cpu.h"
+ #include "dict.h"
+ #include "frame.h"
+ #include "imgutils.h"
+ #include "mem.h"
+ #include "samplefmt.h"
+ #include "hwcontext.h"
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-#define CHECK_CHANNELS_CONSISTENCY(frame) \
+-    av_assert2(!(frame)->channel_layout || \
+-               (frame)->channels == \
+-               av_get_channel_layout_nb_channels((frame)->channel_layout))
+-#endif
++static const AVSideDataDescriptor sd_props[] = {
++    [AV_FRAME_DATA_PANSCAN]                     = { "AVPanScan" },
++    [AV_FRAME_DATA_A53_CC]                      = { "ATSC A53 Part 4 Closed Captions" },
++    [AV_FRAME_DATA_MATRIXENCODING]              = { "AVMatrixEncoding" },
++    [AV_FRAME_DATA_DOWNMIX_INFO]                = { "Metadata relevant to a downmix procedure" },
++    [AV_FRAME_DATA_AFD]                         = { "Active format description" },
++    [AV_FRAME_DATA_MOTION_VECTORS]              = { "Motion vectors" },
++    [AV_FRAME_DATA_SKIP_SAMPLES]                = { "Skip samples" },
++    [AV_FRAME_DATA_GOP_TIMECODE]                = { "GOP timecode" },
++    [AV_FRAME_DATA_S12M_TIMECODE]               = { "SMPTE 12-1 timecode" },
++    [AV_FRAME_DATA_DYNAMIC_HDR_PLUS]            = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)" },
++    [AV_FRAME_DATA_DYNAMIC_HDR_VIVID]           = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)" },
++    [AV_FRAME_DATA_REGIONS_OF_INTEREST]         = { "Regions Of Interest" },
++    [AV_FRAME_DATA_VIDEO_ENC_PARAMS]            = { "Video encoding parameters" },
++    [AV_FRAME_DATA_FILM_GRAIN_PARAMS]           = { "Film grain parameters" },
++    [AV_FRAME_DATA_DETECTION_BBOXES]            = { "Bounding boxes for object detection and classification" },
++    [AV_FRAME_DATA_DOVI_RPU_BUFFER]             = { "Dolby Vision RPU Data" },
++    [AV_FRAME_DATA_DOVI_METADATA]               = { "Dolby Vision Metadata" },
++    [AV_FRAME_DATA_STEREO3D]                    = { "Stereo 3D",                                    AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_REPLAYGAIN]                  = { "AVReplayGain",                                 AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_DISPLAYMATRIX]               = { "3x3 displaymatrix",                            AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_AUDIO_SERVICE_TYPE]          = { "Audio service type",                           AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA]  = { "Mastering display metadata",                   AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL]         = { "Content light level metadata",                 AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { "Ambient viewing environment",                  AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_SPHERICAL]                   = { "Spherical Mapping",                            AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_ICC_PROFILE]                 = { "ICC profile",                                  AV_SIDE_DATA_PROP_GLOBAL },
++    [AV_FRAME_DATA_SEI_UNREGISTERED]            = { "H.26[45] User Data Unregistered SEI message",  AV_SIDE_DATA_PROP_MULTI },
++};
+ 
+ static void get_frame_defaults(AVFrame *frame)
+ {
+     memset(frame, 0, sizeof(*frame));
+ 
+     frame->pts                   =
+     frame->pkt_dts               = AV_NOPTS_VALUE;
+     frame->best_effort_timestamp = AV_NOPTS_VALUE;
+     frame->duration            = 0;
+-#if FF_API_PKT_DURATION
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    frame->pkt_duration        = 0;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+ #if FF_API_FRAME_PKT
+ FF_DISABLE_DEPRECATION_WARNINGS
+     frame->pkt_pos             = -1;
+     frame->pkt_size            = -1;
+ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+     frame->time_base           = (AVRational){ 0, 1 };
+     frame->sample_aspect_ratio = (AVRational){ 0, 1 };
+@@ -70,24 +88,66 @@ static void free_side_data(AVFrameSideDa
+ {
+     AVFrameSideData *sd = *ptr_sd;
+ 
+     av_buffer_unref(&sd->buf);
+     av_dict_free(&sd->metadata);
+     av_freep(ptr_sd);
+ }
+ 
+-static void wipe_side_data(AVFrame *frame)
++static void wipe_side_data(AVFrameSideData ***sd, int *nb_side_data)
++{
++    for (int i = 0; i < *nb_side_data; i++) {
++        free_side_data(&((*sd)[i]));
++    }
++    *nb_side_data = 0;
++
++    av_freep(sd);
++}
++
++static void frame_side_data_wipe(AVFrame *frame)
++{
++    wipe_side_data(&frame->side_data, &frame->nb_side_data);
++}
++
++void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
++{
++    wipe_side_data(sd, nb_sd);
++}
++
++static void remove_side_data(AVFrameSideData ***sd, int *nb_side_data,
++                             const enum AVFrameSideDataType type)
+ {
+-    for (int i = 0; i < frame->nb_side_data; i++) {
+-        free_side_data(&frame->side_data[i]);
++    for (int i = *nb_side_data - 1; i >= 0; i--) {
++        AVFrameSideData *entry = ((*sd)[i]);
++        if (entry->type != type)
++            continue;
++
++        free_side_data(&entry);
++
++        ((*sd)[i]) = ((*sd)[*nb_side_data - 1]);
++        (*nb_side_data)--;
+     }
+-    frame->nb_side_data = 0;
++}
+ 
+-    av_freep(&frame->side_data);
++static void remove_side_data_by_entry(AVFrameSideData ***sd, int *nb_sd,
++                                      const AVFrameSideData *target)
++{
++    for (int i = *nb_sd - 1; i >= 0; i--) {
++        AVFrameSideData *entry = ((*sd)[i]);
++        if (entry != target)
++            continue;
++
++        free_side_data(&entry);
++
++        ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
++        (*nb_sd)--;
++
++        return;
++    }
+ }
+ 
+ AVFrame *av_frame_alloc(void)
+ {
+     AVFrame *frame = av_malloc(sizeof(*frame));
+ 
+     if (!frame)
+         return NULL;
+@@ -176,31 +236,16 @@ fail:
+ }
+ 
+ static int get_audio_buffer(AVFrame *frame, int align)
+ {
+     int planar   = av_sample_fmt_is_planar(frame->format);
+     int channels, planes;
+     int ret;
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    if (!frame->ch_layout.nb_channels) {
+-        if (frame->channel_layout) {
+-            av_channel_layout_from_mask(&frame->ch_layout, frame->channel_layout);
+-        } else {
+-            frame->ch_layout.nb_channels = frame->channels;
+-            frame->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+-        }
+-    }
+-    frame->channels = frame->ch_layout.nb_channels;
+-    frame->channel_layout = frame->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
+-                            frame->ch_layout.u.mask : 0;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     channels = frame->ch_layout.nb_channels;
+     planes   = planar ? channels : 1;
+     if (!frame->linesize[0]) {
+         ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
+                                          frame->nb_samples, frame->format,
+                                          align);
+         if (ret < 0)
+             return ret;
+@@ -240,27 +285,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
+ 
+ }
+ 
+ int av_frame_get_buffer(AVFrame *frame, int align)
+ {
+     if (frame->format < 0)
+         return AVERROR(EINVAL);
+ 
+-FF_DISABLE_DEPRECATION_WARNINGS
+     if (frame->width > 0 && frame->height > 0)
+         return get_video_buffer(frame, align);
+     else if (frame->nb_samples > 0 &&
+-             (av_channel_layout_check(&frame->ch_layout)
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-              || frame->channel_layout || frame->channels > 0
+-#endif
+-             ))
++             (av_channel_layout_check(&frame->ch_layout)))
+         return get_audio_buffer(frame, align);
+-FF_ENABLE_DEPRECATION_WARNINGS
+ 
+     return AVERROR(EINVAL);
+ }
+ 
+ static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
+ {
+     int ret;
+ 
+@@ -293,35 +332,19 @@ FF_ENABLE_DEPRECATION_WARNINGS
+     dst->opaque                 = src->opaque;
+     dst->pkt_dts                = src->pkt_dts;
+ #if FF_API_FRAME_PKT
+ FF_DISABLE_DEPRECATION_WARNINGS
+     dst->pkt_pos                = src->pkt_pos;
+     dst->pkt_size               = src->pkt_size;
+ FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+-#if FF_API_PKT_DURATION
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    dst->pkt_duration           = src->pkt_duration;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     dst->time_base              = src->time_base;
+-#if FF_API_REORDERED_OPAQUE
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    dst->reordered_opaque       = src->reordered_opaque;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     dst->quality                = src->quality;
+     dst->best_effort_timestamp  = src->best_effort_timestamp;
+-#if FF_API_FRAME_PICTURE_NUMBER
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    dst->coded_picture_number   = src->coded_picture_number;
+-    dst->display_picture_number = src->display_picture_number;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     dst->flags                  = src->flags;
+     dst->decode_error_flags     = src->decode_error_flags;
+     dst->color_primaries        = src->color_primaries;
+     dst->color_trc              = src->color_trc;
+     dst->colorspace             = src->colorspace;
+     dst->color_range            = src->color_range;
+     dst->chroma_location        = src->chroma_location;
+ 
+@@ -332,79 +355,57 @@ FF_ENABLE_DEPRECATION_WARNINGS
+         AVFrameSideData *sd_dst;
+         if (   sd_src->type == AV_FRAME_DATA_PANSCAN
+             && (src->width != dst->width || src->height != dst->height))
+             continue;
+         if (force_copy) {
+             sd_dst = av_frame_new_side_data(dst, sd_src->type,
+                                             sd_src->size);
+             if (!sd_dst) {
+-                wipe_side_data(dst);
++                frame_side_data_wipe(dst);
+                 return AVERROR(ENOMEM);
+             }
+             memcpy(sd_dst->data, sd_src->data, sd_src->size);
+         } else {
+             AVBufferRef *ref = av_buffer_ref(sd_src->buf);
+             sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
+             if (!sd_dst) {
+                 av_buffer_unref(&ref);
+-                wipe_side_data(dst);
++                frame_side_data_wipe(dst);
+                 return AVERROR(ENOMEM);
+             }
+         }
+         av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
+     }
+ 
+     ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
+     ret |= av_buffer_replace(&dst->private_ref, src->private_ref);
+     return ret;
+ }
+ 
+ int av_frame_ref(AVFrame *dst, const AVFrame *src)
+ {
+     int ret = 0;
+ 
+     av_assert1(dst->width == 0 && dst->height == 0);
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    av_assert1(dst->channels == 0);
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     av_assert1(dst->ch_layout.nb_channels == 0 &&
+                dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
+ 
+     dst->format         = src->format;
+     dst->width          = src->width;
+     dst->height         = src->height;
+     dst->nb_samples     = src->nb_samples;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    dst->channels       = src->channels;
+-    dst->channel_layout = src->channel_layout;
+-    if (!av_channel_layout_check(&src->ch_layout)) {
+-        if (src->channel_layout)
+-            av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout);
+-        else {
+-            dst->ch_layout.nb_channels = src->channels;
+-            dst->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+-        }
+-    }
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+ 
+     ret = frame_copy_props(dst, src, 0);
+     if (ret < 0)
+         goto fail;
+ 
+-    // this check is needed only until FF_API_OLD_CHANNEL_LAYOUT is out
+-    if (av_channel_layout_check(&src->ch_layout)) {
+-        ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
+-        if (ret < 0)
+-            goto fail;
+-    }
++    ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
++    if (ret < 0)
++        goto fail;
+ 
+     /* duplicate the frame data if it's not refcounted */
+     if (!src->buf[0]) {
+         ret = av_frame_get_buffer(dst, 0);
+         if (ret < 0)
+             goto fail;
+ 
+         ret = av_frame_copy(dst, src);
+@@ -498,39 +499,22 @@ int av_frame_replace(AVFrame *dst, const
+         if (ret < 0)
+             goto fail;
+     }
+ 
+     dst->format         = src->format;
+     dst->width          = src->width;
+     dst->height         = src->height;
+     dst->nb_samples     = src->nb_samples;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    dst->channels       = src->channels;
+-    dst->channel_layout = src->channel_layout;
+-    if (!av_channel_layout_check(&src->ch_layout)) {
+-        av_channel_layout_uninit(&dst->ch_layout);
+-        if (src->channel_layout)
+-            av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout);
+-        else {
+-            dst->ch_layout.nb_channels = src->channels;
+-            dst->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+-        }
+-    } else {
+-#endif
++
+     ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
+     if (ret < 0)
+         goto fail;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-    }
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+ 
+-    wipe_side_data(dst);
++    frame_side_data_wipe(dst);
+     av_dict_free(&dst->metadata);
+     ret = frame_copy_props(dst, src, 0);
+     if (ret < 0)
+         goto fail;
+ 
+     /* replace the buffers */
+     for (int i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) {
+         ret = av_buffer_replace(&dst->buf[i], src->buf[i]);
+@@ -619,17 +603,17 @@ AVFrame *av_frame_clone(const AVFrame *s
+     return ret;
+ }
+ 
+ void av_frame_unref(AVFrame *frame)
+ {
+     if (!frame)
+         return;
+ 
+-    wipe_side_data(frame);
++    frame_side_data_wipe(frame);
+ 
+     for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
+         av_buffer_unref(&frame->buf[i]);
+     for (int i = 0; i < frame->nb_extended_buf; i++)
+         av_buffer_unref(&frame->extended_buf[i]);
+     av_freep(&frame->extended_buf);
+     av_dict_free(&frame->metadata);
+ 
+@@ -644,21 +628,16 @@ void av_frame_unref(AVFrame *frame)
+     av_channel_layout_uninit(&frame->ch_layout);
+ 
+     get_frame_defaults(frame);
+ }
+ 
+ void av_frame_move_ref(AVFrame *dst, AVFrame *src)
+ {
+     av_assert1(dst->width == 0 && dst->height == 0);
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    av_assert1(dst->channels == 0);
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     av_assert1(dst->ch_layout.nb_channels == 0 &&
+                dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
+ 
+     *dst = *src;
+     if (src->extended_data == src->data)
+         dst->extended_data = dst->data;
+     get_frame_defaults(src);
+ }
+@@ -687,22 +666,16 @@ int av_frame_make_writable(AVFrame *fram
+ 
+     if (av_frame_is_writable(frame))
+         return 0;
+ 
+     memset(&tmp, 0, sizeof(tmp));
+     tmp.format         = frame->format;
+     tmp.width          = frame->width;
+     tmp.height         = frame->height;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    tmp.channels       = frame->channels;
+-    tmp.channel_layout = frame->channel_layout;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     tmp.nb_samples     = frame->nb_samples;
+     ret = av_channel_layout_copy(&tmp.ch_layout, &frame->ch_layout);
+     if (ret < 0) {
+         av_frame_unref(&tmp);
+         return ret;
+     }
+ 
+     if (frame->hw_frames_ctx)
+@@ -740,25 +713,16 @@ int av_frame_copy_props(AVFrame *dst, co
+ 
+ AVBufferRef *av_frame_get_plane_buffer(const AVFrame *frame, int plane)
+ {
+     uint8_t *data;
+     int planes;
+ 
+     if (frame->nb_samples) {
+         int channels = frame->ch_layout.nb_channels;
+-
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-        if (!channels) {
+-            channels = frame->channels;
+-            CHECK_CHANNELS_CONSISTENCY(frame);
+-        }
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+         if (!channels)
+             return NULL;
+         planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
+     } else
+         planes = 4;
+ 
+     if (plane < 0 || plane >= planes || !frame->extended_data[plane])
+         return NULL;
+@@ -772,68 +736,147 @@ FF_ENABLE_DEPRECATION_WARNINGS
+     for (int i = 0; i < frame->nb_extended_buf; i++) {
+         AVBufferRef *buf = frame->extended_buf[i];
+         if (data >= buf->data && data < buf->data + buf->size)
+             return buf;
+     }
+     return NULL;
+ }
+ 
+-AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
+-                                                 enum AVFrameSideDataType type,
+-                                                 AVBufferRef *buf)
++static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
++                                                   int *nb_sd,
++                                                   enum AVFrameSideDataType type,
++                                                   AVBufferRef *buf, uint8_t *data,
++                                                   size_t size)
+ {
+     AVFrameSideData *ret, **tmp;
+ 
+-    if (!buf)
+-        return NULL;
+-
+-    if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1)
++    // *nb_sd + 1 needs to fit into an int and a size_t.
++    if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX))
+         return NULL;
+ 
+-    tmp = av_realloc(frame->side_data,
+-                     (frame->nb_side_data + 1) * sizeof(*frame->side_data));
++    tmp = av_realloc_array(*sd, sizeof(**sd), *nb_sd + 1);
+     if (!tmp)
+         return NULL;
+-    frame->side_data = tmp;
++    *sd = tmp;
+ 
+     ret = av_mallocz(sizeof(*ret));
+     if (!ret)
+         return NULL;
+ 
+     ret->buf = buf;
+-    ret->data = ret->buf->data;
+-    ret->size = buf->size;
++    ret->data = data;
++    ret->size = size;
+     ret->type = type;
+ 
+-    frame->side_data[frame->nb_side_data++] = ret;
++    (*sd)[(*nb_sd)++] = ret;
+ 
+     return ret;
+ }
+ 
++static AVFrameSideData *add_side_data_from_buf(AVFrameSideData ***sd,
++                                               int *nb_sd,
++                                               enum AVFrameSideDataType type,
++                                               AVBufferRef *buf)
++{
++    if (!buf)
++        return NULL;
++
++    return add_side_data_from_buf_ext(sd, nb_sd, type, buf, buf->data, buf->size);
++}
++
++AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
++                                                 enum AVFrameSideDataType type,
++                                                 AVBufferRef *buf)
++{
++    return
++        add_side_data_from_buf(
++            &frame->side_data, &frame->nb_side_data, type, buf);
++}
++
+ AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
+                                         enum AVFrameSideDataType type,
+                                         size_t size)
+ {
+     AVFrameSideData *ret;
+     AVBufferRef *buf = av_buffer_alloc(size);
+     ret = av_frame_new_side_data_from_buf(frame, type, buf);
+     if (!ret)
+         av_buffer_unref(&buf);
+     return ret;
+ }
+ 
++AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
++                                        enum AVFrameSideDataType type,
++                                        size_t size, unsigned int flags)
++{
++    AVBufferRef     *buf = av_buffer_alloc(size);
++    AVFrameSideData *ret = NULL;
++
++    if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
++        remove_side_data(sd, nb_sd, type);
++
++    ret = add_side_data_from_buf(sd, nb_sd, type, buf);
++    if (!ret)
++        av_buffer_unref(&buf);
++
++    return ret;
++}
++
++int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
++                             const AVFrameSideData *src, unsigned int flags)
++{
++    AVBufferRef     *buf    = NULL;
++    AVFrameSideData *sd_dst = NULL;
++    int              ret    = AVERROR_BUG;
++
++    if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
++        return AVERROR(EINVAL);
++
++    buf = av_buffer_ref(src->buf);
++    if (!buf)
++        return AVERROR(ENOMEM);
++
++    if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
++        remove_side_data(sd, nb_sd, src->type);
++
++    sd_dst = add_side_data_from_buf_ext(sd, nb_sd, src->type, buf,
++                                        src->data, src->size);
++    if (!sd_dst) {
++        av_buffer_unref(&buf);
++        return AVERROR(ENOMEM);
++    }
++
++    ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0);
++    if (ret < 0) {
++        remove_side_data_by_entry(sd, nb_sd, sd_dst);
++        return ret;
++    }
++
++    return 0;
++}
++
++const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *sd,
++                                                const int nb_sd,
++                                                enum AVFrameSideDataType type)
++{
++    for (int i = 0; i < nb_sd; i++) {
++        if (sd[i]->type == type)
++            return sd[i];
++    }
++    return NULL;
++}
++
+ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
+                                         enum AVFrameSideDataType type)
+ {
+-    for (int i = 0; i < frame->nb_side_data; i++) {
+-        if (frame->side_data[i]->type == type)
+-            return frame->side_data[i];
+-    }
+-    return NULL;
++    return (AVFrameSideData *)av_frame_side_data_get(
++        frame->side_data, frame->nb_side_data,
++        type
++    );
+ }
+ 
+ static int frame_copy_video(AVFrame *dst, const AVFrame *src)
+ {
+     int planes;
+ 
+     if (dst->width  < src->width ||
+         dst->height < src->height)
+@@ -855,40 +898,18 @@ static int frame_copy_video(AVFrame *dst
+ }
+ 
+ static int frame_copy_audio(AVFrame *dst, const AVFrame *src)
+ {
+     int planar   = av_sample_fmt_is_planar(dst->format);
+     int channels = dst->ch_layout.nb_channels;
+     int planes   = planar ? channels : 1;
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    if (!channels || !src->ch_layout.nb_channels) {
+-        if (dst->channels       != src->channels ||
+-            dst->channel_layout != src->channel_layout)
+-            return AVERROR(EINVAL);
+-        CHECK_CHANNELS_CONSISTENCY(src);
+-    }
+-    if (!channels) {
+-        channels = dst->channels;
+-        planes = planar ? channels : 1;
+-    }
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+     if (dst->nb_samples != src->nb_samples ||
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-        (av_channel_layout_check(&dst->ch_layout) &&
+-         av_channel_layout_check(&src->ch_layout) &&
+-#endif
+         av_channel_layout_compare(&dst->ch_layout, &src->ch_layout))
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-        )
+-#endif
+         return AVERROR(EINVAL);
+ 
+     for (int i = 0; i < planes; i++)
+         if (!dst->extended_data[i] || !src->extended_data[i])
+             return AVERROR(EINVAL);
+ 
+     av_samples_copy(dst->extended_data, src->extended_data, 0, 0,
+                     dst->nb_samples, channels, dst->format);
+@@ -896,75 +917,42 @@ FF_ENABLE_DEPRECATION_WARNINGS
+     return 0;
+ }
+ 
+ int av_frame_copy(AVFrame *dst, const AVFrame *src)
+ {
+     if (dst->format != src->format || dst->format < 0)
+         return AVERROR(EINVAL);
+ 
+-FF_DISABLE_DEPRECATION_WARNINGS
+     if (dst->width > 0 && dst->height > 0)
+         return frame_copy_video(dst, src);
+     else if (dst->nb_samples > 0 &&
+-             (av_channel_layout_check(&dst->ch_layout)
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-              || dst->channels > 0
+-#endif
+-            ))
++             (av_channel_layout_check(&dst->ch_layout)))
+         return frame_copy_audio(dst, src);
+-FF_ENABLE_DEPRECATION_WARNINGS
+ 
+     return AVERROR(EINVAL);
+ }
+ 
+ void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
+ {
+-    for (int i = frame->nb_side_data - 1; i >= 0; i--) {
+-        AVFrameSideData *sd = frame->side_data[i];
+-        if (sd->type == type) {
+-            free_side_data(&frame->side_data[i]);
+-            frame->side_data[i] = frame->side_data[frame->nb_side_data - 1];
+-            frame->nb_side_data--;
+-        }
+-    }
++    remove_side_data(&frame->side_data, &frame->nb_side_data, type);
++}
++
++const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type)
++{
++    unsigned t = type;
++    if (t < FF_ARRAY_ELEMS(sd_props) && sd_props[t].name)
++        return &sd_props[t];
++    return NULL;
+ }
+ 
+ const char *av_frame_side_data_name(enum AVFrameSideDataType type)
+ {
+-    switch(type) {
+-    case AV_FRAME_DATA_PANSCAN:         return "AVPanScan";
+-    case AV_FRAME_DATA_A53_CC:          return "ATSC A53 Part 4 Closed Captions";
+-    case AV_FRAME_DATA_STEREO3D:        return "Stereo 3D";
+-    case AV_FRAME_DATA_MATRIXENCODING:  return "AVMatrixEncoding";
+-    case AV_FRAME_DATA_DOWNMIX_INFO:    return "Metadata relevant to a downmix procedure";
+-    case AV_FRAME_DATA_REPLAYGAIN:      return "AVReplayGain";
+-    case AV_FRAME_DATA_DISPLAYMATRIX:   return "3x3 displaymatrix";
+-    case AV_FRAME_DATA_AFD:             return "Active format description";
+-    case AV_FRAME_DATA_MOTION_VECTORS:  return "Motion vectors";
+-    case AV_FRAME_DATA_SKIP_SAMPLES:    return "Skip samples";
+-    case AV_FRAME_DATA_AUDIO_SERVICE_TYPE:          return "Audio service type";
+-    case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA:  return "Mastering display metadata";
+-    case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL:         return "Content light level metadata";
+-    case AV_FRAME_DATA_GOP_TIMECODE:                return "GOP timecode";
+-    case AV_FRAME_DATA_S12M_TIMECODE:               return "SMPTE 12-1 timecode";
+-    case AV_FRAME_DATA_SPHERICAL:                   return "Spherical Mapping";
+-    case AV_FRAME_DATA_ICC_PROFILE:                 return "ICC profile";
+-    case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)";
+-    case AV_FRAME_DATA_DYNAMIC_HDR_VIVID: return "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)";
+-    case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest";
+-    case AV_FRAME_DATA_VIDEO_ENC_PARAMS:            return "Video encoding parameters";
+-    case AV_FRAME_DATA_SEI_UNREGISTERED:            return "H.26[45] User Data Unregistered SEI message";
+-    case AV_FRAME_DATA_FILM_GRAIN_PARAMS:           return "Film grain parameters";
+-    case AV_FRAME_DATA_DETECTION_BBOXES:            return "Bounding boxes for object detection and classification";
+-    case AV_FRAME_DATA_DOVI_RPU_BUFFER:             return "Dolby Vision RPU Data";
+-    case AV_FRAME_DATA_DOVI_METADATA:               return "Dolby Vision Metadata";
+-    case AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT: return "Ambient viewing environment";
+-    }
+-    return NULL;
++    const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
++    return desc ? desc->name : NULL;
+ }
+ 
+ static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame,
+                                  const AVPixFmtDescriptor *desc)
+ {
+     for (int i = 0; frame->data[i]; i++) {
+         const AVComponentDescriptor *comp = NULL;
+         int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0;
+diff --git a/media/ffvpx/libavutil/frame.h b/media/ffvpx/libavutil/frame.h
+--- a/media/ffvpx/libavutil/frame.h
++++ b/media/ffvpx/libavutil/frame.h
+@@ -175,16 +175,20 @@ enum AVFrameSideDataType {
+      * The data is stored as uint8_t in AVFrameSideData.data which is 16 bytes of
+      * uuid_iso_iec_11578 followed by AVFrameSideData.size - 16 bytes of user_data_payload_byte.
+      */
+     AV_FRAME_DATA_SEI_UNREGISTERED,
+ 
+     /**
+      * Film grain parameters for a frame, described by AVFilmGrainParams.
+      * Must be present for every frame which should have film grain applied.
++     *
++     * May be present multiple times, for example when there are multiple
++     * alternative parameter sets for different video signal characteristics.
++     * The user should select the most appropriate set for the application.
+      */
+     AV_FRAME_DATA_FILM_GRAIN_PARAMS,
+ 
+     /**
+      * Bounding boxes for object detection and classification,
+      * as described by AVDetectionBBoxHeader.
+      */
+     AV_FRAME_DATA_DETECTION_BBOXES,
+@@ -246,16 +250,47 @@ enum AVActiveFormatDescription {
+ typedef struct AVFrameSideData {
+     enum AVFrameSideDataType type;
+     uint8_t *data;
+     size_t   size;
+     AVDictionary *metadata;
+     AVBufferRef *buf;
+ } AVFrameSideData;
+ 
++enum AVSideDataProps {
++    /**
++     * The side data type can be used in stream-global structures.
++     * Side data types without this property are only meaningful on per-frame
++     * basis.
++     */
++    AV_SIDE_DATA_PROP_GLOBAL = (1 << 0),
++
++    /**
++     * Multiple instances of this side data type can be meaningfully present in
++     * a single side data array.
++     */
++    AV_SIDE_DATA_PROP_MULTI  = (1 << 1),
++};
++
++/**
++ * This struct describes the properties of a side data type. Its instance
++ * corresponding to a given type can be obtained from av_frame_side_data_desc().
++ */
++typedef struct AVSideDataDescriptor {
++    /**
++     * Human-readable side data description.
++     */
++    const char      *name;
++
++    /**
++     * Side data property flags, a combination of AVSideDataProps values.
++     */
++    unsigned         props;
++} AVSideDataDescriptor;
++
+ /**
+  * Structure describing a single Region Of Interest.
+  *
+  * When multiple regions are defined in a single side-data block, they
+  * should be ordered from most to least important - some encoders are only
+  * capable of supporting a limited number of distinct regions, so will have
+  * to truncate the list.
+  *
+@@ -461,29 +496,16 @@ typedef struct AVFrame {
+     /**
+      * Time base for the timestamps in this frame.
+      * In the future, this field may be set on frames output by decoders or
+      * filters, but its value will be by default ignored on input to encoders
+      * or filters.
+      */
+     AVRational time_base;
+ 
+-#if FF_API_FRAME_PICTURE_NUMBER
+-    /**
+-     * picture number in bitstream order
+-     */
+-    attribute_deprecated
+-    int coded_picture_number;
+-    /**
+-     * picture number in display order
+-     */
+-    attribute_deprecated
+-    int display_picture_number;
+-#endif
+-
+     /**
+      * quality (between 1 (good) and FF_LAMBDA_MAX (bad))
+      */
+     int quality;
+ 
+     /**
+      * Frame owner's private data.
+      *
+@@ -541,45 +563,21 @@ typedef struct AVFrame {
+ #if FF_API_PALETTE_HAS_CHANGED
+     /**
+      * Tell user application that palette has changed from previous frame.
+      */
+     attribute_deprecated
+     int palette_has_changed;
+ #endif
+ 
+-#if FF_API_REORDERED_OPAQUE
+-    /**
+-     * reordered opaque 64 bits (generally an integer or a double precision float
+-     * PTS but can be anything).
+-     * The user sets AVCodecContext.reordered_opaque to represent the input at
+-     * that time,
+-     * the decoder reorders values as needed and sets AVFrame.reordered_opaque
+-     * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
+-     *
+-     * @deprecated Use AV_CODEC_FLAG_COPY_OPAQUE instead
+-     */
+-    attribute_deprecated
+-    int64_t reordered_opaque;
+-#endif
+-
+     /**
+      * Sample rate of the audio data.
+      */
+     int sample_rate;
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-    /**
+-     * Channel layout of the audio data.
+-     * @deprecated use ch_layout instead
+-     */
+-    attribute_deprecated
+-    uint64_t channel_layout;
+-#endif
+-
+     /**
+      * AVBuffer references backing the data for this frame. All the pointers in
+      * data and extended_data must point inside one of the buffers in buf or
+      * extended_buf. This array must be filled contiguously -- if buf[i] is
+      * non-NULL then buf[j] must also be non-NULL for all j < i.
+      *
+      * There may be at most one AVBuffer per data plane, so for video this array
+      * always contains all the references. For planar audio with more than
+@@ -682,29 +680,16 @@ typedef struct AVFrame {
+      * - decoding: Read by user.
+      * @deprecated use AV_CODEC_FLAG_COPY_OPAQUE to pass through arbitrary user
+      *             data from packets to frames
+      */
+     attribute_deprecated
+     int64_t pkt_pos;
+ #endif
+ 
+-#if FF_API_PKT_DURATION
+-    /**
+-     * duration of the corresponding packet, expressed in
+-     * AVStream->time_base units, 0 if unknown.
+-     * - encoding: unused
+-     * - decoding: Read by user.
+-     *
+-     * @deprecated use duration instead
+-     */
+-    attribute_deprecated
+-    int64_t pkt_duration;
+-#endif
+-
+     /**
+      * metadata.
+      * - encoding: Set by user.
+      * - decoding: Set by libavcodec.
+      */
+     AVDictionary *metadata;
+ 
+     /**
+@@ -715,27 +700,16 @@ typedef struct AVFrame {
+      * - decoding: set by libavcodec, read by user.
+      */
+     int decode_error_flags;
+ #define FF_DECODE_ERROR_INVALID_BITSTREAM   1
+ #define FF_DECODE_ERROR_MISSING_REFERENCE   2
+ #define FF_DECODE_ERROR_CONCEALMENT_ACTIVE  4
+ #define FF_DECODE_ERROR_DECODE_SLICES       8
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-    /**
+-     * number of audio channels, only used for audio.
+-     * - encoding: unused
+-     * - decoding: Read by user.
+-     * @deprecated use ch_layout instead
+-     */
+-    attribute_deprecated
+-    int channels;
+-#endif
+-
+ #if FF_API_FRAME_PKT
+     /**
+      * size of the corresponding packet containing the compressed
+      * frame.
+      * It is set to a negative value if unknown.
+      * - encoding: unused
+      * - decoding: set by libavcodec, read by user.
+      * @deprecated use AV_CODEC_FLAG_COPY_OPAQUE to pass through arbitrary user
+@@ -1045,12 +1019,100 @@ enum {
+ int av_frame_apply_cropping(AVFrame *frame, int flags);
+ 
+ /**
+  * @return a string identifying the side data type
+  */
+ const char *av_frame_side_data_name(enum AVFrameSideDataType type);
+ 
+ /**
++ * @return side data descriptor corresponding to a given side data type, NULL
++ *         when not available.
++ */
++const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type);
++
++/**
++ * Free all side data entries and their contents, then zeroes out the
++ * values which the pointers are pointing to.
++ *
++ * @param sd    pointer to array of side data to free. Will be set to NULL
++ *              upon return.
++ * @param nb_sd pointer to an integer containing the number of entries in
++ *              the array. Will be set to 0 upon return.
++ */
++void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd);
++
++#define AV_FRAME_SIDE_DATA_FLAG_UNIQUE (1 << 0)
++
++/**
++ * Add new side data entry to an array.
++ *
++ * @param sd    pointer to array of side data to which to add another entry,
++ *              or to NULL in order to start a new array.
++ * @param nb_sd pointer to an integer containing the number of entries in
++ *              the array.
++ * @param type  type of the added side data
++ * @param size  size of the side data
++ * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
++ *
++ * @return newly added side data on success, NULL on error. In case of
++ *         AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
++ *         AVFrameSideDataType will be removed before the addition is
++ *         attempted.
++ */
++AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
++                                        enum AVFrameSideDataType type,
++                                        size_t size, unsigned int flags);
++
++/**
++ * Add a new side data entry to an array based on existing side data, taking
++ * a reference towards the contained AVBufferRef.
++ *
++ * @param sd    pointer to array of side data to which to add another entry,
++ *              or to NULL in order to start a new array.
++ * @param nb_sd pointer to an integer containing the number of entries in
++ *              the array.
++ * @param src   side data to be cloned, with a new reference utilized
++ *              for the buffer.
++ * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
++ *
++ * @return negative error code on failure, >=0 on success. In case of
++ *         AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
++ *         AVFrameSideDataType will be removed before the addition is
++ *         attempted.
++ */
++int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
++                             const AVFrameSideData *src, unsigned int flags);
++
++/**
++ * Get a side data entry of a specific type from an array.
++ *
++ * @param sd    array of side data.
++ * @param nb_sd integer containing the number of entries in the array.
++ * @param type  type of side data to be queried
++ *
++ * @return a pointer to the side data of a given type on success, NULL if there
++ *         is no side data with such type in this set.
++ */
++const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *sd,
++                                                const int nb_sd,
++                                                enum AVFrameSideDataType type);
++
++/**
++ * Wrapper around av_frame_side_data_get_c() to workaround the limitation
++ * that for any type T the conversion from T * const * to const T * const *
++ * is not performed automatically in C.
++ * @see av_frame_side_data_get_c()
++ */
++static inline
++const AVFrameSideData *av_frame_side_data_get(AVFrameSideData * const *sd,
++                                              const int nb_sd,
++                                              enum AVFrameSideDataType type)
++{
++    return av_frame_side_data_get_c((const AVFrameSideData * const *)sd,
++                                    nb_sd, type);
++}
++
++/**
+  * @}
+  */
+ 
+ #endif /* AVUTIL_FRAME_H */
+diff --git a/media/ffvpx/libavutil/hdr_dynamic_metadata.h b/media/ffvpx/libavutil/hdr_dynamic_metadata.h
+--- a/media/ffvpx/libavutil/hdr_dynamic_metadata.h
++++ b/media/ffvpx/libavutil/hdr_dynamic_metadata.h
+@@ -354,23 +354,23 @@ int av_dynamic_hdr_plus_from_t35(AVDynam
+                                  size_t size);
+ 
+ #define AV_HDR_PLUS_MAX_PAYLOAD_SIZE 907
+ 
+ /**
+  * Serialize dynamic HDR10+ metadata to a user data registered ITU-T T.35 buffer,
+  * excluding the first 48 bytes of the header, and beginning with the application mode.
+  * @param s A pointer containing the decoded AVDynamicHDRPlus structure.
+- * @param data[in,out] A pointer to pointer to a byte buffer to be filled with the
++ * @param[in,out] data A pointer to pointer to a byte buffer to be filled with the
+  *                     serialized metadata.
+  *                     If *data is NULL, a buffer be will be allocated and a pointer to
+  *                     it stored in its place. The caller assumes ownership of the buffer.
+  *                     May be NULL, in which case the function will only store the
+  *                     required buffer size in *size.
+- * @param size[in,out] A pointer to a size to be set to the returned buffer's size.
++ * @param[in,out] size A pointer to a size to be set to the returned buffer's size.
+  *                     If *data is not NULL, *size must contain the size of the input
+  *                     buffer. May be NULL only if *data is NULL.
+  *
+  * @return >= 0 on success. Otherwise, returns the appropriate AVERROR.
+  */
+ int av_dynamic_hdr_plus_to_t35(const AVDynamicHDRPlus *s, uint8_t **data, size_t *size);
+ 
+ #endif /* AVUTIL_HDR_DYNAMIC_METADATA_H */
+diff --git a/media/ffvpx/libavutil/hwcontext.c b/media/ffvpx/libavutil/hwcontext.c
+--- a/media/ffvpx/libavutil/hwcontext.c
++++ b/media/ffvpx/libavutil/hwcontext.c
+@@ -79,16 +79,31 @@ static const char *const hw_type_names[]
+     [AV_HWDEVICE_TYPE_QSV]    = "qsv",
+     [AV_HWDEVICE_TYPE_VAAPI]  = "vaapi",
+     [AV_HWDEVICE_TYPE_VDPAU]  = "vdpau",
+     [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox",
+     [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec",
+     [AV_HWDEVICE_TYPE_VULKAN] = "vulkan",
+ };
+ 
++typedef struct FFHWDeviceContext {
++    /**
++     * The public AVHWDeviceContext. See hwcontext.h for it.
++     */
++    AVHWDeviceContext p;
++
++    const HWContextType *hw_type;
++
++    /**
++     * For a derived device, a reference to the original device
++     * context it was derived from.
++     */
++    AVBufferRef *source_device;
++} FFHWDeviceContext;
++
+ enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
+ {
+     int type;
+     for (type = 0; type < FF_ARRAY_ELEMS(hw_type_names); type++) {
+         if (hw_type_names[type] && !strcmp(hw_type_names[type], name))
+             return type;
+     }
+     return AV_HWDEVICE_TYPE_NONE;
+@@ -121,159 +136,132 @@ enum AVHWDeviceType av_hwdevice_iterate_
+ static const AVClass hwdevice_ctx_class = {
+     .class_name = "AVHWDeviceContext",
+     .item_name  = av_default_item_name,
+     .version    = LIBAVUTIL_VERSION_INT,
+ };
+ 
+ static void hwdevice_ctx_free(void *opaque, uint8_t *data)
+ {
+-    AVHWDeviceContext *ctx = (AVHWDeviceContext*)data;
++    FFHWDeviceContext *ctxi = (FFHWDeviceContext*)data;
++    AVHWDeviceContext *ctx  = &ctxi->p;
+ 
+     /* uninit might still want access the hw context and the user
+      * free() callback might destroy it, so uninit has to be called first */
+-    if (ctx->internal->hw_type->device_uninit)
+-        ctx->internal->hw_type->device_uninit(ctx);
++    if (ctxi->hw_type->device_uninit)
++        ctxi->hw_type->device_uninit(ctx);
+ 
+     if (ctx->free)
+         ctx->free(ctx);
+ 
+-    av_buffer_unref(&ctx->internal->source_device);
++    av_buffer_unref(&ctxi->source_device);
+ 
+     av_freep(&ctx->hwctx);
+-    av_freep(&ctx->internal->priv);
+-    av_freep(&ctx->internal);
+     av_freep(&ctx);
+ }
+ 
+ AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
+ {
++    FFHWDeviceContext *ctxi;
+     AVHWDeviceContext *ctx;
+     AVBufferRef *buf;
+     const HWContextType *hw_type = NULL;
+     int i;
+ 
+     for (i = 0; hw_table[i]; i++) {
+         if (hw_table[i]->type == type) {
+             hw_type = hw_table[i];
+             break;
+         }
+     }
+     if (!hw_type)
+         return NULL;
+ 
+-    ctx = av_mallocz(sizeof(*ctx));
+-    if (!ctx)
++    ctxi = av_mallocz(sizeof(*ctxi));
++    if (!ctxi)
+         return NULL;
+-
+-    ctx->internal = av_mallocz(sizeof(*ctx->internal));
+-    if (!ctx->internal)
+-        goto fail;
+-
+-    if (hw_type->device_priv_size) {
+-        ctx->internal->priv = av_mallocz(hw_type->device_priv_size);
+-        if (!ctx->internal->priv)
+-            goto fail;
+-    }
++    ctx = &ctxi->p;
+ 
+     if (hw_type->device_hwctx_size) {
+         ctx->hwctx = av_mallocz(hw_type->device_hwctx_size);
+         if (!ctx->hwctx)
+             goto fail;
+     }
+ 
+     buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx),
+                            hwdevice_ctx_free, NULL,
+                            AV_BUFFER_FLAG_READONLY);
+     if (!buf)
+         goto fail;
+ 
+     ctx->type     = type;
+     ctx->av_class = &hwdevice_ctx_class;
+ 
+-    ctx->internal->hw_type = hw_type;
++    ctxi->hw_type = hw_type;
+ 
+     return buf;
+ 
+ fail:
+-    if (ctx->internal)
+-        av_freep(&ctx->internal->priv);
+-    av_freep(&ctx->internal);
+     av_freep(&ctx->hwctx);
+     av_freep(&ctx);
+     return NULL;
+ }
+ 
+ int av_hwdevice_ctx_init(AVBufferRef *ref)
+ {
+-    AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
+-    int ret;
++    FFHWDeviceContext *ctxi = (FFHWDeviceContext*)ref->data;
++    AVHWDeviceContext *ctx  = &ctxi->p;
++    int ret = 0;
+ 
+-    if (ctx->internal->hw_type->device_init) {
+-        ret = ctx->internal->hw_type->device_init(ctx);
+-        if (ret < 0)
+-            goto fail;
+-    }
++    if (ctxi->hw_type->device_init)
++        ret = ctxi->hw_type->device_init(ctx);
+ 
+-    return 0;
+-fail:
+-    if (ctx->internal->hw_type->device_uninit)
+-        ctx->internal->hw_type->device_uninit(ctx);
+     return ret;
+ }
+ 
+ static const AVClass hwframe_ctx_class = {
+     .class_name = "AVHWFramesContext",
+     .item_name  = av_default_item_name,
+     .version    = LIBAVUTIL_VERSION_INT,
+ };
+ 
+ static void hwframe_ctx_free(void *opaque, uint8_t *data)
+ {
+-    AVHWFramesContext *ctx = (AVHWFramesContext*)data;
++    FFHWFramesContext *ctxi = (FFHWFramesContext*)data;
++    AVHWFramesContext *ctx  = &ctxi->p;
+ 
+-    if (ctx->internal->pool_internal)
+-        av_buffer_pool_uninit(&ctx->internal->pool_internal);
++    if (ctxi->pool_internal)
++        av_buffer_pool_uninit(&ctxi->pool_internal);
+ 
+-    if (ctx->internal->hw_type->frames_uninit)
+-        ctx->internal->hw_type->frames_uninit(ctx);
++    if (ctxi->hw_type->frames_uninit)
++        ctxi->hw_type->frames_uninit(ctx);
+ 
+     if (ctx->free)
+         ctx->free(ctx);
+ 
+-    av_buffer_unref(&ctx->internal->source_frames);
++    av_buffer_unref(&ctxi->source_frames);
+ 
+     av_buffer_unref(&ctx->device_ref);
+ 
+     av_freep(&ctx->hwctx);
+-    av_freep(&ctx->internal->priv);
+-    av_freep(&ctx->internal);
+     av_freep(&ctx);
+ }
+ 
+ AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
+ {
+-    AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data;
+-    const HWContextType  *hw_type = device_ctx->internal->hw_type;
++    FFHWDeviceContext *device_ctx = (FFHWDeviceContext*)device_ref_in->data;
++    const HWContextType  *hw_type = device_ctx->hw_type;
++    FFHWFramesContext *ctxi;
+     AVHWFramesContext *ctx;
+     AVBufferRef *buf, *device_ref = NULL;
+ 
+-    ctx = av_mallocz(sizeof(*ctx));
+-    if (!ctx)
++    ctxi = av_mallocz(sizeof(*ctxi));
++    if (!ctxi)
+         return NULL;
+-
+-    ctx->internal = av_mallocz(sizeof(*ctx->internal));
+-    if (!ctx->internal)
+-        goto fail;
+-
+-    if (hw_type->frames_priv_size) {
+-        ctx->internal->priv = av_mallocz(hw_type->frames_priv_size);
+-        if (!ctx->internal->priv)
+-            goto fail;
+-    }
++    ctx  = &ctxi->p;
+ 
+     if (hw_type->frames_hwctx_size) {
+         ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size);
+         if (!ctx->hwctx)
+             goto fail;
+     }
+ 
+     device_ref = av_buffer_ref(device_ref_in);
+@@ -283,30 +271,26 @@ AVBufferRef *av_hwframe_ctx_alloc(AVBuff
+     buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx),
+                            hwframe_ctx_free, NULL,
+                            AV_BUFFER_FLAG_READONLY);
+     if (!buf)
+         goto fail;
+ 
+     ctx->av_class   = &hwframe_ctx_class;
+     ctx->device_ref = device_ref;
+-    ctx->device_ctx = device_ctx;
++    ctx->device_ctx = &device_ctx->p;
+     ctx->format     = AV_PIX_FMT_NONE;
+     ctx->sw_format  = AV_PIX_FMT_NONE;
+ 
+-    ctx->internal->hw_type = hw_type;
++    ctxi->hw_type = hw_type;
+ 
+     return buf;
+ 
+ fail:
+-    if (device_ref)
+-        av_buffer_unref(&device_ref);
+-    if (ctx->internal)
+-        av_freep(&ctx->internal->priv);
+-    av_freep(&ctx->internal);
++    av_buffer_unref(&device_ref);
+     av_freep(&ctx->hwctx);
+     av_freep(&ctx);
+     return NULL;
+ }
+ 
+ static int hwframe_pool_prealloc(AVBufferRef *ref)
+ {
+     AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data;
+@@ -332,76 +316,73 @@ fail:
+         av_frame_free(&frames[i]);
+     av_freep(&frames);
+ 
+     return ret;
+ }
+ 
+ int av_hwframe_ctx_init(AVBufferRef *ref)
+ {
+-    AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data;
++    FFHWFramesContext *ctxi = (FFHWFramesContext*)ref->data;
++    AVHWFramesContext *ctx  = &ctxi->p;
+     const enum AVPixelFormat *pix_fmt;
+     int ret;
+ 
+-    if (ctx->internal->source_frames) {
++    if (ctxi->source_frames) {
+         /* A derived frame context is already initialised. */
+         return 0;
+     }
+ 
+     /* validate the pixel format */
+-    for (pix_fmt = ctx->internal->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) {
++    for (pix_fmt = ctxi->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) {
+         if (*pix_fmt == ctx->format)
+             break;
+     }
+     if (*pix_fmt == AV_PIX_FMT_NONE) {
+         av_log(ctx, AV_LOG_ERROR,
+                "The hardware pixel format '%s' is not supported by the device type '%s'\n",
+-               av_get_pix_fmt_name(ctx->format), ctx->internal->hw_type->name);
++               av_get_pix_fmt_name(ctx->format), ctxi->hw_type->name);
+         return AVERROR(ENOSYS);
+     }
+ 
+     /* validate the dimensions */
+     ret = av_image_check_size(ctx->width, ctx->height, 0, ctx);
+     if (ret < 0)
+         return ret;
+ 
+     /* format-specific init */
+-    if (ctx->internal->hw_type->frames_init) {
+-        ret = ctx->internal->hw_type->frames_init(ctx);
++    if (ctxi->hw_type->frames_init) {
++        ret = ctxi->hw_type->frames_init(ctx);
+         if (ret < 0)
+-            goto fail;
++            return ret;
+     }
+ 
+-    if (ctx->internal->pool_internal && !ctx->pool)
+-        ctx->pool = ctx->internal->pool_internal;
++    if (ctxi->pool_internal && !ctx->pool)
++        ctx->pool = ctxi->pool_internal;
+ 
+     /* preallocate the frames in the pool, if requested */
+     if (ctx->initial_pool_size > 0) {
+         ret = hwframe_pool_prealloc(ref);
+         if (ret < 0)
+-            goto fail;
++            return ret;
+     }
+ 
+     return 0;
+-fail:
+-    if (ctx->internal->hw_type->frames_uninit)
+-        ctx->internal->hw_type->frames_uninit(ctx);
+-    return ret;
+ }
+ 
+ int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref,
+                                     enum AVHWFrameTransferDirection dir,
+                                     enum AVPixelFormat **formats, int flags)
+ {
+-    AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
++    FFHWFramesContext *ctxi = (FFHWFramesContext*)hwframe_ref->data;
+ 
+-    if (!ctx->internal->hw_type->transfer_get_formats)
++    if (!ctxi->hw_type->transfer_get_formats)
+         return AVERROR(ENOSYS);
+ 
+-    return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats);
++    return ctxi->hw_type->transfer_get_formats(&ctxi->p, dir, formats);
+ }
+ 
+ static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
+ {
+     AVHWFramesContext *ctx;
+     AVFrame *frame_tmp;
+     int ret = 0;
+ 
+@@ -446,165 +427,165 @@ static int transfer_data_alloc(AVFrame *
+ 
+ fail:
+     av_frame_free(&frame_tmp);
+     return ret;
+ }
+ 
+ int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
+ {
+-    AVHWFramesContext *ctx;
+     int ret;
+ 
+     if (!dst->buf[0])
+         return transfer_data_alloc(dst, src, flags);
+ 
+     /*
+      * Hardware -> Hardware Transfer.
+      * Unlike Software -> Hardware or Hardware -> Software, the transfer
+      * function could be provided by either the src or dst, depending on
+      * the specific combination of hardware.
+      */
+     if (src->hw_frames_ctx && dst->hw_frames_ctx) {
+-        AVHWFramesContext *src_ctx =
+-            (AVHWFramesContext*)src->hw_frames_ctx->data;
+-        AVHWFramesContext *dst_ctx =
+-            (AVHWFramesContext*)dst->hw_frames_ctx->data;
++        FFHWFramesContext *src_ctx =
++            (FFHWFramesContext*)src->hw_frames_ctx->data;
++        FFHWFramesContext *dst_ctx =
++            (FFHWFramesContext*)dst->hw_frames_ctx->data;
+ 
+-        if (src_ctx->internal->source_frames) {
++        if (src_ctx->source_frames) {
+             av_log(src_ctx, AV_LOG_ERROR,
+                    "A device with a derived frame context cannot be used as "
+                    "the source of a HW -> HW transfer.");
+             return AVERROR(ENOSYS);
+         }
+ 
+-        if (dst_ctx->internal->source_frames) {
++        if (dst_ctx->source_frames) {
+             av_log(src_ctx, AV_LOG_ERROR,
+                    "A device with a derived frame context cannot be used as "
+                    "the destination of a HW -> HW transfer.");
+             return AVERROR(ENOSYS);
+         }
+ 
+-        ret = src_ctx->internal->hw_type->transfer_data_from(src_ctx, dst, src);
++        ret = src_ctx->hw_type->transfer_data_from(&src_ctx->p, dst, src);
+         if (ret == AVERROR(ENOSYS))
+-            ret = dst_ctx->internal->hw_type->transfer_data_to(dst_ctx, dst, src);
++            ret = dst_ctx->hw_type->transfer_data_to(&dst_ctx->p, dst, src);
+         if (ret < 0)
+             return ret;
+     } else {
+         if (src->hw_frames_ctx) {
+-            ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
++            FFHWFramesContext *ctx = (FFHWFramesContext*)src->hw_frames_ctx->data;
+ 
+-            ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
++            ret = ctx->hw_type->transfer_data_from(&ctx->p, dst, src);
+             if (ret < 0)
+                 return ret;
+         } else if (dst->hw_frames_ctx) {
+-            ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
++            FFHWFramesContext *ctx = (FFHWFramesContext*)dst->hw_frames_ctx->data;
+ 
+-            ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
++            ret = ctx->hw_type->transfer_data_to(&ctx->p, dst, src);
+             if (ret < 0)
+                 return ret;
+         } else {
+             return AVERROR(ENOSYS);
+         }
+     }
+     return 0;
+ }
+ 
+ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
+ {
+-    AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
++    FFHWFramesContext *ctxi = (FFHWFramesContext*)hwframe_ref->data;
++    AVHWFramesContext *ctx  = &ctxi->p;
+     int ret;
+ 
+-    if (ctx->internal->source_frames) {
++    if (ctxi->source_frames) {
+         // This is a derived frame context, so we allocate in the source
+         // and map the frame immediately.
+         AVFrame *src_frame;
+ 
+         frame->format = ctx->format;
+         frame->hw_frames_ctx = av_buffer_ref(hwframe_ref);
+         if (!frame->hw_frames_ctx)
+             return AVERROR(ENOMEM);
+ 
+         src_frame = av_frame_alloc();
+         if (!src_frame)
+             return AVERROR(ENOMEM);
+ 
+-        ret = av_hwframe_get_buffer(ctx->internal->source_frames,
++        ret = av_hwframe_get_buffer(ctxi->source_frames,
+                                     src_frame, 0);
+         if (ret < 0) {
+             av_frame_free(&src_frame);
+             return ret;
+         }
+ 
+         ret = av_hwframe_map(frame, src_frame,
+-                             ctx->internal->source_allocation_map_flags);
++                             ctxi->source_allocation_map_flags);
+         if (ret) {
+             av_log(ctx, AV_LOG_ERROR, "Failed to map frame into derived "
+                    "frame context: %d.\n", ret);
+             av_frame_free(&src_frame);
+             return ret;
+         }
+ 
+         // Free the source frame immediately - the mapped frame still
+         // contains a reference to it.
+         av_frame_free(&src_frame);
+ 
+         return 0;
+     }
+ 
+-    if (!ctx->internal->hw_type->frames_get_buffer)
++    if (!ctxi->hw_type->frames_get_buffer)
+         return AVERROR(ENOSYS);
+ 
+     if (!ctx->pool)
+         return AVERROR(EINVAL);
+ 
+     frame->hw_frames_ctx = av_buffer_ref(hwframe_ref);
+     if (!frame->hw_frames_ctx)
+         return AVERROR(ENOMEM);
+ 
+-    ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame);
++    ret = ctxi->hw_type->frames_get_buffer(ctx, frame);
+     if (ret < 0) {
+         av_buffer_unref(&frame->hw_frames_ctx);
+         return ret;
+     }
+ 
+     frame->extended_data = frame->data;
+ 
+     return 0;
+ }
+ 
+ void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
+ {
+-    AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
+-    const HWContextType  *hw_type = ctx->internal->hw_type;
++    FFHWDeviceContext *ctx = (FFHWDeviceContext*)ref->data;
++    const HWContextType  *hw_type = ctx->hw_type;
+ 
+     if (hw_type->device_hwconfig_size == 0)
+         return NULL;
+ 
+     return av_mallocz(hw_type->device_hwconfig_size);
+ }
+ 
+ AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref,
+                                                            const void *hwconfig)
+ {
+-    AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
+-    const HWContextType  *hw_type = ctx->internal->hw_type;
++    FFHWDeviceContext *ctx = (FFHWDeviceContext*)ref->data;
++    const HWContextType  *hw_type = ctx->hw_type;
+     AVHWFramesConstraints *constraints;
+ 
+     if (!hw_type->frames_get_constraints)
+         return NULL;
+ 
+     constraints = av_mallocz(sizeof(*constraints));
+     if (!constraints)
+         return NULL;
+ 
+     constraints->min_width = constraints->min_height = 0;
+     constraints->max_width = constraints->max_height = INT_MAX;
+ 
+-    if (hw_type->frames_get_constraints(ctx, hwconfig, constraints) >= 0) {
++    if (hw_type->frames_get_constraints(&ctx->p, hwconfig, constraints) >= 0) {
+         return constraints;
+     } else {
+         av_hwframe_constraints_free(&constraints);
+         return NULL;
+     }
+ }
+ 
+ void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
+@@ -615,33 +596,33 @@ void av_hwframe_constraints_free(AVHWFra
+     }
+     av_freep(constraints);
+ }
+ 
+ int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type,
+                            const char *device, AVDictionary *opts, int flags)
+ {
+     AVBufferRef *device_ref = NULL;
+-    AVHWDeviceContext *device_ctx;
++    FFHWDeviceContext *device_ctx;
+     int ret = 0;
+ 
+     device_ref = av_hwdevice_ctx_alloc(type);
+     if (!device_ref) {
+         ret = AVERROR(ENOMEM);
+         goto fail;
+     }
+-    device_ctx = (AVHWDeviceContext*)device_ref->data;
++    device_ctx = (FFHWDeviceContext*)device_ref->data;
+ 
+-    if (!device_ctx->internal->hw_type->device_create) {
++    if (!device_ctx->hw_type->device_create) {
+         ret = AVERROR(ENOSYS);
+         goto fail;
+     }
+ 
+-    ret = device_ctx->internal->hw_type->device_create(device_ctx, device,
+-                                                       opts, flags);
++    ret = device_ctx->hw_type->device_create(&device_ctx->p, device,
++                                             opts, flags);
+     if (ret < 0)
+         goto fail;
+ 
+     ret = av_hwdevice_ctx_init(device_ref);
+     if (ret < 0)
+         goto fail;
+ 
+     *pdevice_ref = device_ref;
+@@ -653,63 +634,62 @@ fail:
+ }
+ 
+ int av_hwdevice_ctx_create_derived_opts(AVBufferRef **dst_ref_ptr,
+                                         enum AVHWDeviceType type,
+                                         AVBufferRef *src_ref,
+                                         AVDictionary *options, int flags)
+ {
+     AVBufferRef *dst_ref = NULL, *tmp_ref;
+-    AVHWDeviceContext *dst_ctx, *tmp_ctx;
++    FFHWDeviceContext *dst_ctx;
+     int ret = 0;
+ 
+     tmp_ref = src_ref;
+     while (tmp_ref) {
+-        tmp_ctx = (AVHWDeviceContext*)tmp_ref->data;
+-        if (tmp_ctx->type == type) {
++        FFHWDeviceContext *tmp_ctx = (FFHWDeviceContext*)tmp_ref->data;
++        if (tmp_ctx->p.type == type) {
+             dst_ref = av_buffer_ref(tmp_ref);
+             if (!dst_ref) {
+                 ret = AVERROR(ENOMEM);
+                 goto fail;
+             }
+             goto done;
+         }
+-        tmp_ref = tmp_ctx->internal->source_device;
++        tmp_ref = tmp_ctx->source_device;
+     }
+ 
+     dst_ref = av_hwdevice_ctx_alloc(type);
+     if (!dst_ref) {
+         ret = AVERROR(ENOMEM);
+         goto fail;
+     }
+-    dst_ctx = (AVHWDeviceContext*)dst_ref->data;
++    dst_ctx = (FFHWDeviceContext*)dst_ref->data;
+ 
+     tmp_ref = src_ref;
+     while (tmp_ref) {
+-        tmp_ctx = (AVHWDeviceContext*)tmp_ref->data;
+-        if (dst_ctx->internal->hw_type->device_derive) {
+-            ret = dst_ctx->internal->hw_type->device_derive(dst_ctx,
+-                                                            tmp_ctx,
+-                                                            options,
+-                                                            flags);
++        FFHWDeviceContext *tmp_ctx = (FFHWDeviceContext*)tmp_ref->data;
++        if (dst_ctx->hw_type->device_derive) {
++            ret = dst_ctx->hw_type->device_derive(&dst_ctx->p,
++                                                  &tmp_ctx->p,
++                                                  options, flags);
+             if (ret == 0) {
+-                dst_ctx->internal->source_device = av_buffer_ref(src_ref);
+-                if (!dst_ctx->internal->source_device) {
++                dst_ctx->source_device = av_buffer_ref(src_ref);
++                if (!dst_ctx->source_device) {
+                     ret = AVERROR(ENOMEM);
+                     goto fail;
+                 }
+                 ret = av_hwdevice_ctx_init(dst_ref);
+                 if (ret < 0)
+                     goto fail;
+                 goto done;
+             }
+             if (ret != AVERROR(ENOSYS))
+                 goto fail;
+         }
+-        tmp_ref = tmp_ctx->internal->source_device;
++        tmp_ref = tmp_ctx->source_device;
+     }
+ 
+     ret = AVERROR(ENOSYS);
+     goto fail;
+ 
+ done:
+     *dst_ref_ptr = dst_ref;
+     return 0;
+@@ -794,65 +774,64 @@ fail:
+     av_free(hwmap);
+     return ret;
+ }
+ 
+ int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
+ {
+     AVBufferRef    *orig_dst_frames = dst->hw_frames_ctx;
+     enum AVPixelFormat orig_dst_fmt = dst->format;
+-    AVHWFramesContext *src_frames, *dst_frames;
+     HWMapDescriptor *hwmap;
+     int ret;
+ 
+     if (src->hw_frames_ctx && dst->hw_frames_ctx) {
+-        src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data;
+-        dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data;
++        FFHWFramesContext *src_frames = (FFHWFramesContext*)src->hw_frames_ctx->data;
++        FFHWFramesContext *dst_frames = (FFHWFramesContext*)dst->hw_frames_ctx->data;
+ 
+         if ((src_frames == dst_frames &&
+-             src->format == dst_frames->sw_format &&
+-             dst->format == dst_frames->format) ||
+-            (src_frames->internal->source_frames &&
+-             src_frames->internal->source_frames->data ==
++             src->format == dst_frames->p.sw_format &&
++             dst->format == dst_frames->p.format) ||
++            (src_frames->source_frames &&
++             src_frames->source_frames->data ==
+              (uint8_t*)dst_frames)) {
+             // This is an unmap operation.  We don't need to directly
+             // do anything here other than fill in the original frame,
+             // because the real unmap will be invoked when the last
+             // reference to the mapped frame disappears.
+             if (!src->buf[0]) {
+                 av_log(src_frames, AV_LOG_ERROR, "Invalid mapping "
+                        "found when attempting unmap.\n");
+                 return AVERROR(EINVAL);
+             }
+             hwmap = (HWMapDescriptor*)src->buf[0]->data;
+             return av_frame_replace(dst, hwmap->source);
+         }
+     }
+ 
+     if (src->hw_frames_ctx) {
+-        src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data;
++        FFHWFramesContext *src_frames = (FFHWFramesContext*)src->hw_frames_ctx->data;
+ 
+-        if (src_frames->format == src->format &&
+-            src_frames->internal->hw_type->map_from) {
+-            ret = src_frames->internal->hw_type->map_from(src_frames,
+-                                                          dst, src, flags);
++        if (src_frames->p.format == src->format &&
++            src_frames->hw_type->map_from) {
++            ret = src_frames->hw_type->map_from(&src_frames->p,
++                                                dst, src, flags);
+             if (ret >= 0)
+                 return ret;
+             else if (ret != AVERROR(ENOSYS))
+                 goto fail;
+         }
+     }
+ 
+     if (dst->hw_frames_ctx) {
+-        dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data;
++        FFHWFramesContext *dst_frames = (FFHWFramesContext*)dst->hw_frames_ctx->data;
+ 
+-        if (dst_frames->format == dst->format &&
+-            dst_frames->internal->hw_type->map_to) {
+-            ret = dst_frames->internal->hw_type->map_to(dst_frames,
+-                                                        dst, src, flags);
++        if (dst_frames->p.format == dst->format &&
++            dst_frames->hw_type->map_to) {
++            ret = dst_frames->hw_type->map_to(&dst_frames->p,
++                                              dst, src, flags);
+             if (ret >= 0)
+                 return ret;
+             else if (ret != AVERROR(ENOSYS))
+                 goto fail;
+         }
+     }
+ 
+     return AVERROR(ENOSYS);
+@@ -876,81 +855,82 @@ fail:
+ 
+ int av_hwframe_ctx_create_derived(AVBufferRef **derived_frame_ctx,
+                                   enum AVPixelFormat format,
+                                   AVBufferRef *derived_device_ctx,
+                                   AVBufferRef *source_frame_ctx,
+                                   int flags)
+ {
+     AVBufferRef   *dst_ref = NULL;
+-    AVHWFramesContext *dst = NULL;
+-    AVHWFramesContext *src = (AVHWFramesContext*)source_frame_ctx->data;
++    FFHWFramesContext *dsti = NULL;
++    FFHWFramesContext *srci = (FFHWFramesContext*)source_frame_ctx->data;
++    AVHWFramesContext *dst, *src = &srci->p;
+     int ret;
+ 
+-    if (src->internal->source_frames) {
++    if (srci->source_frames) {
+         AVHWFramesContext *src_src =
+-            (AVHWFramesContext*)src->internal->source_frames->data;
++            (AVHWFramesContext*)srci->source_frames->data;
+         AVHWDeviceContext *dst_dev =
+             (AVHWDeviceContext*)derived_device_ctx->data;
+ 
+         if (src_src->device_ctx == dst_dev) {
+             // This is actually an unmapping, so we just return a
+             // reference to the source frame context.
+-            *derived_frame_ctx =
+-                av_buffer_ref(src->internal->source_frames);
++            *derived_frame_ctx = av_buffer_ref(srci->source_frames);
+             if (!*derived_frame_ctx) {
+                 ret = AVERROR(ENOMEM);
+                 goto fail;
+             }
+             return 0;
+         }
+     }
+ 
+     dst_ref = av_hwframe_ctx_alloc(derived_device_ctx);
+     if (!dst_ref) {
+         ret = AVERROR(ENOMEM);
+         goto fail;
+     }
+ 
+-    dst = (AVHWFramesContext*)dst_ref->data;
++    dsti = (FFHWFramesContext*)dst_ref->data;
++    dst  = &dsti->p;
+ 
+     dst->format    = format;
+     dst->sw_format = src->sw_format;
+     dst->width     = src->width;
+     dst->height    = src->height;
+ 
+-    dst->internal->source_frames = av_buffer_ref(source_frame_ctx);
+-    if (!dst->internal->source_frames) {
++    dsti->source_frames = av_buffer_ref(source_frame_ctx);
++    if (!dsti->source_frames) {
+         ret = AVERROR(ENOMEM);
+         goto fail;
+     }
+ 
+-    dst->internal->source_allocation_map_flags =
++    dsti->source_allocation_map_flags =
+         flags & (AV_HWFRAME_MAP_READ      |
+                  AV_HWFRAME_MAP_WRITE     |
+                  AV_HWFRAME_MAP_OVERWRITE |
+                  AV_HWFRAME_MAP_DIRECT);
+ 
+     ret = AVERROR(ENOSYS);
+-    if (src->internal->hw_type->frames_derive_from)
+-        ret = src->internal->hw_type->frames_derive_from(dst, src, flags);
++    if (srci->hw_type->frames_derive_from)
++        ret = srci->hw_type->frames_derive_from(dst, src, flags);
+     if (ret == AVERROR(ENOSYS) &&
+-        dst->internal->hw_type->frames_derive_to)
+-        ret = dst->internal->hw_type->frames_derive_to(dst, src, flags);
++        dsti->hw_type->frames_derive_to)
++        ret = dsti->hw_type->frames_derive_to(dst, src, flags);
+     if (ret == AVERROR(ENOSYS))
+         ret = 0;
+     if (ret)
+         goto fail;
+ 
+     *derived_frame_ctx = dst_ref;
+     return 0;
+ 
+ fail:
+-    if (dst)
+-        av_buffer_unref(&dst->internal->source_frames);
++    if (dsti)
++        av_buffer_unref(&dsti->source_frames);
+     av_buffer_unref(&dst_ref);
+     return ret;
+ }
+ 
+ int ff_hwframe_map_replace(AVFrame *dst, const AVFrame *src)
+ {
+     HWMapDescriptor *hwmap = (HWMapDescriptor*)dst->buf[0]->data;
+     return av_frame_replace(hwmap->source, src);
+diff --git a/media/ffvpx/libavutil/hwcontext.h b/media/ffvpx/libavutil/hwcontext.h
+--- a/media/ffvpx/libavutil/hwcontext.h
++++ b/media/ffvpx/libavutil/hwcontext.h
+@@ -35,18 +35,16 @@ enum AVHWDeviceType {
+     AV_HWDEVICE_TYPE_D3D11VA,
+     AV_HWDEVICE_TYPE_DRM,
+     AV_HWDEVICE_TYPE_OPENCL,
+     AV_HWDEVICE_TYPE_MEDIACODEC,
+     AV_HWDEVICE_TYPE_VULKAN,
+     AV_HWDEVICE_TYPE_D3D12VA,
+ };
+ 
+-typedef struct AVHWDeviceInternal AVHWDeviceInternal;
+-
+ /**
+  * This struct aggregates all the (hardware/vendor-specific) "high-level" state,
+  * i.e. state that is not tied to a concrete processing configuration.
+  * E.g., in an API that supports hardware-accelerated encoding and decoding,
+  * this struct will (if possible) wrap the state that is common to both encoding
+  * and decoding and from which specific instances of encoders or decoders can be
+  * derived.
+  *
+@@ -61,22 +59,16 @@ typedef struct AVHWDeviceInternal AVHWDe
+  */
+ typedef struct AVHWDeviceContext {
+     /**
+      * A class for logging. Set by av_hwdevice_ctx_alloc().
+      */
+     const AVClass *av_class;
+ 
+     /**
+-     * Private data used internally by libavutil. Must not be accessed in any
+-     * way by the caller.
+-     */
+-    AVHWDeviceInternal *internal;
+-
+-    /**
+      * This field identifies the underlying API used for hardware access.
+      *
+      * This field is set when this struct is allocated and never changed
+      * afterwards.
+      */
+     enum AVHWDeviceType type;
+ 
+     /**
+@@ -105,18 +97,16 @@ typedef struct AVHWDeviceContext {
+     void (*free)(struct AVHWDeviceContext *ctx);
+ 
+     /**
+      * Arbitrary user data, to be used e.g. by the free() callback.
+      */
+     void *user_opaque;
+ } AVHWDeviceContext;
+ 
+-typedef struct AVHWFramesInternal AVHWFramesInternal;
+-
+ /**
+  * This struct describes a set or pool of "hardware" frames (i.e. those with
+  * data not located in normal system memory). All the frames in the pool are
+  * assumed to be allocated in the same way and interchangeable.
+  *
+  * This struct is reference-counted with the AVBuffer mechanism and tied to a
+  * given AVHWDeviceContext instance. The av_hwframe_ctx_alloc() constructor
+  * yields a reference, whose data field points to the actual AVHWFramesContext
+@@ -124,22 +114,16 @@ typedef struct AVHWFramesInternal AVHWFr
+  */
+ typedef struct AVHWFramesContext {
+     /**
+      * A class for logging.
+      */
+     const AVClass *av_class;
+ 
+     /**
+-     * Private data used internally by libavutil. Must not be accessed in any
+-     * way by the caller.
+-     */
+-    AVHWFramesInternal *internal;
+-
+-    /**
+      * A reference to the parent AVHWDeviceContext. This reference is owned and
+      * managed by the enclosing AVHWFramesContext, but the caller may derive
+      * additional references from it.
+      */
+     AVBufferRef *device_ref;
+ 
+     /**
+      * The parent AVHWDeviceContext. This is simply a pointer to
+@@ -148,19 +132,22 @@ typedef struct AVHWFramesContext {
+      * Set by libavutil in av_hwframe_ctx_init().
+      */
+     AVHWDeviceContext *device_ctx;
+ 
+     /**
+      * The format-specific data, allocated and freed automatically along with
+      * this context.
+      *
+-     * Should be cast by the user to the format-specific context defined in the
+-     * corresponding header (hwframe_*.h) and filled as described in the
+-     * documentation before calling av_hwframe_ctx_init().
++     * The user shall ignore this field if the corresponding format-specific
++     * header (hwcontext_*.h) does not define a context to be used as
++     * AVHWFramesContext.hwctx.
++     *
++     * Otherwise, it should be cast by the user to said context and filled
++     * as described in the documentation before calling av_hwframe_ctx_init().
+      *
+      * After any frames using this context are created, the contents of this
+      * struct should not be modified by the caller.
+      */
+     void *hwctx;
+ 
+     /**
+      * This field may be set by the caller before calling av_hwframe_ctx_init().
+diff --git a/media/ffvpx/libavutil/hwcontext_internal.h b/media/ffvpx/libavutil/hwcontext_internal.h
+--- a/media/ffvpx/libavutil/hwcontext_internal.h
++++ b/media/ffvpx/libavutil/hwcontext_internal.h
+@@ -36,38 +36,28 @@ typedef struct HWContextType {
+      */
+     const enum AVPixelFormat *pix_fmts;
+ 
+     /**
+      * size of the public hardware-specific context,
+      * i.e. AVHWDeviceContext.hwctx
+      */
+     size_t             device_hwctx_size;
+-    /**
+-     * size of the private data, i.e.
+-     * AVHWDeviceInternal.priv
+-     */
+-    size_t             device_priv_size;
+ 
+     /**
+      * Size of the hardware-specific device configuration.
+      * (Used to query hwframe constraints.)
+      */
+     size_t             device_hwconfig_size;
+ 
+     /**
+      * size of the public frame pool hardware-specific context,
+      * i.e. AVHWFramesContext.hwctx
+      */
+     size_t             frames_hwctx_size;
+-    /**
+-     * size of the private data, i.e.
+-     * AVHWFramesInternal.priv
+-     */
+-    size_t             frames_priv_size;
+ 
+     int              (*device_create)(AVHWDeviceContext *ctx, const char *device,
+                                       AVDictionary *opts, int flags);
+     int              (*device_derive)(AVHWDeviceContext *dst_ctx,
+                                       AVHWDeviceContext *src_ctx,
+                                       AVDictionary *opts, int flags);
+ 
+     int              (*device_init)(AVHWDeviceContext *ctx);
+@@ -95,44 +85,42 @@ typedef struct HWContextType {
+                                  const AVFrame *src, int flags);
+ 
+     int              (*frames_derive_to)(AVHWFramesContext *dst_ctx,
+                                          AVHWFramesContext *src_ctx, int flags);
+     int              (*frames_derive_from)(AVHWFramesContext *dst_ctx,
+                                            AVHWFramesContext *src_ctx, int flags);
+ } HWContextType;
+ 
+-struct AVHWDeviceInternal {
+-    const HWContextType *hw_type;
+-    void                *priv;
+-
++typedef struct FFHWFramesContext {
+     /**
+-     * For a derived device, a reference to the original device
+-     * context it was derived from.
++     * The public AVHWFramesContext. See hwcontext.h for it.
+      */
+-    AVBufferRef *source_device;
+-};
++    AVHWFramesContext p;
+ 
+-struct AVHWFramesInternal {
+     const HWContextType *hw_type;
+-    void                *priv;
+ 
+     AVBufferPool *pool_internal;
+ 
+     /**
+      * For a derived context, a reference to the original frames
+      * context it was derived from.
+      */
+     AVBufferRef *source_frames;
+     /**
+      * Flags to apply to the mapping from the source to the derived
+      * frame context when trying to allocate in the derived context.
+      */
+     int source_allocation_map_flags;
+-};
++} FFHWFramesContext;
++
++static inline FFHWFramesContext *ffhwframesctx(AVHWFramesContext *ctx)
++{
++    return (FFHWFramesContext*)ctx;
++}
+ 
+ typedef struct HWMapDescriptor {
+     /**
+      * A reference to the original source of the mapping.
+      */
+     AVFrame *source;
+     /**
+      * A reference to the hardware frames context in which this
+diff --git a/media/ffvpx/libavutil/hwcontext_vaapi.c b/media/ffvpx/libavutil/hwcontext_vaapi.c
+--- a/media/ffvpx/libavutil/hwcontext_vaapi.c
++++ b/media/ffvpx/libavutil/hwcontext_vaapi.c
+@@ -70,22 +70,32 @@ typedef struct VAAPIDevicePriv {
+ } VAAPIDevicePriv;
+ 
+ typedef struct VAAPISurfaceFormat {
+     enum AVPixelFormat pix_fmt;
+     VAImageFormat image_format;
+ } VAAPISurfaceFormat;
+ 
+ typedef struct VAAPIDeviceContext {
++    /**
++     * The public AVVAAPIDeviceContext. See hwcontext_vaapi.h for it.
++     */
++    AVVAAPIDeviceContext p;
++
+     // Surface formats which can be used with this device.
+     VAAPISurfaceFormat *formats;
+     int              nb_formats;
+ } VAAPIDeviceContext;
+ 
+ typedef struct VAAPIFramesContext {
++    /**
++     * The public AVVAAPIFramesContext. See hwcontext_vaapi.h for it.
++     */
++    AVVAAPIFramesContext p;
++
+     // Surface attributes set at create time.
+     VASurfaceAttrib *attributes;
+     int           nb_attributes;
+     // RT format of the underlying surface (Intel driver ignores this anyway).
+     unsigned int rt_format;
+     // Whether vaDeriveImage works.
+     int derive_works;
+     // Caches whether VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 is unsupported for
+@@ -202,36 +212,36 @@ static enum AVPixelFormat vaapi_pix_fmt_
+     else
+         return AV_PIX_FMT_NONE;
+ }
+ 
+ static int vaapi_get_image_format(AVHWDeviceContext *hwdev,
+                                   enum AVPixelFormat pix_fmt,
+                                   VAImageFormat **image_format)
+ {
+-    VAAPIDeviceContext *ctx = hwdev->internal->priv;
++    VAAPIDeviceContext *ctx = hwdev->hwctx;
+     int i;
+ 
+     for (i = 0; i < ctx->nb_formats; i++) {
+         if (ctx->formats[i].pix_fmt == pix_fmt) {
+             if (image_format)
+                 *image_format = &ctx->formats[i].image_format;
+             return 0;
+         }
+     }
+     return AVERROR(ENOSYS);
+ }
+ 
+ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
+                                         const void *hwconfig,
+                                         AVHWFramesConstraints *constraints)
+ {
+-    AVVAAPIDeviceContext *hwctx = hwdev->hwctx;
++    VAAPIDeviceContext *ctx = hwdev->hwctx;
++    AVVAAPIDeviceContext *hwctx = &ctx->p;
+     const AVVAAPIHWConfig *config = hwconfig;
+-    VAAPIDeviceContext *ctx = hwdev->internal->priv;
+     VASurfaceAttrib *attr_list = NULL;
+     VAStatus vas;
+     enum AVPixelFormat pix_fmt;
+     unsigned int fourcc;
+     int err, i, j, attr_count, pix_fmt_count;
+ 
+     if (config &&
+         !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) {
+@@ -379,18 +389,18 @@ static const struct {
+         "VDPAU wrapper",
+         "Splitted-Desktop Systems VDPAU backend for VA-API",
+         AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES,
+     },
+ };
+ 
+ static int vaapi_device_init(AVHWDeviceContext *hwdev)
+ {
+-    VAAPIDeviceContext *ctx = hwdev->internal->priv;
+-    AVVAAPIDeviceContext *hwctx = hwdev->hwctx;
++    VAAPIDeviceContext *ctx = hwdev->hwctx;
++    AVVAAPIDeviceContext *hwctx = &ctx->p;
+     VAImageFormat *image_list = NULL;
+     VAStatus vas;
+     const char *vendor_string;
+     int err, i, image_count;
+     enum AVPixelFormat pix_fmt;
+     unsigned int fourcc;
+ 
+     image_count = vaMaxNumImageFormats(hwctx->display);
+@@ -469,17 +479,17 @@ static int vaapi_device_init(AVHWDeviceC
+ fail:
+     av_freep(&ctx->formats);
+     av_free(image_list);
+     return err;
+ }
+ 
+ static void vaapi_device_uninit(AVHWDeviceContext *hwdev)
+ {
+-    VAAPIDeviceContext *ctx = hwdev->internal->priv;
++    VAAPIDeviceContext *ctx = hwdev->hwctx;
+ 
+     av_freep(&ctx->formats);
+ }
+ 
+ static void vaapi_buffer_free(void *opaque, uint8_t *data)
+ {
+     AVHWFramesContext     *hwfc = opaque;
+     AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+@@ -493,19 +503,19 @@ static void vaapi_buffer_free(void *opaq
+         av_log(hwfc, AV_LOG_ERROR, "Failed to destroy surface %#x: "
+                "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
+     }
+ }
+ 
+ static AVBufferRef *vaapi_pool_alloc(void *opaque, size_t size)
+ {
+     AVHWFramesContext     *hwfc = opaque;
+-    VAAPIFramesContext     *ctx = hwfc->internal->priv;
++    VAAPIFramesContext     *ctx = hwfc->hwctx;
++    AVVAAPIFramesContext  *avfc = &ctx->p;
+     AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+-    AVVAAPIFramesContext  *avfc = hwfc->hwctx;
+     VASurfaceID surface_id;
+     VAStatus vas;
+     AVBufferRef *ref;
+ 
+     if (hwfc->initial_pool_size > 0 &&
+         avfc->nb_surfaces >= hwfc->initial_pool_size)
+         return NULL;
+ 
+@@ -536,18 +546,18 @@ static AVBufferRef *vaapi_pool_alloc(voi
+         ++avfc->nb_surfaces;
+     }
+ 
+     return ref;
+ }
+ 
+ static int vaapi_frames_init(AVHWFramesContext *hwfc)
+ {
+-    AVVAAPIFramesContext  *avfc = hwfc->hwctx;
+-    VAAPIFramesContext     *ctx = hwfc->internal->priv;
++    VAAPIFramesContext     *ctx = hwfc->hwctx;
++    AVVAAPIFramesContext  *avfc = &ctx->p;
+     AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+     const VAAPIFormatDescriptor *desc;
+     VAImageFormat *expected_format;
+     AVBufferRef *test_surface = NULL;
+     VASurfaceID test_surface_id;
+     VAImage test_image;
+     VAStatus vas;
+     int err, i;
+@@ -618,20 +628,20 @@ static int vaapi_frames_init(AVHWFramesC
+             }
+         } else {
+             // This pool allows dynamic sizing, and will not be usable as a
+             // render target.
+             avfc->nb_surfaces = 0;
+             avfc->surface_ids = NULL;
+         }
+ 
+-        hwfc->internal->pool_internal =
++        ffhwframesctx(hwfc)->pool_internal =
+             av_buffer_pool_init2(sizeof(VASurfaceID), hwfc,
+                                  &vaapi_pool_alloc, NULL);
+-        if (!hwfc->internal->pool_internal) {
++        if (!ffhwframesctx(hwfc)->pool_internal) {
+             av_log(hwfc, AV_LOG_ERROR, "Failed to create VAAPI surface pool.\n");
+             err = AVERROR(ENOMEM);
+             goto fail;
+         }
+     }
+ 
+     // Allocate a single surface to test whether vaDeriveImage() is going
+     // to work for the specific configuration.
+@@ -639,17 +649,17 @@ static int vaapi_frames_init(AVHWFramesC
+         test_surface = av_buffer_pool_get(hwfc->pool);
+         if (!test_surface) {
+             av_log(hwfc, AV_LOG_ERROR, "Unable to allocate a surface from "
+                    "user-configured buffer pool.\n");
+             err = AVERROR(ENOMEM);
+             goto fail;
+         }
+     } else {
+-        test_surface = av_buffer_pool_get(hwfc->internal->pool_internal);
++        test_surface = av_buffer_pool_get(ffhwframesctx(hwfc)->pool_internal);
+         if (!test_surface) {
+             av_log(hwfc, AV_LOG_ERROR, "Unable to allocate a surface from "
+                    "internal buffer pool.\n");
+             err = AVERROR(ENOMEM);
+             goto fail;
+         }
+     }
+     test_surface_id = (VASurfaceID)(uintptr_t)test_surface->data;
+@@ -688,18 +698,18 @@ fail:
+     av_buffer_unref(&test_surface);
+     av_freep(&avfc->surface_ids);
+     av_freep(&ctx->attributes);
+     return err;
+ }
+ 
+ static void vaapi_frames_uninit(AVHWFramesContext *hwfc)
+ {
+-    AVVAAPIFramesContext *avfc = hwfc->hwctx;
+-    VAAPIFramesContext    *ctx = hwfc->internal->priv;
++    VAAPIFramesContext    *ctx = hwfc->hwctx;
++    AVVAAPIFramesContext *avfc = &ctx->p;
+ 
+     av_freep(&avfc->surface_ids);
+     av_freep(&ctx->attributes);
+ }
+ 
+ static int vaapi_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame)
+ {
+     frame->buf[0] = av_buffer_pool_get(hwfc->pool);
+@@ -713,17 +723,17 @@ static int vaapi_get_buffer(AVHWFramesCo
+ 
+     return 0;
+ }
+ 
+ static int vaapi_transfer_get_formats(AVHWFramesContext *hwfc,
+                                       enum AVHWFrameTransferDirection dir,
+                                       enum AVPixelFormat **formats)
+ {
+-    VAAPIDeviceContext *ctx = hwfc->device_ctx->internal->priv;
++    VAAPIDeviceContext *ctx = hwfc->device_ctx->hwctx;
+     enum AVPixelFormat *pix_fmts;
+     int i, k, sw_format_available;
+ 
+     sw_format_available = 0;
+     for (i = 0; i < ctx->nb_formats; i++) {
+         if (ctx->formats[i].pix_fmt == hwfc->sw_format)
+             sw_format_available = 1;
+     }
+@@ -786,17 +796,17 @@ static void vaapi_unmap_frame(AVHWFrames
+ 
+     av_free(map);
+ }
+ 
+ static int vaapi_map_frame(AVHWFramesContext *hwfc,
+                            AVFrame *dst, const AVFrame *src, int flags)
+ {
+     AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+-    VAAPIFramesContext *ctx = hwfc->internal->priv;
++    VAAPIFramesContext *ctx = hwfc->hwctx;
+     VASurfaceID surface_id;
+     const VAAPIFormatDescriptor *desc;
+     VAImageFormat *image_format;
+     VAAPIMapping *map;
+     VAStatus vas;
+     void *address = NULL;
+     int err, i;
+ 
+@@ -1065,17 +1075,17 @@ static void vaapi_unmap_from_drm(AVHWFra
+ 
+     vaDestroySurfaces(dst_dev->display, &surface_id, 1);
+ }
+ 
+ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
+                               const AVFrame *src, int flags)
+ {
+ #if VA_CHECK_VERSION(1, 1, 0)
+-    VAAPIFramesContext     *src_vafc = src_fc->internal->priv;
++    VAAPIFramesContext    *src_vafc = src_fc->hwctx;
+     int use_prime2;
+ #else
+     int k;
+ #endif
+     AVHWFramesContext      *dst_fc =
+         (AVHWFramesContext*)dst->hw_frames_ctx->data;
+     AVVAAPIDeviceContext  *dst_dev = dst_fc->device_ctx->hwctx;
+     const AVDRMFrameDescriptor *desc;
+@@ -2002,21 +2012,19 @@ static int vaapi_device_derive(AVHWDevic
+ #endif
+     return AVERROR(ENOSYS);
+ }
+ 
+ const HWContextType ff_hwcontext_type_vaapi = {
+     .type                   = AV_HWDEVICE_TYPE_VAAPI,
+     .name                   = "VAAPI",
+ 
+-    .device_hwctx_size      = sizeof(AVVAAPIDeviceContext),
+-    .device_priv_size       = sizeof(VAAPIDeviceContext),
++    .device_hwctx_size      = sizeof(VAAPIDeviceContext),
+     .device_hwconfig_size   = sizeof(AVVAAPIHWConfig),
+-    .frames_hwctx_size      = sizeof(AVVAAPIFramesContext),
+-    .frames_priv_size       = sizeof(VAAPIFramesContext),
++    .frames_hwctx_size      = sizeof(VAAPIFramesContext),
+ 
+     .device_create          = &vaapi_device_create,
+     .device_derive          = &vaapi_device_derive,
+     .device_init            = &vaapi_device_init,
+     .device_uninit          = &vaapi_device_uninit,
+     .frames_get_constraints = &vaapi_frames_get_constraints,
+     .frames_init            = &vaapi_frames_init,
+     .frames_uninit          = &vaapi_frames_uninit,
+diff --git a/media/ffvpx/libavutil/imgutils.c b/media/ffvpx/libavutil/imgutils.c
+--- a/media/ffvpx/libavutil/imgutils.c
++++ b/media/ffvpx/libavutil/imgutils.c
+@@ -20,20 +20,20 @@
+  * @file
+  * misc image utilities
+  */
+ 
+ #include "avassert.h"
+ #include "common.h"
+ #include "imgutils.h"
+ #include "imgutils_internal.h"
+-#include "internal.h"
+ #include "intreadwrite.h"
+ #include "log.h"
+ #include "mathematics.h"
++#include "mem.h"
+ #include "pixdesc.h"
+ #include "rational.h"
+ 
+ void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4],
+                                 const AVPixFmtDescriptor *pixdesc)
+ {
+     int i;
+     memset(max_pixsteps, 0, 4*sizeof(max_pixsteps[0]));
+diff --git a/media/ffvpx/libavutil/imgutils_internal.h b/media/ffvpx/libavutil/imgutils_internal.h
+--- a/media/ffvpx/libavutil/imgutils_internal.h
++++ b/media/ffvpx/libavutil/imgutils_internal.h
+@@ -17,14 +17,18 @@
+  */
+ 
+ #ifndef AVUTIL_IMGUTILS_INTERNAL_H
+ #define AVUTIL_IMGUTILS_INTERNAL_H
+ 
+ #include <stddef.h>
+ #include <stdint.h>
+ 
++#include "pixfmt.h"
++
++int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
++
+ int ff_image_copy_plane_uc_from_x86(uint8_t       *dst, ptrdiff_t dst_linesize,
+                                     const uint8_t *src, ptrdiff_t src_linesize,
+                                     ptrdiff_t bytewidth, int height);
+ 
+ 
+ #endif /* AVUTIL_IMGUTILS_INTERNAL_H */
+diff --git a/media/ffvpx/libavutil/internal.h b/media/ffvpx/libavutil/internal.h
+--- a/media/ffvpx/libavutil/internal.h
++++ b/media/ffvpx/libavutil/internal.h
+@@ -35,18 +35,18 @@
+ 
+ #include <limits.h>
+ #include <stdint.h>
+ #include <stddef.h>
+ #include <assert.h>
+ #include <stdio.h>
+ #include "config.h"
+ #include "attributes.h"
++#include "libm.h"
+ #include "macros.h"
+-#include "pixfmt.h"
+ 
+ #ifndef attribute_align_arg
+ #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
+ #    define attribute_align_arg __attribute__((force_align_arg_pointer))
+ #else
+ #    define attribute_align_arg
+ #endif
+ #endif
+@@ -69,38 +69,26 @@
+ #        define FF_ENABLE_DEPRECATION_WARNINGS  _Pragma("GCC diagnostic pop")
+ #    endif
+ #else
+ #    define FF_DISABLE_DEPRECATION_WARNINGS
+ #    define FF_ENABLE_DEPRECATION_WARNINGS
+ #endif
+ 
+ 
+-#define FF_MEMORY_POISON 0x2a
+-
+-/* Check if the hard coded offset of a struct member still matches reality.
+- * Induce a compilation failure if not.
+- */
+-#define AV_CHECK_OFFSET(s, m, o) struct check_##o {    \
+-        int x_##o[offsetof(s, m) == o? 1: -1];         \
+-    }
+-
+-
+ #define FF_ALLOC_TYPED_ARRAY(p, nelem)  (p = av_malloc_array(nelem, sizeof(*p)))
+ #define FF_ALLOCZ_TYPED_ARRAY(p, nelem) (p = av_calloc(nelem, sizeof(*p)))
+ 
+ #define FF_PTR_ADD(ptr, off) ((off) ? (ptr) + (off) : (ptr))
+ 
+ /**
+  * Access a field in a structure by its offset.
+  */
+ #define FF_FIELD_AT(type, off, obj) (*(type *)((char *)&(obj) + (off)))
+ 
+-#include "libm.h"
+-
+ /**
+  * Return NULL if CONFIG_SMALL is true, otherwise the argument
+  * without modification. Used to disable the definition of strings.
+  */
+ #if CONFIG_SMALL
+ #   define NULL_IF_CONFIG_SMALL(x) NULL
+ #else
+ #   define NULL_IF_CONFIG_SMALL(x) x
+@@ -158,18 +146,16 @@ void avpriv_request_sample(void *avc,
+ #ifdef CHECKED
+ #define SUINT   int
+ #define SUINT32 int32_t
+ #else
+ #define SUINT   unsigned
+ #define SUINT32 uint32_t
+ #endif
+ 
+-int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
+-
+ static av_always_inline av_const int avpriv_mirror(int x, int w)
+ {
+     if (!w)
+         return 0;
+ 
+     while ((unsigned)x > (unsigned)w) {
+         x = -x;
+         if (x < 0)
+diff --git a/media/ffvpx/libavutil/intreadwrite.h b/media/ffvpx/libavutil/intreadwrite.h
+--- a/media/ffvpx/libavutil/intreadwrite.h
++++ b/media/ffvpx/libavutil/intreadwrite.h
+@@ -578,19 +578,17 @@ union unaligned_16 { uint16_t l; } __att
+ #   define AV_COPY128U(d, s)                                    \
+     do {                                                        \
+         AV_COPY64U(d, s);                                       \
+         AV_COPY64U((char *)(d) + 8, (const char *)(s) + 8);     \
+     } while(0)
+ #endif
+ 
+ /* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be
+- * naturally aligned. They may be implemented using MMX,
+- * so emms_c() must be called before using any float code
+- * afterwards.
++ * naturally aligned.
+  */
+ 
+ #define AV_COPY(n, d, s) \
+     (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n)
+ 
+ #ifndef AV_COPY16
+ #   define AV_COPY16(d, s) AV_COPY(16, d, s)
+ #endif
+diff --git a/media/ffvpx/libavutil/mem.c b/media/ffvpx/libavutil/mem.c
+--- a/media/ffvpx/libavutil/mem.c
++++ b/media/ffvpx/libavutil/mem.c
+@@ -57,24 +57,26 @@
+ void *malloc(size_t size);
+ void *memalign(size_t align, size_t size);
+ int   posix_memalign(void **ptr, size_t align, size_t size);
+ void *realloc(void *ptr, size_t size);
+ void  free(void *ptr);
+ 
+ #endif /* MALLOC_PREFIX */
+ 
+-#define ALIGN (HAVE_AVX512 ? 64 : (HAVE_AVX ? 32 : 16))
++#define ALIGN (HAVE_SIMD_ALIGN_64 ? 64 : (HAVE_SIMD_ALIGN_32 ? 32 : 16))
++
++#define FF_MEMORY_POISON 0x2a
+ 
+ /* NOTE: if you want to override these functions with your own
+  * implementations (not recommended) you have to link libav* as
+  * dynamic libraries and remove -Wl,-Bsymbolic from the linker flags.
+  * Note that this will cost performance. */
+ 
+-static atomic_size_t max_alloc_size = ATOMIC_VAR_INIT(INT_MAX);
++static atomic_size_t max_alloc_size = INT_MAX;
+ 
+ void av_max_alloc(size_t max){
+     atomic_store_explicit(&max_alloc_size, max, memory_order_relaxed);
+ }
+ 
+ static int size_mult(size_t a, size_t b, size_t *r)
+ {
+     size_t t;
+diff --git a/media/ffvpx/libavutil/mem.h b/media/ffvpx/libavutil/mem.h
+--- a/media/ffvpx/libavutil/mem.h
++++ b/media/ffvpx/libavutil/mem.h
+@@ -111,17 +111,17 @@
+  * Allocate a memory block with alignment suitable for all memory accesses
+  * (including vectors if available on the CPU).
+  *
+  * @param size Size in bytes for the memory block to be allocated
+  * @return Pointer to the allocated block, or `NULL` if the block cannot
+  *         be allocated
+  * @see av_mallocz()
+  */
+-void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1) __attribute__((visibility("default")));
++void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1);
+ 
+ /**
+  * Allocate a memory block with alignment suitable for all memory accesses
+  * (including vectors if available on the CPU) and zero all the bytes of the
+  * block.
+  *
+  * @param size Size in bytes for the memory block to be allocated
+  * @return Pointer to the allocated block, or `NULL` if it cannot be allocated
+diff --git a/media/ffvpx/libavutil/mem_internal.h b/media/ffvpx/libavutil/mem_internal.h
+--- a/media/ffvpx/libavutil/mem_internal.h
++++ b/media/ffvpx/libavutil/mem_internal.h
+@@ -22,18 +22,16 @@
+ #define AVUTIL_MEM_INTERNAL_H
+ 
+ #include "config.h"
+ 
+ #include <stdint.h>
+ 
+ #include "attributes.h"
+ #include "macros.h"
+-#include "mem.h"
+-#include "version.h"
+ 
+ /**
+  * @def DECLARE_ALIGNED(n,t,v)
+  * Declare a variable that is aligned in memory.
+  *
+  * @code{.c}
+  * DECLARE_ALIGNED(16, uint16_t, aligned_int) = 42;
+  * DECLARE_ALIGNED(32, uint8_t, aligned_array)[128];
+@@ -71,37 +69,60 @@
+  * @endcode
+  *
+  * @param n Minimum alignment in bytes
+  * @param t Type of the variable (or array element)
+  * @param v Name of the variable
+  */
+ 
+ #if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C)
+-    #define DECLARE_ALIGNED(n,t,v)      t __attribute__ ((aligned (n))) v
++    #define DECLARE_ALIGNED_T(n,t,v)    t __attribute__ ((aligned (n))) v
+     #define DECLARE_ASM_ALIGNED(n,t,v)  t __attribute__ ((aligned (n))) v
+     #define DECLARE_ASM_CONST(n,t,v)    const t __attribute__ ((aligned (n))) v
+ #elif defined(__DJGPP__)
+-    #define DECLARE_ALIGNED(n,t,v)      t __attribute__ ((aligned (FFMIN(n, 16)))) v
++    #define DECLARE_ALIGNED_T(n,t,v)    t __attribute__ ((aligned (FFMIN(n, 16)))) v
+     #define DECLARE_ASM_ALIGNED(n,t,v)  t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v
+     #define DECLARE_ASM_CONST(n,t,v)    static const t av_used __attribute__ ((aligned (FFMIN(n, 16)))) v
+ #elif defined(__GNUC__) || defined(__clang__)
+-    #define DECLARE_ALIGNED(n,t,v)      t __attribute__ ((aligned (n))) v
++    #define DECLARE_ALIGNED_T(n,t,v)    t __attribute__ ((aligned (n))) v
+     #define DECLARE_ASM_ALIGNED(n,t,v)  t av_used __attribute__ ((aligned (n))) v
+     #define DECLARE_ASM_CONST(n,t,v)    static const t av_used __attribute__ ((aligned (n))) v
+ #elif defined(_MSC_VER)
+-    #define DECLARE_ALIGNED(n,t,v)      __declspec(align(n)) t v
++    #define DECLARE_ALIGNED_T(n,t,v)    __declspec(align(n)) t v
+     #define DECLARE_ASM_ALIGNED(n,t,v)  __declspec(align(n)) t v
+     #define DECLARE_ASM_CONST(n,t,v)    __declspec(align(n)) static const t v
+ #else
+-    #define DECLARE_ALIGNED(n,t,v)      t v
++    #define DECLARE_ALIGNED_T(n,t,v)    t v
+     #define DECLARE_ASM_ALIGNED(n,t,v)  t v
+     #define DECLARE_ASM_CONST(n,t,v)    static const t v
+ #endif
+ 
++#if HAVE_SIMD_ALIGN_64
++    #define ALIGN_64 64
++    #define ALIGN_32 32
++#elif HAVE_SIMD_ALIGN_32
++    #define ALIGN_64 32
++    #define ALIGN_32 32
++#else
++    #define ALIGN_64 16
++    #define ALIGN_32 16
++#endif
++
++#define DECLARE_ALIGNED(n,t,v) DECLARE_ALIGNED_V(n,t,v)
++
++// Macro needs to be double-wrapped in order to expand
++// possible other macros being passed for n.
++#define DECLARE_ALIGNED_V(n,t,v) DECLARE_ALIGNED_##n(t,v)
++
++#define DECLARE_ALIGNED_4(t,v)  DECLARE_ALIGNED_T(       4, t, v)
++#define DECLARE_ALIGNED_8(t,v)  DECLARE_ALIGNED_T(       8, t, v)
++#define DECLARE_ALIGNED_16(t,v) DECLARE_ALIGNED_T(      16, t, v)
++#define DECLARE_ALIGNED_32(t,v) DECLARE_ALIGNED_T(ALIGN_32, t, v)
++#define DECLARE_ALIGNED_64(t,v) DECLARE_ALIGNED_T(ALIGN_64, t, v)
++
+ // Some broken preprocessors need a second expansion
+ // to be forced to tokenize __VA_ARGS__
+ #define E1(x) x
+ 
+ #define LOCAL_ALIGNED_A(a, t, v, s, o, ...)             \
+     uint8_t la_##v[sizeof(t s o) + (a)];                \
+     t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
+ 
+diff --git a/media/ffvpx/libavutil/moz.build b/media/ffvpx/libavutil/moz.build
+--- a/media/ffvpx/libavutil/moz.build
++++ b/media/ffvpx/libavutil/moz.build
+@@ -30,16 +30,17 @@ SOURCES += [
+     'fifo.c',
+     'fixed_dsp.c',
+     'float_dsp.c',
+     'frame.c',
+     'hwcontext.c',
+     'imgutils.c',
+     'log.c',
+     'log2_tab.c',
++    'mastering_display_metadata.c',
+     'mathematics.c',
+     'mem.c',
+     'opt.c',
+     'parseutils.c',
+     'pixdesc.c',
+     'rational.c',
+     'reverse.c',
+     'samplefmt.c',
+@@ -51,39 +52,42 @@ SOURCES += [
+     'tx_int32.c',
+     'utils.c'
+ ]
+ 
+ if not CONFIG['MOZ_FFVPX_AUDIOONLY']:
+     SOURCES += [
+         'adler32.c',
+         'base64.c',
+-        'color_utils.c',
+         'film_grain_params.c',
+         'hdr_dynamic_metadata.c',
+         'integer.c',
+         'intmath.c',
+         'lls.c',
+-        'mastering_display_metadata.c',
+         'pixelutils.c',
+         'threadmessage.c',
+         'timecode.c',
+         'video_enc_params.c'
+     ]
+     if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
+         LOCAL_INCLUDES += ['/media/mozva']
+         SOURCES += [
+             'hwcontext_vaapi.c',
+         ]
+         USE_LIBS += ['mozva']
+ 
+ EXPORTS.ffvpx = [
+     "tx.h"
+ ]
+ 
++c11_flags = ["-std=gnu11"]
++if CONFIG["CC_TYPE"] == "clang-cl":
++    c11_flags.insert(0, "-Xclang")
++CFLAGS += c11_flags
++
+ SYMBOLS_FILE =  'avutil.symbols'
+ NoVisibilityFlags()
+ 
+ OS_LIBS += CONFIG['REALTIME_LIBS']
+ if CONFIG['OS_TARGET'] != 'WINNT':
+     OS_LIBS += ['m']
+ 
+ if CONFIG['MOZ_NEEDS_LIBATOMIC']:
+diff --git a/media/ffvpx/libavutil/opt.c b/media/ffvpx/libavutil/opt.c
+--- a/media/ffvpx/libavutil/opt.c
++++ b/media/ffvpx/libavutil/opt.c
+@@ -24,123 +24,209 @@
+  * AVOptions
+  * @author Michael Niedermayer <michaelni@gmx.at>
+  */
+ 
+ #include "avutil.h"
+ #include "avassert.h"
+ #include "avstring.h"
+ #include "channel_layout.h"
+-#include "common.h"
+ #include "dict.h"
+ #include "eval.h"
+ #include "log.h"
++#include "mem.h"
+ #include "parseutils.h"
+ #include "pixdesc.h"
+ #include "mathematics.h"
+ #include "opt.h"
+ #include "samplefmt.h"
+ #include "bprint.h"
+ #include "version.h"
+ 
+ #include <float.h>
+ 
++#define TYPE_BASE(type) ((type) & ~AV_OPT_TYPE_FLAG_ARRAY)
++
+ const AVOption *av_opt_next(const void *obj, const AVOption *last)
+ {
+     const AVClass *class;
+     if (!obj)
+         return NULL;
+     class = *(const AVClass**)obj;
+     if (!last && class && class->option && class->option[0].name)
+         return class->option;
+     if (last && last[1].name)
+         return ++last;
+     return NULL;
+ }
+ 
++static const size_t opt_elem_size[] = {
++    [AV_OPT_TYPE_FLAGS]         = sizeof(unsigned),
++    [AV_OPT_TYPE_INT]           = sizeof(int),
++    [AV_OPT_TYPE_INT64]         = sizeof(int64_t),
++    [AV_OPT_TYPE_UINT64]        = sizeof(uint64_t),
++    [AV_OPT_TYPE_DOUBLE]        = sizeof(double),
++    [AV_OPT_TYPE_FLOAT]         = sizeof(float),
++    [AV_OPT_TYPE_STRING]        = sizeof(char *),
++    [AV_OPT_TYPE_RATIONAL]      = sizeof(AVRational),
++    [AV_OPT_TYPE_BINARY]        = sizeof(uint8_t *),
++    [AV_OPT_TYPE_DICT]          = sizeof(AVDictionary *),
++    [AV_OPT_TYPE_IMAGE_SIZE]    = sizeof(int[2]),
++    [AV_OPT_TYPE_VIDEO_RATE]    = sizeof(AVRational),
++    [AV_OPT_TYPE_PIXEL_FMT]     = sizeof(int),
++    [AV_OPT_TYPE_SAMPLE_FMT]    = sizeof(int),
++    [AV_OPT_TYPE_DURATION]      = sizeof(int64_t),
++    [AV_OPT_TYPE_COLOR]         = sizeof(uint8_t[4]),
++    [AV_OPT_TYPE_CHLAYOUT]      = sizeof(AVChannelLayout),
++    [AV_OPT_TYPE_BOOL]          = sizeof(int),
++};
++
++// option is plain old data
++static int opt_is_pod(enum AVOptionType type)
++{
++    switch (type) {
++    case AV_OPT_TYPE_FLAGS:
++    case AV_OPT_TYPE_INT:
++    case AV_OPT_TYPE_INT64:
++    case AV_OPT_TYPE_DOUBLE:
++    case AV_OPT_TYPE_FLOAT:
++    case AV_OPT_TYPE_RATIONAL:
++    case AV_OPT_TYPE_UINT64:
++    case AV_OPT_TYPE_IMAGE_SIZE:
++    case AV_OPT_TYPE_PIXEL_FMT:
++    case AV_OPT_TYPE_SAMPLE_FMT:
++    case AV_OPT_TYPE_VIDEO_RATE:
++    case AV_OPT_TYPE_DURATION:
++    case AV_OPT_TYPE_COLOR:
++    case AV_OPT_TYPE_BOOL:
++        return 1;
++    }
++    return 0;
++}
++
++static uint8_t opt_array_sep(const AVOption *o)
++{
++    const AVOptionArrayDef *d = o->default_val.arr;
++    av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY);
++    return (d && d->sep) ? d->sep : ',';
++}
++
++static void *opt_array_pelem(const AVOption *o, void *array, unsigned idx)
++{
++    av_assert1(o->type & AV_OPT_TYPE_FLAG_ARRAY);
++    return (uint8_t *)array + idx * opt_elem_size[TYPE_BASE(o->type)];
++}
++
++static unsigned *opt_array_pcount(const void *parray)
++{
++    return (unsigned *)((const void * const *)parray + 1);
++}
++
++static void opt_free_elem(const AVOption *o, void *ptr)
++{
++    switch (TYPE_BASE(o->type)) {
++    case AV_OPT_TYPE_STRING:
++    case AV_OPT_TYPE_BINARY:
++        av_freep(ptr);
++        break;
++
++    case AV_OPT_TYPE_DICT:
++        av_dict_free((AVDictionary **)ptr);
++        break;
++
++    case AV_OPT_TYPE_CHLAYOUT:
++        av_channel_layout_uninit((AVChannelLayout *)ptr);
++        break;
++
++    default:
++        break;
++    }
++}
++
++static void opt_free_array(const AVOption *o, void *parray, unsigned *count)
++{
++    for (unsigned i = 0; i < *count; i++)
++        opt_free_elem(o, opt_array_pelem(o, *(void **)parray, i));
++
++    av_freep(parray);
++    *count = 0;
++}
++
+ static int read_number(const AVOption *o, const void *dst, double *num, int *den, int64_t *intnum)
+ {
+     switch (o->type) {
+     case AV_OPT_TYPE_FLAGS:
+         *intnum = *(unsigned int*)dst;
+         return 0;
+     case AV_OPT_TYPE_PIXEL_FMT:
+         *intnum = *(enum AVPixelFormat *)dst;
+         return 0;
+     case AV_OPT_TYPE_SAMPLE_FMT:
+         *intnum = *(enum AVSampleFormat *)dst;
+         return 0;
+     case AV_OPT_TYPE_BOOL:
+     case AV_OPT_TYPE_INT:
+         *intnum = *(int *)dst;
+         return 0;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     case AV_OPT_TYPE_DURATION:
+     case AV_OPT_TYPE_INT64:
+     case AV_OPT_TYPE_UINT64:
+         *intnum = *(int64_t *)dst;
+         return 0;
+     case AV_OPT_TYPE_FLOAT:
+         *num = *(float *)dst;
+         return 0;
+     case AV_OPT_TYPE_DOUBLE:
+         *num = *(double *)dst;
+         return 0;
+     case AV_OPT_TYPE_RATIONAL:
+         *intnum = ((AVRational *)dst)->num;
+         *den    = ((AVRational *)dst)->den;
+         return 0;
+     case AV_OPT_TYPE_CONST:
+-        *num = o->default_val.dbl;
++        *intnum = o->default_val.i64;
+         return 0;
+     }
+     return AVERROR(EINVAL);
+ }
+ 
+ static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
+ {
+-    if (o->type != AV_OPT_TYPE_FLAGS &&
++    const enum AVOptionType type = TYPE_BASE(o->type);
++
++    if (type != AV_OPT_TYPE_FLAGS &&
+         (!den || o->max * den < num * intnum || o->min * den > num * intnum)) {
+         num = den ? num * intnum / den : (num && intnum ? INFINITY : NAN);
+         av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n",
+                num, o->name, o->min, o->max);
+         return AVERROR(ERANGE);
+     }
+-    if (o->type == AV_OPT_TYPE_FLAGS) {
++    if (type == AV_OPT_TYPE_FLAGS) {
+         double d = num*intnum/den;
+         if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) {
+             av_log(obj, AV_LOG_ERROR,
+                    "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n",
+                    num*intnum/den, o->name);
+             return AVERROR(ERANGE);
+         }
+     }
+ 
+-    switch (o->type) {
++    switch (type) {
+     case AV_OPT_TYPE_PIXEL_FMT:
+         *(enum AVPixelFormat *)dst = llrint(num / den) * intnum;
+         break;
+     case AV_OPT_TYPE_SAMPLE_FMT:
+         *(enum AVSampleFormat *)dst = llrint(num / den) * intnum;
+         break;
+     case AV_OPT_TYPE_BOOL:
+     case AV_OPT_TYPE_FLAGS:
+     case AV_OPT_TYPE_INT:
+         *(int *)dst = llrint(num / den) * intnum;
+         break;
+     case AV_OPT_TYPE_DURATION:
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     case AV_OPT_TYPE_INT64:{
+         double d = num / den;
+         if (intnum == 1 && d == (double)INT64_MAX) {
+             *(int64_t *)dst = INT64_MAX;
+         } else
+             *(int64_t *)dst = llrint(d) * intnum;
+         break;}
+     case AV_OPT_TYPE_UINT64:{
+@@ -218,50 +304,53 @@ static int set_string_binary(void *obj, 
+     *lendst = len;
+ 
+     return 0;
+ }
+ 
+ static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst)
+ {
+     av_freep(dst);
++    if (!val)
++        return 0;
+     *dst = av_strdup(val);
+     return *dst ? 0 : AVERROR(ENOMEM);
+ }
+ 
+ #define DEFAULT_NUMVAL(opt) ((opt->type == AV_OPT_TYPE_INT64 || \
+                               opt->type == AV_OPT_TYPE_UINT64 || \
+                               opt->type == AV_OPT_TYPE_CONST || \
+                               opt->type == AV_OPT_TYPE_FLAGS || \
+                               opt->type == AV_OPT_TYPE_INT)     \
+                              ? opt->default_val.i64             \
+                              : opt->default_val.dbl)
+ 
+ static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
+ {
++    const enum AVOptionType type = TYPE_BASE(o->type);
+     int ret = 0;
+ 
+-    if (o->type == AV_OPT_TYPE_RATIONAL || o->type == AV_OPT_TYPE_VIDEO_RATE) {
++    if (type == AV_OPT_TYPE_RATIONAL || type == AV_OPT_TYPE_VIDEO_RATE) {
+         int num, den;
+         char c;
+         if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) {
+             if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0)
+                 return ret;
+             ret = 0;
+         }
+     }
+ 
+     for (;;) {
+         int i = 0;
+         char buf[256];
+         int cmd = 0;
+         double d;
+         int64_t intnum = 1;
+ 
+-        if (o->type == AV_OPT_TYPE_FLAGS) {
++        if (type == AV_OPT_TYPE_FLAGS) {
+             if (*val == '+' || *val == '-')
+                 cmd = *(val++);
+             for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
+                 buf[i] = val[i];
+             buf[i] = 0;
+         }
+ 
+         {
+@@ -307,18 +396,18 @@ static int set_string_number(void *obj, 
+                 res = av_expr_parse_and_eval(&d, i ? buf : val, const_names,
+                                             const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
+                 if (res < 0) {
+                     av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);
+                     return res;
+                 }
+             }
+         }
+-        if (o->type == AV_OPT_TYPE_FLAGS) {
+-            read_number(o, dst, NULL, NULL, &intnum);
++        if (type == AV_OPT_TYPE_FLAGS) {
++            intnum = *(unsigned int*)dst;
+             if (cmd == '+')
+                 d = intnum | (int64_t)d;
+             else if (cmd == '-')
+                 d = intnum &~(int64_t)d;
+         }
+ 
+         if ((ret = write_number(obj, o, dst, d, 1, 1)) < 0)
+             return ret;
+@@ -439,26 +528,36 @@ static int set_string_fmt(void *obj, con
+                fmt, o->name, desc, min, max);
+         return AVERROR(ERANGE);
+     }
+ 
+     *(int *)dst = fmt;
+     return 0;
+ }
+ 
++static int get_pix_fmt(const char *name)
++{
++    return av_get_pix_fmt(name);
++}
++
+ static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
+ {
+     return set_string_fmt(obj, o, val, dst,
+-                          AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format");
++                          AV_PIX_FMT_NB, get_pix_fmt, "pixel format");
++}
++
++static int get_sample_fmt(const char *name)
++{
++    return av_get_sample_fmt(name);
+ }
+ 
+ static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst)
+ {
+     return set_string_fmt(obj, o, val, dst,
+-                          AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format");
++                          AV_SAMPLE_FMT_NB, get_sample_fmt, "sample format");
+ }
+ 
+ static int set_string_dict(void *obj, const AVOption *o, const char *val, uint8_t **dst)
+ {
+     AVDictionary *options = NULL;
+ 
+     if (val) {
+         int ret = av_dict_parse_string(&options, val, "=", ":", 0);
+@@ -479,43 +578,30 @@ static int set_string_channel_layout(voi
+ {
+     AVChannelLayout *channel_layout = dst;
+     av_channel_layout_uninit(channel_layout);
+     if (!val)
+         return 0;
+     return av_channel_layout_from_string(channel_layout, val);
+ }
+ 
+-int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
++static int opt_set_elem(void *obj, void *target_obj, const AVOption *o,
++                        const char *val, void *dst)
+ {
+-    int ret = 0;
+-    void *dst, *target_obj;
+-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+-    if (!o || !target_obj)
+-        return AVERROR_OPTION_NOT_FOUND;
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    if (!val && (o->type != AV_OPT_TYPE_STRING &&
+-                 o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT &&
+-                 o->type != AV_OPT_TYPE_IMAGE_SIZE &&
+-                 o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR &&
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-                 o->type != AV_OPT_TYPE_CHANNEL_LAYOUT &&
+-#endif
+-                 o->type != AV_OPT_TYPE_BOOL))
+-        return AVERROR(EINVAL);
+-FF_ENABLE_DEPRECATION_WARNINGS
++    const enum AVOptionType type = TYPE_BASE(o->type);
++    int ret;
+ 
+-    if (o->flags & AV_OPT_FLAG_READONLY)
++    if (!val && (type != AV_OPT_TYPE_STRING &&
++                 type != AV_OPT_TYPE_PIXEL_FMT && type != AV_OPT_TYPE_SAMPLE_FMT &&
++                 type != AV_OPT_TYPE_IMAGE_SIZE &&
++                 type != AV_OPT_TYPE_DURATION && type != AV_OPT_TYPE_COLOR &&
++                 type != AV_OPT_TYPE_BOOL))
+         return AVERROR(EINVAL);
+ 
+-    if (o->flags & AV_OPT_FLAG_DEPRECATED)
+-        av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
+-
+-    dst = ((uint8_t *)target_obj) + o->offset;
+-    switch (o->type) {
++    switch (type) {
+     case AV_OPT_TYPE_BOOL:
+         return set_string_bool(obj, o, val, dst);
+     case AV_OPT_TYPE_STRING:
+         return set_string(obj, o, val, dst);
+     case AV_OPT_TYPE_BINARY:
+         return set_string_binary(obj, o, val, dst);
+     case AV_OPT_TYPE_FLAGS:
+     case AV_OPT_TYPE_INT:
+@@ -552,48 +638,129 @@ FF_ENABLE_DEPRECATION_WARNINGS
+                        usecs / 1000000.0, o->name, o->min / 1000000.0, o->max / 1000000.0);
+                 return AVERROR(ERANGE);
+             }
+             *(int64_t *)dst = usecs;
+             return 0;
+         }
+     case AV_OPT_TYPE_COLOR:
+         return set_string_color(obj, o, val, dst);
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-        if (!val || !strcmp(val, "none")) {
+-            *(int64_t *)dst = 0;
+-        } else {
+-            int64_t cl = av_get_channel_layout(val);
+-            if (!cl) {
+-                av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
+-                ret = AVERROR(EINVAL);
+-            }
+-            *(int64_t *)dst = cl;
+-            return ret;
+-        }
+-        break;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     case AV_OPT_TYPE_CHLAYOUT:
+         ret = set_string_channel_layout(obj, o, val, dst);
+         if (ret < 0) {
+             av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val);
+             ret = AVERROR(EINVAL);
+         }
+         return ret;
+     case AV_OPT_TYPE_DICT:
+         return set_string_dict(obj, o, val, dst);
+     }
+ 
+     av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
+     return AVERROR(EINVAL);
+ }
+ 
++static int opt_set_array(void *obj, void *target_obj, const AVOption *o,
++                         const char *val, void *dst)
++{
++    const AVOptionArrayDef *arr = o->default_val.arr;
++    const size_t      elem_size = opt_elem_size[TYPE_BASE(o->type)];
++    const uint8_t           sep = opt_array_sep(o);
++    uint8_t                *str = NULL;
++
++    void       *elems = NULL;
++    unsigned nb_elems = 0;
++    int ret;
++
++    if (val && *val) {
++        str = av_malloc(strlen(val) + 1);
++        if (!str)
++            return AVERROR(ENOMEM);
++    }
++
++    // split and unescape the string
++    while (val && *val) {
++        uint8_t *p = str;
++        void *tmp;
++
++        if (arr && arr->size_max && nb_elems >= arr->size_max) {
++            av_log(obj, AV_LOG_ERROR,
++                   "Cannot assign more than %u elements to array option %s\n",
++                   arr->size_max, o->name);
++            ret = AVERROR(EINVAL);
++            goto fail;
++        }
++
++        for (; *val; val++, p++) {
++            if (*val == '\\' && val[1])
++                val++;
++            else if (*val == sep) {
++                val++;
++                break;
++            }
++            *p = *val;
++        }
++        *p = 0;
++
++        tmp = av_realloc_array(elems, nb_elems + 1, elem_size);
++        if (!tmp) {
++            ret = AVERROR(ENOMEM);
++            goto fail;
++        }
++        elems = tmp;
++
++        tmp = opt_array_pelem(o, elems, nb_elems);
++        memset(tmp, 0, elem_size);
++
++        ret = opt_set_elem(obj, target_obj, o, str, tmp);
++        if (ret < 0)
++            goto fail;
++        nb_elems++;
++    }
++    av_freep(&str);
++
++    opt_free_array(o, dst, opt_array_pcount(dst));
++
++    if (arr && nb_elems < arr->size_min) {
++        av_log(obj, AV_LOG_ERROR,
++               "Cannot assign fewer than %u elements to array option %s\n",
++               arr->size_min, o->name);
++        ret = AVERROR(EINVAL);
++        goto fail;
++    }
++
++    *((void **)dst)        = elems;
++    *opt_array_pcount(dst) = nb_elems;
++
++    return 0;
++fail:
++    av_freep(&str);
++    opt_free_array(o, &elems, &nb_elems);
++    return ret;
++}
++
++int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
++{
++    void *dst, *target_obj;
++    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
++    if (!o || !target_obj)
++        return AVERROR_OPTION_NOT_FOUND;
++
++    if (o->flags & AV_OPT_FLAG_READONLY)
++        return AVERROR(EINVAL);
++
++    if (o->flags & AV_OPT_FLAG_DEPRECATED)
++        av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
++
++    dst = ((uint8_t *)target_obj) + o->offset;
++
++    return ((o->type & AV_OPT_TYPE_FLAG_ARRAY) ?
++            opt_set_array : opt_set_elem)(obj, target_obj, o, val, dst);
++}
++
+ #define OPT_EVAL_NUMBER(name, opttype, vartype)                         \
+ int av_opt_eval_ ## name(void *obj, const AVOption *o,                  \
+                          const char *val, vartype *name ## _out)        \
+ {                                                                       \
+     if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY)    \
+         return AVERROR(EINVAL);                                         \
+     return set_string_number(obj, obj, o, val, name ## _out);           \
+ }
+@@ -609,17 +776,17 @@ static int set_number(void *obj, const c
+                       int search_flags)
+ {
+     void *dst, *target_obj;
+     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ 
+     if (!o || !target_obj)
+         return AVERROR_OPTION_NOT_FOUND;
+ 
+-    if (o->flags & AV_OPT_FLAG_READONLY)
++    if ((o->flags & AV_OPT_FLAG_READONLY) || (o->type & AV_OPT_TYPE_FLAG_ARRAY))
+         return AVERROR(EINVAL);
+ 
+     dst = ((uint8_t *)target_obj) + o->offset;
+     return write_number(obj, o, dst, num, den, intnum);
+ }
+ 
+ int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
+ {
+@@ -692,17 +859,18 @@ int av_opt_set_video_rate(void *obj, con
+ {
+     void *target_obj;
+     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ 
+     if (!o || !target_obj)
+         return AVERROR_OPTION_NOT_FOUND;
+     if (o->type != AV_OPT_TYPE_VIDEO_RATE) {
+         av_log(obj, AV_LOG_ERROR,
+-               "The value set by option '%s' is not a video rate.\n", o->name);
++               "The value set by option '%s' is not a video rate.\n",
++               o->name);
+         return AVERROR(EINVAL);
+     }
+     if (val.num <= 0 || val.den <= 0)
+         return AVERROR(EINVAL);
+     return set_number(obj, name, val.num, val.den, 1, search_flags);
+ }
+ 
+ static int set_format(void *obj, const char *name, int fmt, int search_flags,
+@@ -739,36 +907,16 @@ int av_opt_set_pixel_fmt(void *obj, cons
+     return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_PIXEL_FMT, "pixel", AV_PIX_FMT_NB);
+ }
+ 
+ int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
+ {
+     return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB);
+ }
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags)
+-{
+-    void *target_obj;
+-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+-
+-    if (!o || !target_obj)
+-        return AVERROR_OPTION_NOT_FOUND;
+-    if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
+-        av_log(obj, AV_LOG_ERROR,
+-               "The value set by option '%s' is not a channel layout.\n", o->name);
+-        return AVERROR(EINVAL);
+-    }
+-    *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl;
+-    return 0;
+-}
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+ int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val,
+                         int search_flags)
+ {
+     void *target_obj;
+     AVDictionary **dst;
+     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+ 
+     if (!o || !target_obj)
+@@ -829,191 +977,270 @@ static void format_duration(char *buf, s
+                  (int)(d % 1000000));
+     e = buf + strlen(buf);
+     while (e > buf && e[-1] == '0')
+         *(--e) = 0;
+     if (e > buf && e[-1] == '.')
+         *(--e) = 0;
+ }
+ 
++static int opt_get_elem(const AVOption *o, uint8_t **pbuf, size_t buf_len,
++                        void *dst, int search_flags)
++{
++    int ret;
++
++    switch (TYPE_BASE(o->type)) {
++    case AV_OPT_TYPE_BOOL:
++        ret = snprintf(*pbuf, buf_len, "%s", get_bool_name(*(int *)dst));
++        break;
++    case AV_OPT_TYPE_FLAGS:
++        ret = snprintf(*pbuf, buf_len, "0x%08X", *(int *)dst);
++        break;
++    case AV_OPT_TYPE_INT:
++        ret = snprintf(*pbuf, buf_len, "%d", *(int *)dst);
++        break;
++    case AV_OPT_TYPE_INT64:
++        ret = snprintf(*pbuf, buf_len, "%"PRId64, *(int64_t *)dst);
++        break;
++    case AV_OPT_TYPE_UINT64:
++        ret = snprintf(*pbuf, buf_len, "%"PRIu64, *(uint64_t *)dst);
++        break;
++    case AV_OPT_TYPE_FLOAT:
++        ret = snprintf(*pbuf, buf_len, "%f", *(float *)dst);
++        break;
++    case AV_OPT_TYPE_DOUBLE:
++        ret = snprintf(*pbuf, buf_len, "%f", *(double *)dst);
++        break;
++    case AV_OPT_TYPE_VIDEO_RATE:
++    case AV_OPT_TYPE_RATIONAL:
++        ret = snprintf(*pbuf, buf_len, "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den);
++        break;
++    case AV_OPT_TYPE_CONST:
++        ret = snprintf(*pbuf, buf_len, "%"PRId64, o->default_val.i64);
++        break;
++    case AV_OPT_TYPE_STRING:
++        if (*(uint8_t **)dst) {
++            *pbuf = av_strdup(*(uint8_t **)dst);
++        } else if (search_flags & AV_OPT_ALLOW_NULL) {
++            *pbuf = NULL;
++            return 0;
++        } else {
++            *pbuf = av_strdup("");
++        }
++        return *pbuf ? 0 : AVERROR(ENOMEM);
++    case AV_OPT_TYPE_BINARY: {
++        const uint8_t *bin;
++        int len;
++
++        if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
++            *pbuf = NULL;
++            return 0;
++        }
++        len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *));
++        if ((uint64_t)len * 2 + 1 > INT_MAX)
++            return AVERROR(EINVAL);
++        if (!(*pbuf = av_malloc(len * 2 + 1)))
++            return AVERROR(ENOMEM);
++        if (!len) {
++            *pbuf[0] = '\0';
++            return 0;
++        }
++        bin = *(uint8_t **)dst;
++        for (int i = 0; i < len; i++)
++            snprintf(*pbuf + i * 2, 3, "%02X", bin[i]);
++        return 0;
++    }
++    case AV_OPT_TYPE_IMAGE_SIZE:
++        ret = snprintf(*pbuf, buf_len, "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
++        break;
++    case AV_OPT_TYPE_PIXEL_FMT:
++        ret = snprintf(*pbuf, buf_len, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
++        break;
++    case AV_OPT_TYPE_SAMPLE_FMT:
++        ret = snprintf(*pbuf, buf_len, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
++        break;
++    case AV_OPT_TYPE_DURATION: {
++        int64_t i64 = *(int64_t *)dst;
++        format_duration(*pbuf, buf_len, i64);
++        ret = strlen(*pbuf); // no overflow possible, checked by an assert
++        break;
++    }
++    case AV_OPT_TYPE_COLOR:
++        ret = snprintf(*pbuf, buf_len, "0x%02x%02x%02x%02x",
++                       (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
++                       (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
++        break;
++    case AV_OPT_TYPE_CHLAYOUT:
++        ret = av_channel_layout_describe(dst, *pbuf, buf_len);
++        break;
++    case AV_OPT_TYPE_DICT:
++        if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
++            *pbuf = NULL;
++            return 0;
++        }
++        return av_dict_get_string(*(AVDictionary **)dst, (char **)pbuf, '=', ':');
++    default:
++        return AVERROR(EINVAL);
++    }
++
++    return ret;
++}
++
++static int opt_get_array(const AVOption *o, void *dst, uint8_t **out_val)
++{
++    const unsigned count = *opt_array_pcount(dst);
++    const uint8_t    sep = opt_array_sep(o);
++
++    uint8_t *str     = NULL;
++    size_t   str_len = 0;
++    int ret;
++
++    *out_val = NULL;
++
++    for (unsigned i = 0; i < count; i++) {
++        uint8_t buf[128], *out = buf;
++        size_t out_len;
++
++        ret = opt_get_elem(o, &out, sizeof(buf),
++                           opt_array_pelem(o, *(void **)dst, i), 0);
++        if (ret < 0)
++            goto fail;
++
++        out_len = strlen(out);
++        if (out_len > SIZE_MAX / 2 - !!i ||
++            !!i + out_len * 2 > SIZE_MAX - str_len - 1) {
++            ret = AVERROR(ERANGE);
++            goto fail;
++        }
++
++        //                         terminator     escaping  separator
++        //                                ↓             ↓     ↓
++        ret = av_reallocp(&str, str_len + 1 + out_len * 2 + !!i);
++        if (ret < 0)
++            goto fail;
++
++        // add separator if needed
++        if (i)
++            str[str_len++] = sep;
++
++        // escape the element
++        for (unsigned j = 0; j < out_len; j++) {
++            uint8_t val = out[j];
++            if (val == sep || val == '\\')
++                str[str_len++] = '\\';
++            str[str_len++] = val;
++        }
++        str[str_len] = 0;
++
++fail:
++        if (out != buf)
++            av_freep(&out);
++        if (ret < 0) {
++            av_freep(&str);
++            return ret;
++        }
++    }
++
++    *out_val = str;
++
++    return 0;
++}
++
+ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
+ {
+     void *dst, *target_obj;
+     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+-    uint8_t *bin, buf[128];
+-    int len, i, ret;
+-    int64_t i64;
++    uint8_t *out, buf[128];
++    int ret;
+ 
+     if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
+         return AVERROR_OPTION_NOT_FOUND;
+ 
+     if (o->flags & AV_OPT_FLAG_DEPRECATED)
+         av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
+ 
+     dst = (uint8_t *)target_obj + o->offset;
+ 
+-    buf[0] = 0;
+-    switch (o->type) {
+-    case AV_OPT_TYPE_BOOL:
+-        ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(get_bool_name(*(int *)dst), "invalid"));
+-        break;
+-    case AV_OPT_TYPE_FLAGS:
+-        ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);
+-        break;
+-    case AV_OPT_TYPE_INT:
+-        ret = snprintf(buf, sizeof(buf), "%d", *(int *)dst);
+-        break;
+-    case AV_OPT_TYPE_INT64:
+-        ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t *)dst);
+-        break;
+-    case AV_OPT_TYPE_UINT64:
+-        ret = snprintf(buf, sizeof(buf), "%"PRIu64, *(uint64_t *)dst);
+-        break;
+-    case AV_OPT_TYPE_FLOAT:
+-        ret = snprintf(buf, sizeof(buf), "%f", *(float *)dst);
+-        break;
+-    case AV_OPT_TYPE_DOUBLE:
+-        ret = snprintf(buf, sizeof(buf), "%f", *(double *)dst);
+-        break;
+-    case AV_OPT_TYPE_VIDEO_RATE:
+-    case AV_OPT_TYPE_RATIONAL:
+-        ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational *)dst)->num, ((AVRational *)dst)->den);
+-        break;
+-    case AV_OPT_TYPE_CONST:
+-        ret = snprintf(buf, sizeof(buf), "%f", o->default_val.dbl);
+-        break;
+-    case AV_OPT_TYPE_STRING:
+-        if (*(uint8_t **)dst) {
+-            *out_val = av_strdup(*(uint8_t **)dst);
+-        } else if (search_flags & AV_OPT_ALLOW_NULL) {
+-            *out_val = NULL;
+-            return 0;
+-        } else {
++    if (o->type & AV_OPT_TYPE_FLAG_ARRAY) {
++        ret = opt_get_array(o, dst, out_val);
++        if (ret < 0)
++            return ret;
++        if (!*out_val && !(search_flags & AV_OPT_ALLOW_NULL)) {
+             *out_val = av_strdup("");
+-        }
+-        return *out_val ? 0 : AVERROR(ENOMEM);
+-    case AV_OPT_TYPE_BINARY:
+-        if (!*(uint8_t **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
+-            *out_val = NULL;
+-            return 0;
++            if (!*out_val)
++               return AVERROR(ENOMEM);
+         }
+-        len = *(int *)(((uint8_t *)dst) + sizeof(uint8_t *));
+-        if ((uint64_t)len * 2 + 1 > INT_MAX)
+-            return AVERROR(EINVAL);
+-        if (!(*out_val = av_malloc(len * 2 + 1)))
+-            return AVERROR(ENOMEM);
+-        if (!len) {
+-            *out_val[0] = '\0';
+-            return 0;
+-        }
+-        bin = *(uint8_t **)dst;
+-        for (i = 0; i < len; i++)
+-            snprintf(*out_val + i * 2, 3, "%02X", bin[i]);
+         return 0;
+-    case AV_OPT_TYPE_IMAGE_SIZE:
+-        ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
+-        break;
+-    case AV_OPT_TYPE_PIXEL_FMT:
+-        ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
+-        break;
+-    case AV_OPT_TYPE_SAMPLE_FMT:
+-        ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none"));
+-        break;
+-    case AV_OPT_TYPE_DURATION:
+-        i64 = *(int64_t *)dst;
+-        format_duration(buf, sizeof(buf), i64);
+-        ret = strlen(buf); // no overflow possible, checked by an assert
+-        break;
+-    case AV_OPT_TYPE_COLOR:
+-        ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x",
+-                       (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1],
+-                       (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]);
+-        break;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
++    }
+ 
+-        i64 = *(int64_t *)dst;
+-        ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64);
+-        break;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-    case AV_OPT_TYPE_CHLAYOUT:
+-        ret = av_channel_layout_describe(dst, buf, sizeof(buf));
+-        break;
+-    case AV_OPT_TYPE_DICT:
+-        if (!*(AVDictionary **)dst && (search_flags & AV_OPT_ALLOW_NULL)) {
+-            *out_val = NULL;
+-            return 0;
+-        }
+-        return av_dict_get_string(*(AVDictionary **)dst, (char **)out_val, '=', ':');
+-    default:
+-        return AVERROR(EINVAL);
++    buf[0] = 0;
++    out = buf;
++    ret = opt_get_elem(o, &out, sizeof(buf), dst, search_flags);
++    if (ret < 0)
++        return ret;
++    if (out != buf) {
++        *out_val = out;
++        return 0;
+     }
+ 
+     if (ret >= sizeof(buf))
+         return AVERROR(EINVAL);
+-    *out_val = av_strdup(buf);
++    *out_val = av_strdup(out);
+     return *out_val ? 0 : AVERROR(ENOMEM);
+ }
+ 
+-static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
++static int get_number(void *obj, const char *name, double *num, int *den, int64_t *intnum,
+                       int search_flags)
+ {
+     void *dst, *target_obj;
+     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+     if (!o || !target_obj)
+-        goto error;
++        return AVERROR_OPTION_NOT_FOUND;
++    if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
++        return AVERROR(EINVAL);
+ 
+     dst = ((uint8_t *)target_obj) + o->offset;
+ 
+-    if (o_out) *o_out= o;
+-
+     return read_number(o, dst, num, den, intnum);
+-
+-error:
+-    *den    =
+-    *intnum = 0;
+-    return -1;
+ }
+ 
+ int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
+ {
+     int64_t intnum = 1;
+     double num = 1;
+     int ret, den = 1;
+ 
+-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
++    if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
+         return ret;
+     if (num == den)
+         *out_val = intnum;
+     else
+         *out_val = num * intnum / den;
+     return 0;
+ }
+ 
+ int av_opt_get_double(void *obj, const char *name, int search_flags, double *out_val)
+ {
+     int64_t intnum = 1;
+     double num = 1;
+     int ret, den = 1;
+ 
+-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
++    if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
+         return ret;
+     *out_val = num * intnum / den;
+     return 0;
+ }
+ 
+ int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_val)
+ {
+     int64_t intnum = 1;
+     double num = 1;
+     int ret, den = 1;
+ 
+-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
++    if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
+         return ret;
+ 
+     if (num == 1.0 && (int)intnum == intnum)
+         *out_val = (AVRational){intnum, den};
+     else
+         *out_val = av_d2q(num*intnum/den, 1<<24);
+     return 0;
+ }
+@@ -1021,33 +1248,33 @@ int av_opt_get_q(void *obj, const char *
+ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out)
+ {
+     void *dst, *target_obj;
+     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+     if (!o || !target_obj)
+         return AVERROR_OPTION_NOT_FOUND;
+     if (o->type != AV_OPT_TYPE_IMAGE_SIZE) {
+         av_log(obj, AV_LOG_ERROR,
+-               "The value for option '%s' is not an image size.\n", name);
++               "The value for option '%s' is not a image size.\n", name);
+         return AVERROR(EINVAL);
+     }
+ 
+     dst = ((uint8_t*)target_obj) + o->offset;
+     if (w_out) *w_out = *(int *)dst;
+     if (h_out) *h_out = *((int *)dst+1);
+     return 0;
+ }
+ 
+ int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val)
+ {
+     int64_t intnum = 1;
+     double     num = 1;
+     int   ret, den = 1;
+ 
+-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
++    if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
+         return ret;
+ 
+     if (num == 1.0 && (int)intnum == intnum)
+         *out_val = (AVRational) { intnum, den };
+     else
+         *out_val = av_d2q(num * intnum / den, 1 << 24);
+     return 0;
+ }
+@@ -1075,37 +1302,16 @@ int av_opt_get_pixel_fmt(void *obj, cons
+     return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_PIXEL_FMT, "pixel");
+ }
+ 
+ int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt)
+ {
+     return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample");
+ }
+ 
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl)
+-{
+-    void *dst, *target_obj;
+-    const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+-    if (!o || !target_obj)
+-        return AVERROR_OPTION_NOT_FOUND;
+-    if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) {
+-        av_log(obj, AV_LOG_ERROR,
+-               "The value for option '%s' is not a channel layout.\n", name);
+-        return AVERROR(EINVAL);
+-    }
+-
+-    dst = ((uint8_t*)target_obj) + o->offset;
+-    *cl = *(int64_t *)dst;
+-    return 0;
+-}
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-
+ int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *cl)
+ {
+     void *dst, *target_obj;
+     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
+     if (!o || !target_obj)
+         return AVERROR_OPTION_NOT_FOUND;
+     if (o->type != AV_OPT_TYPE_CHLAYOUT) {
+         av_log(obj, AV_LOG_ERROR,
+@@ -1226,16 +1432,130 @@ static char *get_opt_flags_string(void *
+             av_strlcatf(flags, sizeof(flags), "%s", opt->name);
+         }
+     }
+     if (flags[0])
+         return av_strdup(flags);
+     return NULL;
+ }
+ 
++static void log_type(void *av_log_obj, const AVOption *o,
++                     enum AVOptionType parent_type)
++{
++    const char *desc[] = {
++        [AV_OPT_TYPE_FLAGS]         = "<flags>",
++        [AV_OPT_TYPE_INT]           = "<int>",
++        [AV_OPT_TYPE_INT64]         = "<int64>",
++        [AV_OPT_TYPE_UINT64]        = "<uint64>",
++        [AV_OPT_TYPE_DOUBLE]        = "<double>",
++        [AV_OPT_TYPE_FLOAT]         = "<float>",
++        [AV_OPT_TYPE_STRING]        = "<string>",
++        [AV_OPT_TYPE_RATIONAL]      = "<rational>",
++        [AV_OPT_TYPE_BINARY]        = "<binary>",
++        [AV_OPT_TYPE_DICT]          = "<dictionary>",
++        [AV_OPT_TYPE_IMAGE_SIZE]    = "<image_size>",
++        [AV_OPT_TYPE_VIDEO_RATE]    = "<video_rate>",
++        [AV_OPT_TYPE_PIXEL_FMT]     = "<pix_fmt>",
++        [AV_OPT_TYPE_SAMPLE_FMT]    = "<sample_fmt>",
++        [AV_OPT_TYPE_DURATION]      = "<duration>",
++        [AV_OPT_TYPE_COLOR]         = "<color>",
++        [AV_OPT_TYPE_CHLAYOUT]      = "<channel_layout>",
++        [AV_OPT_TYPE_BOOL]          = "<boolean>",
++    };
++    const enum AVOptionType type = TYPE_BASE(o->type);
++
++    if (o->type == AV_OPT_TYPE_CONST && TYPE_BASE(parent_type) == AV_OPT_TYPE_INT)
++        av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", o->default_val.i64);
++    else if (type < FF_ARRAY_ELEMS(desc) && desc[type]) {
++        if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
++            av_log(av_log_obj, AV_LOG_INFO, "[%-10s]", desc[type]);
++        else
++            av_log(av_log_obj, AV_LOG_INFO, "%-12s ", desc[type]);
++    }
++    else
++        av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
++}
++
++static void log_default(void *obj, void *av_log_obj, const AVOption *opt)
++{
++    if (opt->type == AV_OPT_TYPE_CONST || opt->type == AV_OPT_TYPE_BINARY)
++        return;
++    if ((opt->type == AV_OPT_TYPE_COLOR      ||
++         opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
++         opt->type == AV_OPT_TYPE_STRING     ||
++         opt->type == AV_OPT_TYPE_DICT       ||
++         opt->type == AV_OPT_TYPE_CHLAYOUT   ||
++         opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
++        !opt->default_val.str)
++        return;
++
++    if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) {
++        const AVOptionArrayDef *arr = opt->default_val.arr;
++        if (arr && arr->def)
++            av_log(av_log_obj, AV_LOG_INFO, " (default %s)", arr->def);
++        return;
++    }
++
++    av_log(av_log_obj, AV_LOG_INFO, " (default ");
++    switch (opt->type) {
++    case AV_OPT_TYPE_BOOL:
++        av_log(av_log_obj, AV_LOG_INFO, "%s", get_bool_name(opt->default_val.i64));
++        break;
++    case AV_OPT_TYPE_FLAGS: {
++        char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64);
++        if (def_flags) {
++            av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags);
++            av_freep(&def_flags);
++        } else {
++            av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
++        }
++        break;
++    }
++    case AV_OPT_TYPE_DURATION: {
++        char buf[25];
++        format_duration(buf, sizeof(buf), opt->default_val.i64);
++        av_log(av_log_obj, AV_LOG_INFO, "%s", buf);
++        break;
++    }
++    case AV_OPT_TYPE_INT:
++    case AV_OPT_TYPE_UINT64:
++    case AV_OPT_TYPE_INT64: {
++        const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64);
++        if (def_const)
++            av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
++        else
++            log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
++        break;
++    }
++    case AV_OPT_TYPE_DOUBLE:
++    case AV_OPT_TYPE_FLOAT:
++        log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
++        break;
++    case AV_OPT_TYPE_RATIONAL: {
++        AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
++        av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
++        break;
++    case AV_OPT_TYPE_PIXEL_FMT:
++        av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
++        break;
++    case AV_OPT_TYPE_SAMPLE_FMT:
++        av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
++        break;
++    case AV_OPT_TYPE_COLOR:
++    case AV_OPT_TYPE_IMAGE_SIZE:
++    case AV_OPT_TYPE_STRING:
++    case AV_OPT_TYPE_DICT:
++    case AV_OPT_TYPE_VIDEO_RATE:
++    case AV_OPT_TYPE_CHLAYOUT:
++        av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
++        break;
++    }
++    av_log(av_log_obj, AV_LOG_INFO, ")");
++}
++
+ static void opt_list(void *obj, void *av_log_obj, const char *unit,
+                      int req_flags, int rej_flags, enum AVOptionType parent_type)
+ {
+     const AVOption *opt = NULL;
+     AVOptionRanges *r;
+     int i;
+ 
+     while ((opt = av_opt_next(obj, opt))) {
+@@ -1254,86 +1574,18 @@ static void opt_list(void *obj, void *av
+             continue;
+         else if (unit && opt->type == AV_OPT_TYPE_CONST)
+             av_log(av_log_obj, AV_LOG_INFO, "     %-15s ", opt->name);
+         else
+             av_log(av_log_obj, AV_LOG_INFO, "  %s%-17s ",
+                    (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? " " : "-",
+                    opt->name);
+ 
+-        switch (opt->type) {
+-            case AV_OPT_TYPE_FLAGS:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<flags>");
+-                break;
+-            case AV_OPT_TYPE_INT:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int>");
+-                break;
+-            case AV_OPT_TYPE_INT64:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<int64>");
+-                break;
+-            case AV_OPT_TYPE_UINT64:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<uint64>");
+-                break;
+-            case AV_OPT_TYPE_DOUBLE:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<double>");
+-                break;
+-            case AV_OPT_TYPE_FLOAT:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<float>");
+-                break;
+-            case AV_OPT_TYPE_STRING:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<string>");
+-                break;
+-            case AV_OPT_TYPE_RATIONAL:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<rational>");
+-                break;
+-            case AV_OPT_TYPE_BINARY:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<binary>");
+-                break;
+-            case AV_OPT_TYPE_DICT:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<dictionary>");
+-                break;
+-            case AV_OPT_TYPE_IMAGE_SIZE:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<image_size>");
+-                break;
+-            case AV_OPT_TYPE_VIDEO_RATE:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<video_rate>");
+-                break;
+-            case AV_OPT_TYPE_PIXEL_FMT:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<pix_fmt>");
+-                break;
+-            case AV_OPT_TYPE_SAMPLE_FMT:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<sample_fmt>");
+-                break;
+-            case AV_OPT_TYPE_DURATION:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<duration>");
+-                break;
+-            case AV_OPT_TYPE_COLOR:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<color>");
+-                break;
+-            case AV_OPT_TYPE_CHLAYOUT:
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-            case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<channel_layout>");
+-                break;
+-            case AV_OPT_TYPE_BOOL:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "<boolean>");
+-                break;
+-            case AV_OPT_TYPE_CONST:
+-                if (parent_type == AV_OPT_TYPE_INT)
+-                    av_log(av_log_obj, AV_LOG_INFO, "%-12"PRId64" ", opt->default_val.i64);
+-                else
+-                    av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
+-                break;
+-            default:
+-                av_log(av_log_obj, AV_LOG_INFO, "%-12s ", "");
+-                break;
+-        }
++        log_type(av_log_obj, opt, parent_type);
++
+         av_log(av_log_obj, AV_LOG_INFO, "%c%c%c%c%c%c%c%c%c%c%c",
+                (opt->flags & AV_OPT_FLAG_ENCODING_PARAM)  ? 'E' : '.',
+                (opt->flags & AV_OPT_FLAG_DECODING_PARAM)  ? 'D' : '.',
+                (opt->flags & AV_OPT_FLAG_FILTERING_PARAM) ? 'F' : '.',
+                (opt->flags & AV_OPT_FLAG_VIDEO_PARAM)     ? 'V' : '.',
+                (opt->flags & AV_OPT_FLAG_AUDIO_PARAM)     ? 'A' : '.',
+                (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM)  ? 'S' : '.',
+                (opt->flags & AV_OPT_FLAG_EXPORT)          ? 'X' : '.',
+@@ -1360,88 +1612,17 @@ FF_ENABLE_DEPRECATION_WARNINGS
+                     log_value(av_log_obj, AV_LOG_INFO, r->range[i]->value_max);
+                     av_log(av_log_obj, AV_LOG_INFO, ")");
+                 }
+                 break;
+             }
+             av_opt_freep_ranges(&r);
+         }
+ 
+-        if (opt->type != AV_OPT_TYPE_CONST  &&
+-            opt->type != AV_OPT_TYPE_BINARY &&
+-                !((opt->type == AV_OPT_TYPE_COLOR      ||
+-                   opt->type == AV_OPT_TYPE_IMAGE_SIZE ||
+-                   opt->type == AV_OPT_TYPE_STRING     ||
+-                   opt->type == AV_OPT_TYPE_DICT       ||
+-                   opt->type == AV_OPT_TYPE_CHLAYOUT   ||
+-                   opt->type == AV_OPT_TYPE_VIDEO_RATE) &&
+-                  !opt->default_val.str)) {
+-            av_log(av_log_obj, AV_LOG_INFO, " (default ");
+-            switch (opt->type) {
+-            case AV_OPT_TYPE_BOOL:
+-                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(get_bool_name(opt->default_val.i64), "invalid"));
+-                break;
+-            case AV_OPT_TYPE_FLAGS: {
+-                char *def_flags = get_opt_flags_string(obj, opt->unit, opt->default_val.i64);
+-                if (def_flags) {
+-                    av_log(av_log_obj, AV_LOG_INFO, "%s", def_flags);
+-                    av_freep(&def_flags);
+-                } else {
+-                    av_log(av_log_obj, AV_LOG_INFO, "%"PRIX64, opt->default_val.i64);
+-                }
+-                break;
+-            }
+-            case AV_OPT_TYPE_DURATION: {
+-                char buf[25];
+-                format_duration(buf, sizeof(buf), opt->default_val.i64);
+-                av_log(av_log_obj, AV_LOG_INFO, "%s", buf);
+-                break;
+-            }
+-            case AV_OPT_TYPE_INT:
+-            case AV_OPT_TYPE_UINT64:
+-            case AV_OPT_TYPE_INT64: {
+-                const char *def_const = get_opt_const_name(obj, opt->unit, opt->default_val.i64);
+-                if (def_const)
+-                    av_log(av_log_obj, AV_LOG_INFO, "%s", def_const);
+-                else
+-                    log_int_value(av_log_obj, AV_LOG_INFO, opt->default_val.i64);
+-                break;
+-            }
+-            case AV_OPT_TYPE_DOUBLE:
+-            case AV_OPT_TYPE_FLOAT:
+-                log_value(av_log_obj, AV_LOG_INFO, opt->default_val.dbl);
+-                break;
+-            case AV_OPT_TYPE_RATIONAL: {
+-                AVRational q = av_d2q(opt->default_val.dbl, INT_MAX);
+-                av_log(av_log_obj, AV_LOG_INFO, "%d/%d", q.num, q.den); }
+-                break;
+-            case AV_OPT_TYPE_PIXEL_FMT:
+-                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_pix_fmt_name(opt->default_val.i64), "none"));
+-                break;
+-            case AV_OPT_TYPE_SAMPLE_FMT:
+-                av_log(av_log_obj, AV_LOG_INFO, "%s", (char *)av_x_if_null(av_get_sample_fmt_name(opt->default_val.i64), "none"));
+-                break;
+-            case AV_OPT_TYPE_COLOR:
+-            case AV_OPT_TYPE_IMAGE_SIZE:
+-            case AV_OPT_TYPE_STRING:
+-            case AV_OPT_TYPE_DICT:
+-            case AV_OPT_TYPE_VIDEO_RATE:
+-            case AV_OPT_TYPE_CHLAYOUT:
+-                av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str);
+-                break;
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-            case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-                av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64);
+-                break;
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-            }
+-            av_log(av_log_obj, AV_LOG_INFO, ")");
+-        }
++        log_default(obj, av_log_obj, opt);
+ 
+         av_log(av_log_obj, AV_LOG_INFO, "\n");
+         if (opt->unit && opt->type != AV_OPT_TYPE_CONST)
+             opt_list(obj, av_log_obj, opt->unit, req_flags, rej_flags, opt->type);
+     }
+ }
+ 
+ int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags)
+@@ -1468,31 +1649,41 @@ void av_opt_set_defaults2(void *s, int m
+         void *dst = ((uint8_t*)s) + opt->offset;
+ 
+         if ((opt->flags & mask) != flags)
+             continue;
+ 
+         if (opt->flags & AV_OPT_FLAG_READONLY)
+             continue;
+ 
++        if (opt->type & AV_OPT_TYPE_FLAG_ARRAY) {
++            const AVOptionArrayDef *arr = opt->default_val.arr;
++            const char              sep = opt_array_sep(opt);
++
++            av_assert0(sep && sep != '\\' &&
++                       (sep < 'a' || sep > 'z') &&
++                       (sep < 'A' || sep > 'Z') &&
++                       (sep < '0' || sep > '9'));
++
++            if (arr && arr->def)
++                opt_set_array(s, s, opt, arr->def, dst);
++
++            continue;
++        }
++
+         switch (opt->type) {
+             case AV_OPT_TYPE_CONST:
+                 /* Nothing to be done here */
+                 break;
+             case AV_OPT_TYPE_BOOL:
+             case AV_OPT_TYPE_FLAGS:
+             case AV_OPT_TYPE_INT:
+             case AV_OPT_TYPE_INT64:
+             case AV_OPT_TYPE_UINT64:
+             case AV_OPT_TYPE_DURATION:
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-            case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+             case AV_OPT_TYPE_PIXEL_FMT:
+             case AV_OPT_TYPE_SAMPLE_FMT:
+                 write_number(s, opt, dst, 1, 1, opt->default_val.i64);
+                 break;
+             case AV_OPT_TYPE_DOUBLE:
+             case AV_OPT_TYPE_FLOAT: {
+                 double val;
+                 val = opt->default_val.dbl;
+@@ -1665,25 +1856,25 @@ int av_opt_get_key_value(const char **ro
+ }
+ 
+ int av_opt_set_from_string(void *ctx, const char *opts,
+                            const char *const *shorthand,
+                            const char *key_val_sep, const char *pairs_sep)
+ {
+     int ret, count = 0;
+     const char *dummy_shorthand = NULL;
+-    char *av_uninit(parsed_key), *av_uninit(value);
+     const char *key;
+ 
+     if (!opts)
+         return 0;
+     if (!shorthand)
+         shorthand = &dummy_shorthand;
+ 
+     while (*opts) {
++        char *parsed_key, *value;
+         ret = av_opt_get_key_value(&opts, key_val_sep, pairs_sep,
+                                    *shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
+                                    &parsed_key, &value);
+         if (ret < 0) {
+             if (ret == AVERROR(EINVAL))
+                 av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
+             else
+                 av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", opts,
+@@ -1715,33 +1906,22 @@ int av_opt_set_from_string(void *ctx, co
+     }
+     return count;
+ }
+ 
+ void av_opt_free(void *obj)
+ {
+     const AVOption *o = NULL;
+     while ((o = av_opt_next(obj, o))) {
+-        switch (o->type) {
+-        case AV_OPT_TYPE_STRING:
+-        case AV_OPT_TYPE_BINARY:
+-            av_freep((uint8_t *)obj + o->offset);
+-            break;
++        void *pitem = (uint8_t *)obj + o->offset;
+ 
+-        case AV_OPT_TYPE_DICT:
+-            av_dict_free((AVDictionary **)(((uint8_t *)obj) + o->offset));
+-            break;
+-
+-        case AV_OPT_TYPE_CHLAYOUT:
+-            av_channel_layout_uninit((AVChannelLayout *)(((uint8_t *)obj) + o->offset));
+-            break;
+-
+-        default:
+-            break;
+-        }
++        if (o->type & AV_OPT_TYPE_FLAG_ARRAY)
++            opt_free_array(o, pitem, opt_array_pcount(pitem));
++        else
++            opt_free_elem(o, pitem);
+     }
+ }
+ 
+ int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags)
+ {
+     const AVDictionaryEntry *t = NULL;
+     AVDictionary    *tmp = NULL;
+     int ret;
+@@ -1833,58 +2013,103 @@ const AVClass *av_opt_child_class_iterat
+     if (parent->child_class_iterate)
+         return parent->child_class_iterate(iter);
+     return NULL;
+ }
+ 
+ void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
+ {
+     const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
+-    if(!opt)
++
++    // no direct access to array-type options
++    if (!opt || (opt->type & AV_OPT_TYPE_FLAG_ARRAY))
+         return NULL;
+     return (uint8_t*)obj + opt->offset;
+ }
+ 
+-static int opt_size(enum AVOptionType type)
++static int opt_copy_elem(void *logctx, enum AVOptionType type,
++                         void *dst, const void *src)
+ {
+-    switch(type) {
+-    case AV_OPT_TYPE_BOOL:
+-    case AV_OPT_TYPE_INT:
+-    case AV_OPT_TYPE_FLAGS:
+-        return sizeof(int);
+-    case AV_OPT_TYPE_DURATION:
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+-    case AV_OPT_TYPE_INT64:
+-    case AV_OPT_TYPE_UINT64:
+-        return sizeof(int64_t);
+-    case AV_OPT_TYPE_DOUBLE:
+-        return sizeof(double);
+-    case AV_OPT_TYPE_FLOAT:
+-        return sizeof(float);
+-    case AV_OPT_TYPE_STRING:
+-        return sizeof(uint8_t*);
+-    case AV_OPT_TYPE_VIDEO_RATE:
+-    case AV_OPT_TYPE_RATIONAL:
+-        return sizeof(AVRational);
+-    case AV_OPT_TYPE_BINARY:
+-        return sizeof(uint8_t*) + sizeof(int);
+-    case AV_OPT_TYPE_IMAGE_SIZE:
+-        return sizeof(int[2]);
+-    case AV_OPT_TYPE_PIXEL_FMT:
+-        return sizeof(enum AVPixelFormat);
+-    case AV_OPT_TYPE_SAMPLE_FMT:
+-        return sizeof(enum AVSampleFormat);
+-    case AV_OPT_TYPE_COLOR:
+-        return 4;
++    if (type == AV_OPT_TYPE_STRING) {
++        const char *src_str = *(const char *const *)src;
++        char         **dstp =  (char **)dst;
++        if (*dstp != src_str)
++            av_freep(dstp);
++        if (src_str) {
++            *dstp = av_strdup(src_str);
++            if (!*dstp)
++                return AVERROR(ENOMEM);
++        }
++    } else if (type == AV_OPT_TYPE_BINARY) {
++        const uint8_t *const *src8 = (const uint8_t *const *)src;
++        uint8_t             **dst8 = (uint8_t **)dst;
++        int len = *(const int *)(src8 + 1);
++        if (*dst8 != *src8)
++            av_freep(dst8);
++        *dst8 = av_memdup(*src8, len);
++        if (len && !*dst8) {
++            *(int *)(dst8 + 1) = 0;
++            return AVERROR(ENOMEM);
++        }
++        *(int *)(dst8 + 1) = len;
++    } else if (type == AV_OPT_TYPE_CONST) {
++        // do nothing
++    } else if (type == AV_OPT_TYPE_DICT) {
++        const AVDictionary *sdict = *(const AVDictionary * const *)src;
++        AVDictionary     **ddictp = (AVDictionary **)dst;
++        if (sdict != *ddictp)
++            av_dict_free(ddictp);
++        *ddictp = NULL;
++        return av_dict_copy(ddictp, sdict, 0);
++    } else if (type == AV_OPT_TYPE_CHLAYOUT) {
++        if (dst != src)
++            return av_channel_layout_copy(dst, src);
++    } else if (opt_is_pod(type)) {
++        size_t size = opt_elem_size[type];
++        memcpy(dst, src, size);
++    } else {
++        av_log(logctx, AV_LOG_ERROR, "Unhandled option type: %d\n", type);
++        return AVERROR(EINVAL);
+     }
+-    return AVERROR(EINVAL);
++
++    return 0;
++}
++
++static int opt_copy_array(void *logctx, const AVOption *o,
++                          void **pdst, const void * const *psrc)
++{
++    unsigned nb_elems = *opt_array_pcount(psrc);
++    void         *dst = NULL;
++    int ret;
++
++    if (*pdst == *psrc) {
++        *pdst                   = NULL;
++        *opt_array_pcount(pdst) = 0;
++    }
++
++    opt_free_array(o, pdst, opt_array_pcount(pdst));
++
++    dst = av_calloc(nb_elems, opt_elem_size[TYPE_BASE(o->type)]);
++    if (!dst)
++        return AVERROR(ENOMEM);
++
++    for (unsigned i = 0; i < nb_elems; i++) {
++        ret = opt_copy_elem(logctx, TYPE_BASE(o->type),
++                            opt_array_pelem(o, dst, i),
++                            opt_array_pelem(o, *(void**)psrc, i));
++        if (ret < 0) {
++            opt_free_array(o, &dst, &nb_elems);
++            return ret;
++        }
++    }
++
++    *pdst                   = dst;
++    *opt_array_pcount(pdst) = nb_elems;
++
++    return 0;
+ }
+ 
+ int av_opt_copy(void *dst, const void *src)
+ {
+     const AVOption *o = NULL;
+     const AVClass *c;
+     int ret = 0;
+ 
+@@ -1893,57 +2118,22 @@ int av_opt_copy(void *dst, const void *s
+ 
+     c = *(AVClass **)src;
+     if (!c || c != *(AVClass **)dst)
+         return AVERROR(EINVAL);
+ 
+     while ((o = av_opt_next(src, o))) {
+         void *field_dst = (uint8_t *)dst + o->offset;
+         void *field_src = (uint8_t *)src + o->offset;
+-        uint8_t **field_dst8 = (uint8_t **)field_dst;
+-        uint8_t **field_src8 = (uint8_t **)field_src;
+ 
+-        if (o->type == AV_OPT_TYPE_STRING) {
+-            if (*field_dst8 != *field_src8)
+-                av_freep(field_dst8);
+-            *field_dst8 = av_strdup(*field_src8);
+-            if (*field_src8 && !*field_dst8)
+-                ret = AVERROR(ENOMEM);
+-        } else if (o->type == AV_OPT_TYPE_BINARY) {
+-            int len = *(int *)(field_src8 + 1);
+-            if (*field_dst8 != *field_src8)
+-                av_freep(field_dst8);
+-            *field_dst8 = av_memdup(*field_src8, len);
+-            if (len && !*field_dst8) {
+-                ret = AVERROR(ENOMEM);
+-                len = 0;
+-            }
+-            *(int *)(field_dst8 + 1) = len;
+-        } else if (o->type == AV_OPT_TYPE_CONST) {
+-            // do nothing
+-        } else if (o->type == AV_OPT_TYPE_DICT) {
+-            AVDictionary **sdict = (AVDictionary **) field_src;
+-            AVDictionary **ddict = (AVDictionary **) field_dst;
+-            int ret2;
+-            if (*sdict != *ddict)
+-                av_dict_free(ddict);
+-            *ddict = NULL;
+-            ret2 = av_dict_copy(ddict, *sdict, 0);
+-            if (ret2 < 0)
+-                ret = ret2;
+-        } else if (o->type == AV_OPT_TYPE_CHLAYOUT) {
+-            if (field_dst != field_src)
+-                ret = av_channel_layout_copy(field_dst, field_src);
+-        } else {
+-            int size = opt_size(o->type);
+-            if (size < 0)
+-                ret = size;
+-            else
+-                memcpy(field_dst, field_src, size);
+-        }
++        int err = (o->type & AV_OPT_TYPE_FLAG_ARRAY)                 ?
++                  opt_copy_array(dst, o,       field_dst, field_src) :
++                  opt_copy_elem (dst, o->type, field_dst, field_src);
++        if (err < 0)
++            ret = err;
+     }
+     return ret;
+ }
+ 
+ int av_opt_query_ranges(AVOptionRanges **ranges_arg, void *obj, const char *key, int flags)
+ {
+     int ret;
+     const AVClass *c = *(AVClass**)obj;
+@@ -1990,21 +2180,16 @@ int av_opt_query_ranges_default(AVOption
+     case AV_OPT_TYPE_INT64:
+     case AV_OPT_TYPE_UINT64:
+     case AV_OPT_TYPE_PIXEL_FMT:
+     case AV_OPT_TYPE_SAMPLE_FMT:
+     case AV_OPT_TYPE_FLOAT:
+     case AV_OPT_TYPE_DOUBLE:
+     case AV_OPT_TYPE_DURATION:
+     case AV_OPT_TYPE_COLOR:
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+         break;
+     case AV_OPT_TYPE_STRING:
+         range->component_min = 0;
+         range->component_max = 0x10FFFF; // max unicode value
+         range->value_min = -1;
+         range->value_max = INT_MAX;
+         break;
+     case AV_OPT_TYPE_RATIONAL:
+@@ -2054,41 +2239,53 @@ void av_opt_freep_ranges(AVOptionRanges 
+     }
+     av_freep(&ranges->range);
+     av_freep(rangesp);
+ }
+ 
+ int av_opt_is_set_to_default(void *obj, const AVOption *o)
+ {
+     int64_t i64;
+-    double d, d2;
+-    float f;
++    double d;
+     AVRational q;
+     int ret, w, h;
+     char *str;
+     void *dst;
+ 
+     if (!o || !obj)
+         return AVERROR(EINVAL);
+ 
+     dst = ((uint8_t*)obj) + o->offset;
+ 
++    if (o->type & AV_OPT_TYPE_FLAG_ARRAY) {
++        const char *def = o->default_val.arr ? o->default_val.arr->def : NULL;
++        uint8_t *val;
++
++        ret = opt_get_array(o, dst, &val);
++        if (ret < 0)
++            return ret;
++
++        if (!!val != !!def)
++            ret = 0;
++        else if (val)
++            ret = !strcmp(val, def);
++
++        av_freep(&val);
++
++        return ret;
++    }
++
+     switch (o->type) {
+     case AV_OPT_TYPE_CONST:
+         return 1;
+     case AV_OPT_TYPE_BOOL:
+     case AV_OPT_TYPE_FLAGS:
+     case AV_OPT_TYPE_PIXEL_FMT:
+     case AV_OPT_TYPE_SAMPLE_FMT:
+     case AV_OPT_TYPE_INT:
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-FF_DISABLE_DEPRECATION_WARNINGS
+-    case AV_OPT_TYPE_CHANNEL_LAYOUT:
+-FF_ENABLE_DEPRECATION_WARNINGS
+-#endif
+     case AV_OPT_TYPE_DURATION:
+     case AV_OPT_TYPE_INT64:
+     case AV_OPT_TYPE_UINT64:
+         read_number(o, dst, NULL, NULL, &i64);
+         return o->default_val.i64 == i64;
+     case AV_OPT_TYPE_CHLAYOUT: {
+         AVChannelLayout ch_layout = { 0 };
+         if (o->default_val.str) {
+@@ -2100,23 +2297,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
+     case AV_OPT_TYPE_STRING:
+         str = *(char **)dst;
+         if (str == o->default_val.str) //2 NULLs
+             return 1;
+         if (!str || !o->default_val.str) //1 NULL
+             return 0;
+         return !strcmp(str, o->default_val.str);
+     case AV_OPT_TYPE_DOUBLE:
+-        read_number(o, dst, &d, NULL, NULL);
++        d = *(double *)dst;
+         return o->default_val.dbl == d;
+     case AV_OPT_TYPE_FLOAT:
+-        read_number(o, dst, &d, NULL, NULL);
+-        f = o->default_val.dbl;
+-        d2 = f;
+-        return d2 == d;
++        d = *(float *)dst;
++        return (float)o->default_val.dbl == d;
+     case AV_OPT_TYPE_RATIONAL:
+         q = av_d2q(o->default_val.dbl, INT_MAX);
+         return !av_cmp_q(*(AVRational*)dst, q);
+     case AV_OPT_TYPE_BINARY: {
+         struct {
+             uint8_t *data;
+             int size;
+         } tmp = {0};
+diff --git a/media/ffvpx/libavutil/opt.h b/media/ffvpx/libavutil/opt.h
+--- a/media/ffvpx/libavutil/opt.h
++++ b/media/ffvpx/libavutil/opt.h
+@@ -38,16 +38,26 @@
+ /**
+  * @defgroup avoptions AVOptions
+  * @ingroup lavu_data
+  * @{
+  * AVOptions provide a generic system to declare options on arbitrary structs
+  * ("objects"). An option can have a help text, a type and a range of possible
+  * values. Options may then be enumerated, read and written to.
+  *
++ * There are two modes of access to members of AVOption and its child structs.
++ * One is called 'native access', and refers to access from the code that
++ * declares the AVOption in question.  The other is 'foreign access', and refers
++ * to access from other code.
++ *
++ * Certain struct members in this header are documented as 'native access only'
++ * or similar - it means that only the code that declared the AVOption in
++ * question is allowed to access the field. This allows us to extend the
++ * semantics of those fields without breaking API compatibility.
++ *
+  * @section avoptions_implement Implementing AVOptions
+  * This section describes how to add AVOptions capabilities to a struct.
+  *
+  * All AVOptions-related information is stored in an AVClass. Therefore
+  * the first member of the struct should be a pointer to an AVClass describing it.
+  * The option field of the AVClass must be set to a NULL-terminated static array
+  * of AVOptions. Each AVOption must have a non-empty name, a type, a default
+  * value and for number-type AVOptions also a range of allowed values. It must
+@@ -216,93 +226,172 @@
+  * AVDictionary and call av_opt_set_dict() on it. A specific case of this
+  * are the format/codec open functions in lavf/lavc which take a dictionary
+  * filled with option as a parameter. This makes it possible to set some options
+  * that cannot be set otherwise, since e.g. the input file format is not known
+  * before the file is actually opened.
+  */
+ 
+ enum AVOptionType{
+-    AV_OPT_TYPE_FLAGS,
++    AV_OPT_TYPE_FLAGS = 1,
+     AV_OPT_TYPE_INT,
+     AV_OPT_TYPE_INT64,
+     AV_OPT_TYPE_DOUBLE,
+     AV_OPT_TYPE_FLOAT,
+     AV_OPT_TYPE_STRING,
+     AV_OPT_TYPE_RATIONAL,
+     AV_OPT_TYPE_BINARY,  ///< offset must point to a pointer immediately followed by an int for the length
+     AV_OPT_TYPE_DICT,
+     AV_OPT_TYPE_UINT64,
+     AV_OPT_TYPE_CONST,
+     AV_OPT_TYPE_IMAGE_SIZE, ///< offset must point to two consecutive integers
+     AV_OPT_TYPE_PIXEL_FMT,
+     AV_OPT_TYPE_SAMPLE_FMT,
+     AV_OPT_TYPE_VIDEO_RATE, ///< offset must point to AVRational
+     AV_OPT_TYPE_DURATION,
+     AV_OPT_TYPE_COLOR,
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-    AV_OPT_TYPE_CHANNEL_LAYOUT,
+-#endif
+     AV_OPT_TYPE_BOOL,
+     AV_OPT_TYPE_CHLAYOUT,
++
++    /**
++     * May be combined with another regular option type to declare an array
++     * option.
++     *
++     * For array options, @ref AVOption.offset should refer to a pointer
++     * corresponding to the option type. The pointer should be immediately
++     * followed by an unsigned int that will store the number of elements in the
++     * array.
++     */
++    AV_OPT_TYPE_FLAG_ARRAY = (1 << 16),
+ };
+ 
+ /**
++ * A generic parameter which can be set by the user for muxing or encoding.
++ */
++#define AV_OPT_FLAG_ENCODING_PARAM  (1 << 0)
++/**
++ * A generic parameter which can be set by the user for demuxing or decoding.
++ */
++#define AV_OPT_FLAG_DECODING_PARAM  (1 << 1)
++#define AV_OPT_FLAG_AUDIO_PARAM     (1 << 3)
++#define AV_OPT_FLAG_VIDEO_PARAM     (1 << 4)
++#define AV_OPT_FLAG_SUBTITLE_PARAM  (1 << 5)
++/**
++ * The option is intended for exporting values to the caller.
++ */
++#define AV_OPT_FLAG_EXPORT          (1 << 6)
++/**
++ * The option may not be set through the AVOptions API, only read.
++ * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set.
++ */
++#define AV_OPT_FLAG_READONLY        (1 << 7)
++/**
++ * A generic parameter which can be set by the user for bit stream filtering.
++ */
++#define AV_OPT_FLAG_BSF_PARAM       (1 << 8)
++
++/**
++ * A generic parameter which can be set by the user at runtime.
++ */
++#define AV_OPT_FLAG_RUNTIME_PARAM   (1 << 15)
++/**
++ * A generic parameter which can be set by the user for filtering.
++ */
++#define AV_OPT_FLAG_FILTERING_PARAM (1 << 16)
++/**
++ * Set if option is deprecated, users should refer to AVOption.help text for
++ * more information.
++ */
++#define AV_OPT_FLAG_DEPRECATED      (1 << 17)
++/**
++ * Set if option constants can also reside in child objects.
++ */
++#define AV_OPT_FLAG_CHILD_CONSTS    (1 << 18)
++
++/**
++ * May be set as default_val for AV_OPT_TYPE_FLAG_ARRAY options.
++ */
++typedef struct AVOptionArrayDef {
++    /**
++     * Native access only.
++     *
++     * Default value of the option, as would be serialized by av_opt_get() (i.e.
++     * using the value of sep as the separator).
++     */
++    const char         *def;
++
++    /**
++     * Minimum number of elements in the array. When this field is non-zero, def
++     * must be non-NULL and contain at least this number of elements.
++     */
++    unsigned            size_min;
++    /**
++     * Maximum number of elements in the array, 0 when unlimited.
++     */
++    unsigned            size_max;
++
++    /**
++     * Separator between array elements in string representations of this
++     * option, used by av_opt_set() and av_opt_get(). It must be a printable
++     * ASCII character, excluding alphanumeric and the backslash. A comma is
++     * used when sep=0.
++     *
++     * The separator and the backslash must be backslash-escaped in order to
++     * appear in string representations of the option value.
++     */
++    char                sep;
++} AVOptionArrayDef;
++
++/**
+  * AVOption
+  */
+ typedef struct AVOption {
+     const char *name;
+ 
+     /**
+      * short English help text
+      * @todo What about other languages?
+      */
+     const char *help;
+ 
+     /**
++     * Native access only.
++     *
+      * The offset relative to the context structure where the option
+      * value is stored. It should be 0 for named constants.
+      */
+     int offset;
+     enum AVOptionType type;
+ 
+     /**
++     * Native access only, except when documented otherwise.
+      * the default value for scalar options
+      */
+     union {
+         int64_t i64;
+         double dbl;
+         const char *str;
+         /* TODO those are unused now */
+         AVRational q;
++
++        /**
++         * Used for AV_OPT_TYPE_FLAG_ARRAY options. May be NULL.
++         *
++         * Foreign access to some members allowed, as noted in AVOptionArrayDef
++         * documentation.
++         */
++        const AVOptionArrayDef *arr;
+     } default_val;
+     double min;                 ///< minimum valid value for the option
+     double max;                 ///< maximum valid value for the option
+ 
++    /**
++     * A combination of AV_OPT_FLAG_*.
++     */
+     int flags;
+-#define AV_OPT_FLAG_ENCODING_PARAM  1   ///< a generic parameter which can be set by the user for muxing or encoding
+-#define AV_OPT_FLAG_DECODING_PARAM  2   ///< a generic parameter which can be set by the user for demuxing or decoding
+-#define AV_OPT_FLAG_AUDIO_PARAM     8
+-#define AV_OPT_FLAG_VIDEO_PARAM     16
+-#define AV_OPT_FLAG_SUBTITLE_PARAM  32
+-/**
+- * The option is intended for exporting values to the caller.
+- */
+-#define AV_OPT_FLAG_EXPORT          64
+-/**
+- * The option may not be set through the AVOptions API, only read.
+- * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set.
+- */
+-#define AV_OPT_FLAG_READONLY        128
+-#define AV_OPT_FLAG_BSF_PARAM       (1<<8) ///< a generic parameter which can be set by the user for bit stream filtering
+-#define AV_OPT_FLAG_RUNTIME_PARAM   (1<<15) ///< a generic parameter which can be set by the user at runtime
+-#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
+-#define AV_OPT_FLAG_DEPRECATED      (1<<17) ///< set if option is deprecated, users should refer to AVOption.help text for more information
+-#define AV_OPT_FLAG_CHILD_CONSTS    (1<<18) ///< set if option constants can also reside in child objects
+-//FIXME think about enc-audio, ... style flags
+ 
+     /**
+      * The logical unit to which the option belongs. Non-constant
+      * options and corresponding named constants share the same
+      * unit. May be NULL.
+      */
+     const char *unit;
+ } AVOption;
+@@ -371,25 +460,19 @@ typedef struct AVOptionRanges {
+     int nb_ranges;
+     /**
+      * Number of componentes.
+      */
+     int nb_components;
+ } AVOptionRanges;
+ 
+ /**
+- * Show the obj options.
+- *
+- * @param req_flags requested flags for the options to show. Show only the
+- * options for which it is opt->flags & req_flags.
+- * @param rej_flags rejected flags for the options to show. Show only the
+- * options for which it is !(opt->flags & req_flags).
+- * @param av_log_obj log context to use for showing the options
++ * @defgroup opt_mng AVOption (un)initialization and inspection.
++ * @{
+  */
+-int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags);
+ 
+ /**
+  * Set the values of all AVOption fields to their default values.
+  *
+  * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass)
+  */
+ void av_opt_set_defaults(void *s);
+ 
+@@ -400,170 +483,46 @@ void av_opt_set_defaults(void *s);
+  *
+  * @param s an AVOption-enabled struct (its first member must be a pointer to AVClass)
+  * @param mask combination of AV_OPT_FLAG_*
+  * @param flags combination of AV_OPT_FLAG_*
+  */
+ void av_opt_set_defaults2(void *s, int mask, int flags);
+ 
+ /**
+- * Parse the key/value pairs list in opts. For each key/value pair
+- * found, stores the value in the field in ctx that is named like the
+- * key. ctx must be an AVClass context, storing is done using
+- * AVOptions.
+- *
+- * @param opts options string to parse, may be NULL
+- * @param key_val_sep a 0-terminated list of characters used to
+- * separate key from value
+- * @param pairs_sep a 0-terminated list of characters used to separate
+- * two pairs from each other
+- * @return the number of successfully set key/value pairs, or a negative
+- * value corresponding to an AVERROR code in case of error:
+- * AVERROR(EINVAL) if opts cannot be parsed,
+- * the error code issued by av_opt_set() if a key/value pair
+- * cannot be set
+- */
+-int av_set_options_string(void *ctx, const char *opts,
+-                          const char *key_val_sep, const char *pairs_sep);
+-
+-/**
+- * Parse the key-value pairs list in opts. For each key=value pair found,
+- * set the value of the corresponding option in ctx.
+- *
+- * @param ctx          the AVClass object to set options on
+- * @param opts         the options string, key-value pairs separated by a
+- *                     delimiter
+- * @param shorthand    a NULL-terminated array of options names for shorthand
+- *                     notation: if the first field in opts has no key part,
+- *                     the key is taken from the first element of shorthand;
+- *                     then again for the second, etc., until either opts is
+- *                     finished, shorthand is finished or a named option is
+- *                     found; after that, all options must be named
+- * @param key_val_sep  a 0-terminated list of characters used to separate
+- *                     key from value, for example '='
+- * @param pairs_sep    a 0-terminated list of characters used to separate
+- *                     two pairs from each other, for example ':' or ','
+- * @return  the number of successfully set key=value pairs, or a negative
+- *          value corresponding to an AVERROR code in case of error:
+- *          AVERROR(EINVAL) if opts cannot be parsed,
+- *          the error code issued by av_set_string3() if a key/value pair
+- *          cannot be set
+- *
+- * Options names must use only the following characters: a-z A-Z 0-9 - . / _
+- * Separators must use characters distinct from option names and from each
+- * other.
+- */
+-int av_opt_set_from_string(void *ctx, const char *opts,
+-                           const char *const *shorthand,
+-                           const char *key_val_sep, const char *pairs_sep);
+-/**
+  * Free all allocated objects in obj.
+  */
+ void av_opt_free(void *obj);
+ 
+ /**
+- * Check whether a particular flag is set in a flags field.
+- *
+- * @param field_name the name of the flag field option
+- * @param flag_name the name of the flag to check
+- * @return non-zero if the flag is set, zero if the flag isn't set,
+- *         isn't of the right type, or the flags field doesn't exist.
+- */
+-int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name);
+-
+-/**
+- * Set all the options from a given dictionary on an object.
+- *
+- * @param obj a struct whose first element is a pointer to AVClass
+- * @param options options to process. This dictionary will be freed and replaced
+- *                by a new one containing all options not found in obj.
+- *                Of course this new dictionary needs to be freed by caller
+- *                with av_dict_free().
+- *
+- * @return 0 on success, a negative AVERROR if some option was found in obj,
+- *         but could not be set.
++ * Iterate over all AVOptions belonging to obj.
+  *
+- * @see av_dict_copy()
++ * @param obj an AVOptions-enabled struct or a double pointer to an
++ *            AVClass describing it.
++ * @param prev result of the previous call to av_opt_next() on this object
++ *             or NULL
++ * @return next AVOption or NULL
+  */
+-int av_opt_set_dict(void *obj, struct AVDictionary **options);
+-
+-
+-/**
+- * Set all the options from a given dictionary on an object.
+- *
+- * @param obj a struct whose first element is a pointer to AVClass
+- * @param options options to process. This dictionary will be freed and replaced
+- *                by a new one containing all options not found in obj.
+- *                Of course this new dictionary needs to be freed by caller
+- *                with av_dict_free().
+- * @param search_flags A combination of AV_OPT_SEARCH_*.
+- *
+- * @return 0 on success, a negative AVERROR if some option was found in obj,
+- *         but could not be set.
+- *
+- * @see av_dict_copy()
+- */
+-int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags);
++const AVOption *av_opt_next(const void *obj, const AVOption *prev);
+ 
+ /**
+- * Extract a key-value pair from the beginning of a string.
+- *
+- * @param ropts        pointer to the options string, will be updated to
+- *                     point to the rest of the string (one of the pairs_sep
+- *                     or the final NUL)
+- * @param key_val_sep  a 0-terminated list of characters used to separate
+- *                     key from value, for example '='
+- * @param pairs_sep    a 0-terminated list of characters used to separate
+- *                     two pairs from each other, for example ':' or ','
+- * @param flags        flags; see the AV_OPT_FLAG_* values below
+- * @param rkey         parsed key; must be freed using av_free()
+- * @param rval         parsed value; must be freed using av_free()
++ * Iterate over AVOptions-enabled children of obj.
+  *
+- * @return  >=0 for success, or a negative value corresponding to an
+- *          AVERROR code in case of error; in particular:
+- *          AVERROR(EINVAL) if no key is present
+- *
++ * @param prev result of a previous call to this function or NULL
++ * @return next AVOptions-enabled child or NULL
+  */
+-int av_opt_get_key_value(const char **ropts,
+-                         const char *key_val_sep, const char *pairs_sep,
+-                         unsigned flags,
+-                         char **rkey, char **rval);
+-
+-enum {
+-
+-    /**
+-     * Accept to parse a value without a key; the key will then be returned
+-     * as NULL.
+-     */
+-    AV_OPT_FLAG_IMPLICIT_KEY = 1,
+-};
++void *av_opt_child_next(void *obj, void *prev);
+ 
+ /**
+- * @defgroup opt_eval_funcs Evaluating option strings
+- * @{
+- * This group of functions can be used to evaluate option strings
+- * and get numbers out of them. They do the same thing as av_opt_set(),
+- * except the result is written into the caller-supplied pointer.
+- *
+- * @param obj a struct whose first element is a pointer to AVClass.
+- * @param o an option for which the string is to be evaluated.
+- * @param val string to be evaluated.
+- * @param *_out value of the string will be written here.
++ * Iterate over potential AVOptions-enabled children of parent.
+  *
+- * @return 0 on success, a negative number on failure.
++ * @param iter a pointer where iteration state is stored.
++ * @return AVClass corresponding to next potential child or NULL
+  */
+-int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int        *flags_out);
+-int av_opt_eval_int   (void *obj, const AVOption *o, const char *val, int        *int_out);
+-int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t    *int64_out);
+-int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float      *float_out);
+-int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double     *double_out);
+-int av_opt_eval_q     (void *obj, const AVOption *o, const char *val, AVRational *q_out);
+-/**
+- * @}
+- */
++const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter);
+ 
+ #define AV_OPT_SEARCH_CHILDREN   (1 << 0) /**< Search in possible children of the
+                                                given object first. */
+ /**
+  *  The obj passed to av_opt_find() is fake -- only a double pointer to AVClass
+  *  instead of a required pointer to a struct containing AVClass. This is
+  *  useful for searching for options without needing to allocate the corresponding
+  *  object.
+@@ -628,41 +587,171 @@ const AVOption *av_opt_find(void *obj, c
+  *
+  * @return A pointer to the option found, or NULL if no option
+  *         was found.
+  */
+ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
+                              int opt_flags, int search_flags, void **target_obj);
+ 
+ /**
+- * Iterate over all AVOptions belonging to obj.
++ * Show the obj options.
++ *
++ * @param req_flags requested flags for the options to show. Show only the
++ * options for which it is opt->flags & req_flags.
++ * @param rej_flags rejected flags for the options to show. Show only the
++ * options for which it is !(opt->flags & req_flags).
++ * @param av_log_obj log context to use for showing the options
++ */
++int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags);
++
++/**
++ * Extract a key-value pair from the beginning of a string.
++ *
++ * @param ropts        pointer to the options string, will be updated to
++ *                     point to the rest of the string (one of the pairs_sep
++ *                     or the final NUL)
++ * @param key_val_sep  a 0-terminated list of characters used to separate
++ *                     key from value, for example '='
++ * @param pairs_sep    a 0-terminated list of characters used to separate
++ *                     two pairs from each other, for example ':' or ','
++ * @param flags        flags; see the AV_OPT_FLAG_* values below
++ * @param rkey         parsed key; must be freed using av_free()
++ * @param rval         parsed value; must be freed using av_free()
++ *
++ * @return  >=0 for success, or a negative value corresponding to an
++ *          AVERROR code in case of error; in particular:
++ *          AVERROR(EINVAL) if no key is present
+  *
+- * @param obj an AVOptions-enabled struct or a double pointer to an
+- *            AVClass describing it.
+- * @param prev result of the previous call to av_opt_next() on this object
+- *             or NULL
+- * @return next AVOption or NULL
++ */
++int av_opt_get_key_value(const char **ropts,
++                         const char *key_val_sep, const char *pairs_sep,
++                         unsigned flags,
++                         char **rkey, char **rval);
++
++enum {
++
++    /**
++     * Accept to parse a value without a key; the key will then be returned
++     * as NULL.
++     */
++    AV_OPT_FLAG_IMPLICIT_KEY = 1,
++};
++
++/**
++ * @}
+  */
+-const AVOption *av_opt_next(const void *obj, const AVOption *prev);
++
++/**
++ * @defgroup opt_write Setting and modifying option values
++ * @{
++ */
++
++/**
++ * Parse the key/value pairs list in opts. For each key/value pair
++ * found, stores the value in the field in ctx that is named like the
++ * key. ctx must be an AVClass context, storing is done using
++ * AVOptions.
++ *
++ * @param opts options string to parse, may be NULL
++ * @param key_val_sep a 0-terminated list of characters used to
++ * separate key from value
++ * @param pairs_sep a 0-terminated list of characters used to separate
++ * two pairs from each other
++ * @return the number of successfully set key/value pairs, or a negative
++ * value corresponding to an AVERROR code in case of error:
++ * AVERROR(EINVAL) if opts cannot be parsed,
++ * the error code issued by av_opt_set() if a key/value pair
++ * cannot be set
++ */
++int av_set_options_string(void *ctx, const char *opts,
++                          const char *key_val_sep, const char *pairs_sep);
+ 
+ /**
+- * Iterate over AVOptions-enabled children of obj.
++ * Parse the key-value pairs list in opts. For each key=value pair found,
++ * set the value of the corresponding option in ctx.
+  *
+- * @param prev result of a previous call to this function or NULL
+- * @return next AVOptions-enabled child or NULL
++ * @param ctx          the AVClass object to set options on
++ * @param opts         the options string, key-value pairs separated by a
++ *                     delimiter
++ * @param shorthand    a NULL-terminated array of options names for shorthand
++ *                     notation: if the first field in opts has no key part,
++ *                     the key is taken from the first element of shorthand;
++ *                     then again for the second, etc., until either opts is
++ *                     finished, shorthand is finished or a named option is
++ *                     found; after that, all options must be named
++ * @param key_val_sep  a 0-terminated list of characters used to separate
++ *                     key from value, for example '='
++ * @param pairs_sep    a 0-terminated list of characters used to separate
++ *                     two pairs from each other, for example ':' or ','
++ * @return  the number of successfully set key=value pairs, or a negative
++ *          value corresponding to an AVERROR code in case of error:
++ *          AVERROR(EINVAL) if opts cannot be parsed,
++ *          the error code issued by av_set_string3() if a key/value pair
++ *          cannot be set
++ *
++ * Options names must use only the following characters: a-z A-Z 0-9 - . / _
++ * Separators must use characters distinct from option names and from each
++ * other.
+  */
+-void *av_opt_child_next(void *obj, void *prev);
++int av_opt_set_from_string(void *ctx, const char *opts,
++                           const char *const *shorthand,
++                           const char *key_val_sep, const char *pairs_sep);
+ 
+ /**
+- * Iterate over potential AVOptions-enabled children of parent.
++ * Set all the options from a given dictionary on an object.
++ *
++ * @param obj a struct whose first element is a pointer to AVClass
++ * @param options options to process. This dictionary will be freed and replaced
++ *                by a new one containing all options not found in obj.
++ *                Of course this new dictionary needs to be freed by caller
++ *                with av_dict_free().
++ *
++ * @return 0 on success, a negative AVERROR if some option was found in obj,
++ *         but could not be set.
++ *
++ * @see av_dict_copy()
++ */
++int av_opt_set_dict(void *obj, struct AVDictionary **options);
++
++
++/**
++ * Set all the options from a given dictionary on an object.
++ *
++ * @param obj a struct whose first element is a pointer to AVClass
++ * @param options options to process. This dictionary will be freed and replaced
++ *                by a new one containing all options not found in obj.
++ *                Of course this new dictionary needs to be freed by caller
++ *                with av_dict_free().
++ * @param search_flags A combination of AV_OPT_SEARCH_*.
+  *
+- * @param iter a pointer where iteration state is stored.
+- * @return AVClass corresponding to next potential child or NULL
++ * @return 0 on success, a negative AVERROR if some option was found in obj,
++ *         but could not be set.
++ *
++ * @see av_dict_copy()
+  */
+-const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter);
++int av_opt_set_dict2(void *obj, struct AVDictionary **options, int search_flags);
++
++/**
++ * Copy options from src object into dest object.
++ *
++ * The underlying AVClass of both src and dest must coincide. The guarantee
++ * below does not apply if this is not fulfilled.
++ *
++ * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object.
++ * Original memory allocated for such options is freed unless both src and dest options points to the same memory.
++ *
++ * Even on error it is guaranteed that allocated options from src and dest
++ * no longer alias each other afterwards; in particular calling av_opt_free()
++ * on both src and dest is safe afterwards if dest has been memdup'ed from src.
++ *
++ * @param dest Object to copy from
++ * @param src  Object to copy into
++ * @return 0 on success, negative on error
++ */
++int av_opt_copy(void *dest, const void *src);
+ 
+ /**
+  * @defgroup opt_set_funcs Option setting functions
+  * @{
+  * Those functions set the field of obj with the given name to value.
+  *
+  * @param[in] obj A struct whose first element is a pointer to an AVClass.
+  * @param[in] name the name of the field to set
+@@ -692,20 +781,16 @@ int av_opt_set         (void *obj, const
+ int av_opt_set_int     (void *obj, const char *name, int64_t     val, int search_flags);
+ int av_opt_set_double  (void *obj, const char *name, double      val, int search_flags);
+ int av_opt_set_q       (void *obj, const char *name, AVRational  val, int search_flags);
+ int av_opt_set_bin     (void *obj, const char *name, const uint8_t *val, int size, int search_flags);
+ int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_flags);
+ int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);
+ int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags);
+ int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags);
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-attribute_deprecated
+-int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);
+-#endif
+ int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *layout, int search_flags);
+ /**
+  * @note Any old dictionary present is discarded and replaced with a copy of the new one. The
+  * caller still owns val is and responsible for freeing it.
+  */
+ int av_opt_set_dict_val(void *obj, const char *name, const AVDictionary *val, int search_flags);
+ 
+ /**
+@@ -721,16 +806,22 @@ int av_opt_set_dict_val(void *obj, const
+ #define av_opt_set_int_list(obj, name, val, term, flags) \
+     (av_int_list_length(val, term) > INT_MAX / sizeof(*(val)) ? \
+      AVERROR(EINVAL) : \
+      av_opt_set_bin(obj, name, (const uint8_t *)(val), \
+                     av_int_list_length(val, term) * sizeof(*(val)), flags))
+ 
+ /**
+  * @}
++ * @}
++ */
++
++/**
++ * @defgroup opt_read Reading option values
++ * @{
+  */
+ 
+ /**
+  * @defgroup opt_get_funcs Option getting functions
+  * @{
+  * Those functions get a value of the option with the given name from an object.
+  *
+  * @param[in] obj a struct whose first element is a pointer to an AVClass.
+@@ -751,95 +842,61 @@ int av_opt_set_dict_val(void *obj, const
+ int av_opt_get         (void *obj, const char *name, int search_flags, uint8_t   **out_val);
+ int av_opt_get_int     (void *obj, const char *name, int search_flags, int64_t    *out_val);
+ int av_opt_get_double  (void *obj, const char *name, int search_flags, double     *out_val);
+ int av_opt_get_q       (void *obj, const char *name, int search_flags, AVRational *out_val);
+ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_out, int *h_out);
+ int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt);
+ int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt);
+ int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val);
+-#if FF_API_OLD_CHANNEL_LAYOUT
+-attribute_deprecated
+-int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout);
+-#endif
+ int av_opt_get_chlayout(void *obj, const char *name, int search_flags, AVChannelLayout *layout);
+ /**
+  * @param[out] out_val The returned dictionary is a copy of the actual value and must
+  * be freed with av_dict_free() by the caller
+  */
+ int av_opt_get_dict_val(void *obj, const char *name, int search_flags, AVDictionary **out_val);
+ /**
+  * @}
+  */
++
++/**
++ * @defgroup opt_eval_funcs Evaluating option strings
++ * @{
++ * This group of functions can be used to evaluate option strings
++ * and get numbers out of them. They do the same thing as av_opt_set(),
++ * except the result is written into the caller-supplied pointer.
++ *
++ * @param obj a struct whose first element is a pointer to AVClass.
++ * @param o an option for which the string is to be evaluated.
++ * @param val string to be evaluated.
++ * @param *_out value of the string will be written here.
++ *
++ * @return 0 on success, a negative number on failure.
++ */
++int av_opt_eval_flags (void *obj, const AVOption *o, const char *val, int        *flags_out);
++int av_opt_eval_int   (void *obj, const AVOption *o, const char *val, int        *int_out);
++int av_opt_eval_int64 (void *obj, const AVOption *o, const char *val, int64_t    *int64_out);
++int av_opt_eval_float (void *obj, const AVOption *o, const char *val, float      *float_out);
++int av_opt_eval_double(void *obj, const AVOption *o, const char *val, double     *double_out);
++int av_opt_eval_q     (void *obj, const AVOption *o, const char *val, AVRational *q_out);
++/**
++ * @}
++ */
++
+ /**
+  * Gets a pointer to the requested field in a struct.
+  * This function allows accessing a struct even when its fields are moved or
+  * renamed since the application making the access has been compiled,
+  *
+  * @returns a pointer to the field, it can be cast to the correct type and read
+  *          or written to.
+  */
+ void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
+ 
+ /**
+- * Free an AVOptionRanges struct and set it to NULL.
+- */
+-void av_opt_freep_ranges(AVOptionRanges **ranges);
+-
+-/**
+- * Get a list of allowed ranges for the given option.
+- *
+- * The returned list may depend on other fields in obj like for example profile.
+- *
+- * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+- *              AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+- *              AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
+- *
+- * The result must be freed with av_opt_freep_ranges.
+- *
+- * @return number of compontents returned on success, a negative errro code otherwise
+- */
+-int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
+-
+-/**
+- * Copy options from src object into dest object.
+- *
+- * The underlying AVClass of both src and dest must coincide. The guarantee
+- * below does not apply if this is not fulfilled.
+- *
+- * Options that require memory allocation (e.g. string or binary) are malloc'ed in dest object.
+- * Original memory allocated for such options is freed unless both src and dest options points to the same memory.
+- *
+- * Even on error it is guaranteed that allocated options from src and dest
+- * no longer alias each other afterwards; in particular calling av_opt_free()
+- * on both src and dest is safe afterwards if dest has been memdup'ed from src.
+- *
+- * @param dest Object to copy from
+- * @param src  Object to copy into
+- * @return 0 on success, negative on error
+- */
+-int av_opt_copy(void *dest, const void *src);
+-
+-/**
+- * Get a default list of allowed ranges for the given option.
+- *
+- * This list is constructed without using the AVClass.query_ranges() callback
+- * and can be used as fallback from within the callback.
+- *
+- * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
+- *              AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
+- *              AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
+- *
+- * The result must be freed with av_opt_free_ranges.
+- *
+- * @return number of compontents returned on success, a negative errro code otherwise
+- */
+-int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
+-
+-/**
+  * Check if given option is set to its default value.
+  *
+  * Options o must belong to the obj. This function must not be called to check child's options state.
+  * @see av_opt_is_set_to_default_by_name().
+  *
+  * @param obj  AVClass object to check option on
+  * @param o    option to be checked
+  * @return     >0 when option is set to its default,
+@@ -855,16 +912,25 @@ int av_opt_is_set_to_default(void *obj, 
+  * @param name         option name
+  * @param search_flags combination of AV_OPT_SEARCH_*
+  * @return             >0 when option is set to its default,
+  *                     0 when option is not set its default,
+  *                     <0 on error
+  */
+ int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags);
+ 
++/**
++ * Check whether a particular flag is set in a flags field.
++ *
++ * @param field_name the name of the flag field option
++ * @param flag_name the name of the flag to check
++ * @return non-zero if the flag is set, zero if the flag isn't set,
++ *         isn't of the right type, or the flags field doesn't exist.
++ */
++int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name);
+ 
+ #define AV_OPT_SERIALIZE_SKIP_DEFAULTS              0x00000001  ///< Serialize options that are not set to default values only.
+ #define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT            0x00000002  ///< Serialize options that exactly match opt_flags only.
+ 
+ /**
+  * Serialize object's options.
+  *
+  * Create a string containing object's serialized options.
+@@ -879,13 +945,54 @@ int av_opt_is_set_to_default_by_name(voi
+  *                           Buffer must be freed by the caller when is no longer needed.
+  * @param[in]  key_val_sep   character used to separate key from value
+  * @param[in]  pairs_sep     character used to separate two pairs from each other
+  * @return                   >= 0 on success, negative on error
+  * @warning Separators cannot be neither '\\' nor '\0'. They also cannot be the same.
+  */
+ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
+                      const char key_val_sep, const char pairs_sep);
++
++/**
++ * @}
++ */
++
++/**
++ * Free an AVOptionRanges struct and set it to NULL.
++ */
++void av_opt_freep_ranges(AVOptionRanges **ranges);
++
++/**
++ * Get a list of allowed ranges for the given option.
++ *
++ * The returned list may depend on other fields in obj like for example profile.
++ *
++ * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
++ *              AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
++ *              AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
++ *
++ * The result must be freed with av_opt_freep_ranges.
++ *
++ * @return number of compontents returned on success, a negative errro code otherwise
++ */
++int av_opt_query_ranges(AVOptionRanges **, void *obj, const char *key, int flags);
++
++/**
++ * Get a default list of allowed ranges for the given option.
++ *
++ * This list is constructed without using the AVClass.query_ranges() callback
++ * and can be used as fallback from within the callback.
++ *
++ * @param flags is a bitmask of flags, undefined flags should not be set and should be ignored
++ *              AV_OPT_SEARCH_FAKE_OBJ indicates that the obj is a double pointer to a AVClass instead of a full instance
++ *              AV_OPT_MULTI_COMPONENT_RANGE indicates that function may return more than one component, @see AVOptionRanges
++ *
++ * The result must be freed with av_opt_free_ranges.
++ *
++ * @return number of compontents returned on success, a negative errro code otherwise
++ */
++int av_opt_query_ranges_default(AVOptionRanges **, void *obj, const char *key, int flags);
++
+ /**
+  * @}
+  */
+ 
+ #endif /* AVUTIL_OPT_H */
+diff --git a/media/ffvpx/libavutil/pixdesc.c b/media/ffvpx/libavutil/pixdesc.c
+--- a/media/ffvpx/libavutil/pixdesc.c
++++ b/media/ffvpx/libavutil/pixdesc.c
+@@ -455,22 +455,16 @@ static const AVPixFmtDescriptor av_pix_f
+         .log2_chroma_h = 0,
+         .comp = {
+             { 0, 1, 0, 0, 8 },        /* Y */
+             { 1, 1, 0, 0, 8 },        /* U */
+             { 2, 1, 0, 0, 8 },        /* V */
+         },
+         .flags = AV_PIX_FMT_FLAG_PLANAR,
+     },
+-#if FF_API_XVMC
+-    [AV_PIX_FMT_XVMC] = {
+-        .name = "xvmc",
+-        .flags = AV_PIX_FMT_FLAG_HWACCEL,
+-    },
+-#endif
+     [AV_PIX_FMT_UYVY422] = {
+         .name = "uyvy422",
+         .nb_components = 3,
+         .log2_chroma_w = 1,
+         .log2_chroma_h = 0,
+         .comp = {
+             { 0, 2, 1, 0, 8 },        /* Y */
+             { 0, 4, 0, 0, 8 },        /* U */
+@@ -2855,16 +2849,19 @@ static const char * const color_space_na
+     [AVCOL_SPC_SMPTE240M] = "smpte240m",
+     [AVCOL_SPC_YCGCO] = "ycgco",
+     [AVCOL_SPC_BT2020_NCL] = "bt2020nc",
+     [AVCOL_SPC_BT2020_CL] = "bt2020c",
+     [AVCOL_SPC_SMPTE2085] = "smpte2085",
+     [AVCOL_SPC_CHROMA_DERIVED_NCL] = "chroma-derived-nc",
+     [AVCOL_SPC_CHROMA_DERIVED_CL] = "chroma-derived-c",
+     [AVCOL_SPC_ICTCP] = "ictcp",
++    [AVCOL_SPC_IPT_C2] = "ipt-c2",
++    [AVCOL_SPC_YCGCO_RE] = "ycgco-re",
++    [AVCOL_SPC_YCGCO_RO] = "ycgco-ro",
+ };
+ 
+ static const char * const chroma_location_names[] = {
+     [AVCHROMA_LOC_UNSPECIFIED] = "unspecified",
+     [AVCHROMA_LOC_LEFT] = "left",
+     [AVCHROMA_LOC_CENTER] = "center",
+     [AVCHROMA_LOC_TOPLEFT] = "topleft",
+     [AVCHROMA_LOC_TOP] = "top",
+diff --git a/media/ffvpx/libavutil/pixfmt.h b/media/ffvpx/libavutil/pixfmt.h
+--- a/media/ffvpx/libavutil/pixfmt.h
++++ b/media/ffvpx/libavutil/pixfmt.h
+@@ -28,16 +28,23 @@
+ 
+ #include "libavutil/avconfig.h"
+ #include "version.h"
+ 
+ #define AVPALETTE_SIZE 1024
+ #define AVPALETTE_COUNT 256
+ 
+ /**
++ * Maximum number of planes in any pixel format.
++ * This should be used when a maximum is needed, but code should not
++ * be written to require a maximum for no good reason.
++ */
++#define AV_VIDEO_MAX_PLANES 4
++
++/**
+  * Pixel format.
+  *
+  * @note
+  * AV_PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA
+  * color is put together as:
+  *  (A << 24) | (R << 16) | (G << 8) | B
+  * This is stored as BGRA on little-endian CPU architectures and ARGB on
+  * big-endian CPUs.
+@@ -283,20 +290,16 @@ enum AVPixelFormat {
+     AV_PIX_FMT_BAYER_BGGR16BE, ///< bayer, BGBG..(odd line), GRGR..(even line), 16-bit samples, big-endian
+     AV_PIX_FMT_BAYER_RGGB16LE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, little-endian
+     AV_PIX_FMT_BAYER_RGGB16BE, ///< bayer, RGRG..(odd line), GBGB..(even line), 16-bit samples, big-endian
+     AV_PIX_FMT_BAYER_GBRG16LE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, little-endian
+     AV_PIX_FMT_BAYER_GBRG16BE, ///< bayer, GBGB..(odd line), RGRG..(even line), 16-bit samples, big-endian
+     AV_PIX_FMT_BAYER_GRBG16LE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, little-endian
+     AV_PIX_FMT_BAYER_GRBG16BE, ///< bayer, GRGR..(odd line), BGBG..(even line), 16-bit samples, big-endian
+ 
+-#if FF_API_XVMC
+-    AV_PIX_FMT_XVMC,///< XVideo Motion Acceleration via common packet passing
+-#endif
+-
+     AV_PIX_FMT_YUV440P10LE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian
+     AV_PIX_FMT_YUV440P10BE, ///< planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian
+     AV_PIX_FMT_YUV440P12LE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian
+     AV_PIX_FMT_YUV440P12BE, ///< planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), big-endian
+     AV_PIX_FMT_AYUV64LE,    ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
+     AV_PIX_FMT_AYUV64BE,    ///< packed AYUV 4:4:4,64bpp (1 Cr & Cb sample per 1x1 Y & A samples), big-endian
+ 
+     AV_PIX_FMT_VIDEOTOOLBOX, ///< hardware decoding through Videotoolbox
+@@ -615,16 +618,19 @@ enum AVColorSpace {
+     AVCOL_SPC_YCGCO       = 8,  ///< used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+     AVCOL_SPC_YCOCG       = AVCOL_SPC_YCGCO,
+     AVCOL_SPC_BT2020_NCL  = 9,  ///< ITU-R BT2020 non-constant luminance system
+     AVCOL_SPC_BT2020_CL   = 10, ///< ITU-R BT2020 constant luminance system
+     AVCOL_SPC_SMPTE2085   = 11, ///< SMPTE 2085, Y'D'zD'x
+     AVCOL_SPC_CHROMA_DERIVED_NCL = 12, ///< Chromaticity-derived non-constant luminance system
+     AVCOL_SPC_CHROMA_DERIVED_CL = 13, ///< Chromaticity-derived constant luminance system
+     AVCOL_SPC_ICTCP       = 14, ///< ITU-R BT.2100-0, ICtCp
++    AVCOL_SPC_IPT_C2      = 15, ///< SMPTE ST 2128, IPT-C2
++    AVCOL_SPC_YCGCO_RE    = 16, ///< YCgCo-R, even addition of bits
++    AVCOL_SPC_YCGCO_RO    = 17, ///< YCgCo-R, odd addition of bits
+     AVCOL_SPC_NB                ///< Not part of ABI
+ };
+ 
+ /**
+  * Visual content value range.
+  *
+  * These values are based on definitions that can be found in multiple
+  * specifications, such as ITU-T BT.709 (3.4 - Quantization of RGB, luminance
+diff --git a/media/ffvpx/libavutil/rational.c b/media/ffvpx/libavutil/rational.c
+--- a/media/ffvpx/libavutil/rational.c
++++ b/media/ffvpx/libavutil/rational.c
+@@ -109,17 +109,17 @@ AVRational av_d2q(double d, int max)
+     int exponent;
+     int64_t den;
+     if (isnan(d))
+         return (AVRational) { 0,0 };
+     if (fabs(d) > INT_MAX + 3LL)
+         return (AVRational) { d < 0 ? -1 : 1, 0 };
+     frexp(d, &exponent);
+     exponent = FFMAX(exponent-1, 0);
+-    den = 1LL << (61 - exponent);
++    den = 1LL << (62 - exponent);
+     // (int64_t)rint() and llrint() do not work with gcc on ia64 and sparc64,
+     // see Ticket2713 for affected gcc/glibc versions
+     av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, max);
+     if ((!a.num || !a.den) && d && max>0 && max<INT_MAX)
+         av_reduce(&a.num, &a.den, floor(d * den + 0.5), den, INT_MAX);
+ 
+     return a;
+ }
+diff --git a/media/ffvpx/libavutil/rational.h b/media/ffvpx/libavutil/rational.h
+--- a/media/ffvpx/libavutil/rational.h
++++ b/media/ffvpx/libavutil/rational.h
+@@ -163,16 +163,20 @@ static av_always_inline AVRational av_in
+ }
+ 
+ /**
+  * Convert a double precision floating point number to a rational.
+  *
+  * In case of infinity, the returned value is expressed as `{1, 0}` or
+  * `{-1, 0}` depending on the sign.
+  *
++ * In general rational numbers with |num| <= 1<<26 && |den| <= 1<<26
++ * can be recovered exactly from their double representation.
++ * (no exceptions were found within 1B random ones)
++ *
+  * @param d   `double` to convert
+  * @param max Maximum allowed numerator and denominator
+  * @return `d` in AVRational form
+  * @see av_q2d()
+  */
+ AVRational av_d2q(double d, int max) av_const;
+ 
+ /**
+diff --git a/media/ffvpx/libavutil/thread.h b/media/ffvpx/libavutil/thread.h
+--- a/media/ffvpx/libavutil/thread.h
++++ b/media/ffvpx/libavutil/thread.h
+@@ -21,16 +21,18 @@
+ 
+ #ifndef AVUTIL_THREAD_H
+ #define AVUTIL_THREAD_H
+ 
+ #include "config.h"
+ 
+ #if HAVE_PRCTL
+ #include <sys/prctl.h>
++#elif (HAVE_PTHREAD_SETNAME_NP || HAVE_PTHREAD_SET_NAME_NP) && HAVE_PTHREAD_NP_H
++#include <pthread_np.h>
+ #endif
+ 
+ #include "error.h"
+ 
+ #if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS
+ 
+ #if HAVE_PTHREADS
+ #include <pthread.h>
+@@ -208,16 +210,30 @@ static inline int ff_thread_once(char *c
+     }
+     return 0;
+ }
+ 
+ #endif
+ 
+ static inline int ff_thread_setname(const char *name)
+ {
++    int ret = 0;
++
+ #if HAVE_PRCTL
+-    return AVERROR(prctl(PR_SET_NAME, name));
++    ret = AVERROR(prctl(PR_SET_NAME, name));
++#elif HAVE_PTHREAD_SETNAME_NP
++#if defined(__APPLE__)
++    ret = AVERROR(pthread_setname_np(name));
++#elif defined(__NetBSD__)
++    ret = AVERROR(pthread_setname_np(pthread_self(), "%s", name));
++#else
++    ret = AVERROR(pthread_setname_np(pthread_self(), name));
++#endif
++#elif HAVE_PTHREAD_SET_NAME_NP
++    pthread_set_name_np(pthread_self(), name);
++#else
++    ret = AVERROR(ENOSYS);
+ #endif
+ 
+-    return AVERROR(ENOSYS);
++    return ret;
+ }
+ 
+ #endif /* AVUTIL_THREAD_H */
+diff --git a/media/ffvpx/libavutil/timecode.c b/media/ffvpx/libavutil/timecode.c
+--- a/media/ffvpx/libavutil/timecode.c
++++ b/media/ffvpx/libavutil/timecode.c
+@@ -205,17 +205,17 @@ static int check_timecode(void *log_ctx,
+     }
+     return 0;
+ }
+ 
+ static int fps_from_frame_rate(AVRational rate)
+ {
+     if (!rate.den || !rate.num)
+         return -1;
+-    return (rate.num + rate.den/2) / rate.den;
++    return (rate.num + rate.den/2LL) / rate.den;
+ }
+ 
+ int av_timecode_check_frame_rate(AVRational rate)
+ {
+     return check_fps(fps_from_frame_rate(rate));
+ }
+ 
+ int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
+diff --git a/media/ffvpx/libavutil/timestamp.h b/media/ffvpx/libavutil/timestamp.h
+--- a/media/ffvpx/libavutil/timestamp.h
++++ b/media/ffvpx/libavutil/timestamp.h
+@@ -57,21 +57,28 @@ static inline char *av_ts_make_string(ch
+  * Fill the provided buffer with a string containing a timestamp time
+  * representation.
+  *
+  * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
+  * @param ts the timestamp to represent
+  * @param tb the timebase of the timestamp
+  * @return the buffer in input
+  */
+-static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb)
++char *av_ts_make_time_string2(char *buf, int64_t ts, AVRational tb);
++
++/**
++ * Fill the provided buffer with a string containing a timestamp
++ * representation.
++ *
++ * @see av_ts_make_time_string2
++ */
++static inline char *av_ts_make_time_string(char *buf, int64_t ts,
++                                           const AVRational *tb)
+ {
+-    if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
+-    else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts);
+-    return buf;
++    return av_ts_make_time_string2(buf, ts, *tb);
+ }
+ 
+ /**
+  * Convenience macro, the return value should be used only directly in
+  * function arguments but never stand-alone.
+  */
+ #define av_ts2timestr(ts, tb) av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb)
+ 
+diff --git a/media/ffvpx/libavutil/tx.c b/media/ffvpx/libavutil/tx.c
+--- a/media/ffvpx/libavutil/tx.c
++++ b/media/ffvpx/libavutil/tx.c
+@@ -14,16 +14,17 @@
+  * 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
+  */
+ 
+ #include "avassert.h"
+ #include "intmath.h"
+ #include "cpu.h"
++#include "mem.h"
+ #include "qsort.h"
+ #include "bprint.h"
+ 
+ #include "tx_priv.h"
+ 
+ #define TYPE_IS(type, x)               \
+     (((x) == AV_TX_FLOAT_ ## type)  || \
+      ((x) == AV_TX_DOUBLE_ ## type) || \
+@@ -588,17 +589,18 @@ static void print_type(AVBPrint *bp, enu
+                type == AV_TX_INT32_FFT   ? "fft_int32"   :
+                type == AV_TX_INT32_MDCT  ? "mdct_int32"  :
+                type == AV_TX_INT32_RDFT  ? "rdft_int32"  :
+                type == AV_TX_INT32_DCT_I ? "dctI_int32" :
+                type == AV_TX_INT32_DST_I ? "dstI_int32" :
+                "unknown");
+ }
+ 
+-static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio)
++static void print_cd_info(const FFTXCodelet *cd, int prio, int len, int print_prio,
++                          int log_level)
+ {
+     AVBPrint bp;
+     av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
+ 
+     av_bprintf(&bp, "%s - type: ", cd->name);
+ 
+     print_type(&bp, cd->type);
+ 
+@@ -638,27 +640,27 @@ static void print_cd_info(const FFTXCode
+         av_bprintf(&bp, "%s, factor: %i, ",
+                    !len && cd->min_len != cd->max_len ? "]" : "", cd->factors[0]);
+     }
+     print_flags(&bp, cd->flags);
+ 
+     if (print_prio)
+         av_bprintf(&bp, ", prio: %i", prio);
+ 
+-    av_log(NULL, AV_LOG_DEBUG, "%s\n", bp.str);
++    av_log(NULL, log_level, "%s\n", bp.str);
+ }
+ 
+ static void print_tx_structure(AVTXContext *s, int depth)
+ {
+     const FFTXCodelet *cd = s->cd_self;
+ 
+     for (int i = 0; i <= depth; i++)
+         av_log(NULL, AV_LOG_DEBUG, "    ");
+ 
+-    print_cd_info(cd, cd->prio, s->len, 0);
++    print_cd_info(cd, cd->prio, s->len, 0, AV_LOG_DEBUG);
+ 
+     for (int i = 0; i < s->nb_sub; i++)
+         print_tx_structure(&s->sub[i], depth + 1);
+ }
+ #endif /* CONFIG_SMALL */
+ 
+ typedef struct TXCodeletMatch {
+     const FFTXCodelet *cd;
+@@ -811,21 +813,21 @@ av_cold int ff_tx_init_subtx(AVTXContext
+     /* No matches found */
+     if (!nb_cd_matches)
+         return AVERROR(ENOSYS);
+ 
+     /* Sort the list */
+     AV_QSORT(cd_matches, nb_cd_matches, TXCodeletMatch, cmp_matches);
+ 
+ #if !CONFIG_SMALL
+-    av_log(NULL, AV_LOG_DEBUG, "%s\n", bp.str);
++    av_log(NULL, AV_LOG_TRACE, "%s\n", bp.str);
+ 
+     for (int i = 0; i < nb_cd_matches; i++) {
+-        av_log(NULL, AV_LOG_DEBUG, "    %i: ", i + 1);
+-        print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 0, 1);
++        av_log(NULL, AV_LOG_TRACE, "    %i: ", i + 1);
++        print_cd_info(cd_matches[i].cd, cd_matches[i].prio, 0, 1, AV_LOG_TRACE);
+     }
+ #endif
+ 
+     if (!s->sub) {
+         s->sub = sub = av_mallocz(TX_MAX_SUB*sizeof(*sub));
+         if (!sub) {
+             ret = AVERROR(ENOMEM);
+             goto end;
+@@ -909,20 +911,22 @@ av_cold int av_tx_init(AVTXContext **ctx
+     if (!len || type >= AV_TX_NB || !ctx || !tx)
+         return AVERROR(EINVAL);
+ 
+     if (!(flags & AV_TX_UNALIGNED))
+         flags |= FF_TX_ALIGNED;
+     if (!(flags & AV_TX_INPLACE))
+         flags |= FF_TX_OUT_OF_PLACE;
+ 
+-    if (!scale && ((type == AV_TX_FLOAT_MDCT) || (type == AV_TX_INT32_MDCT)))
++    if (!scale && ((type == AV_TX_DOUBLE_MDCT) || (type == AV_TX_DOUBLE_DCT) ||
++                   (type == AV_TX_DOUBLE_DCT_I) || (type == AV_TX_DOUBLE_DST_I) ||
++                   (type == AV_TX_DOUBLE_RDFT)))
++        scale = &default_scale_d;
++    else if (!scale && !TYPE_IS(FFT, type))
+         scale = &default_scale_f;
+-    else if (!scale && (type == AV_TX_DOUBLE_MDCT))
+-        scale = &default_scale_d;
+ 
+     ret = ff_tx_init_subtx(&tmp, type, flags, NULL, len, inv, scale);
+     if (ret < 0)
+         return ret;
+ 
+     *ctx = &tmp.sub[0];
+     *tx  = tmp.fn[0];
+ 
+diff --git a/media/ffvpx/libavutil/tx_template.c b/media/ffvpx/libavutil/tx_template.c
+--- a/media/ffvpx/libavutil/tx_template.c
++++ b/media/ffvpx/libavutil/tx_template.c
+@@ -19,16 +19,18 @@
+  * 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
+  */
+ 
++#include "mem.h"
++
+ #define TABLE_DEF(name, size) \
+     DECLARE_ALIGNED(32, TXSample, TX_TAB(ff_tx_tab_ ##name))[size]
+ 
+ #define SR_POW2_TABLES \
+     SR_TABLE(8)        \
+     SR_TABLE(16)       \
+     SR_TABLE(32)       \
+     SR_TABLE(64)       \
+diff --git a/media/ffvpx/libavutil/version.h b/media/ffvpx/libavutil/version.h
+--- a/media/ffvpx/libavutil/version.h
++++ b/media/ffvpx/libavutil/version.h
+@@ -73,19 +73,19 @@
+  * @defgroup lavu_ver Version and Build diagnostics
+  *
+  * Macros and function useful to check at compiletime and at runtime
+  * which version of libavutil is in use.
+  *
+  * @{
+  */
+ 
+-#define LIBAVUTIL_VERSION_MAJOR  58
+-#define LIBAVUTIL_VERSION_MINOR  36
+-#define LIBAVUTIL_VERSION_MICRO 101
++#define LIBAVUTIL_VERSION_MAJOR  59
++#define LIBAVUTIL_VERSION_MINOR  13
++#define LIBAVUTIL_VERSION_MICRO 100
+ 
+ #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
+                                                LIBAVUTIL_VERSION_MINOR, \
+                                                LIBAVUTIL_VERSION_MICRO)
+ #define LIBAVUTIL_VERSION       AV_VERSION(LIBAVUTIL_VERSION_MAJOR,     \
+                                            LIBAVUTIL_VERSION_MINOR,     \
+                                            LIBAVUTIL_VERSION_MICRO)
+ #define LIBAVUTIL_BUILD         LIBAVUTIL_VERSION_INT
+@@ -100,29 +100,22 @@
+  *
+  * @note, when bumping the major version it is recommended to manually
+  * disable each FF_API_* in its own commit instead of disabling them all
+  * at once through the bump. This improves the git bisect-ability of the change.
+  *
+  * @{
+  */
+ 
+-#define FF_API_FIFO_PEEK2               (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_FIFO_OLD_API             (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_XVMC                     (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_OLD_CHANNEL_LAYOUT       (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_AV_FOPEN_UTF8            (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_PKT_DURATION             (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_REORDERED_OPAQUE         (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_FRAME_PICTURE_NUMBER     (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_HDR_VIVID_THREE_SPLINE   (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_FRAME_PKT                (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_INTERLACED_FRAME         (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_FRAME_KEY                (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_PALETTE_HAS_CHANGED      (LIBAVUTIL_VERSION_MAJOR < 59)
+-#define FF_API_VULKAN_CONTIGUOUS_MEMORY (LIBAVUTIL_VERSION_MAJOR < 59)
++#define FF_API_HDR_VIVID_THREE_SPLINE   (LIBAVUTIL_VERSION_MAJOR < 60)
++#define FF_API_FRAME_PKT                (LIBAVUTIL_VERSION_MAJOR < 60)
++#define FF_API_INTERLACED_FRAME         (LIBAVUTIL_VERSION_MAJOR < 60)
++#define FF_API_FRAME_KEY                (LIBAVUTIL_VERSION_MAJOR < 60)
++#define FF_API_PALETTE_HAS_CHANGED      (LIBAVUTIL_VERSION_MAJOR < 60)
++#define FF_API_VULKAN_CONTIGUOUS_MEMORY (LIBAVUTIL_VERSION_MAJOR < 60)
++#define FF_API_H274_FILM_GRAIN_VCS      (LIBAVUTIL_VERSION_MAJOR < 60)
+ 
+ /**
+  * @}
+  * @}
+  */
+ 
+ #endif /* AVUTIL_VERSION_H */
+diff --git a/media/ffvpx/libavutil/x86/emms.h b/media/ffvpx/libavutil/x86/emms.h
+deleted file mode 100644
+--- a/media/ffvpx/libavutil/x86/emms.h
++++ /dev/null
+@@ -1,58 +0,0 @@
+-/*
+- * 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
+- */
+-
+-#ifndef AVUTIL_X86_EMMS_H
+-#define AVUTIL_X86_EMMS_H
+-
+-#include "config.h"
+-#include "libavutil/attributes.h"
+-
+-void avpriv_emms_asm(void);
+-
+-#if HAVE_MMX_INLINE
+-#ifndef __MMX__
+-#include "libavutil/cpu.h"
+-#endif
+-
+-#   define emms_c emms_c
+-/**
+- * Empty mmx state.
+- * this must be called between any dsp function and float/double code.
+- * for example sin(); dsp->idct_put(); emms_c(); cos()
+- * Note, *alloc() and *free() also use float code in some libc implementations
+- * thus this also applies to them or any function using them.
+- */
+-static av_always_inline void emms_c(void)
+-{
+-/* Some inlined functions may also use mmx instructions regardless of
+- * runtime cpuflags. With that in mind, we unconditionally empty the
+- * mmx state if the target cpu chosen at configure time supports it.
+- */
+-#if !defined(__MMX__)
+-    if(av_get_cpu_flags() & AV_CPU_FLAG_MMX)
+-#endif
+-        __asm__ volatile ("emms" ::: "memory");
+-}
+-#elif HAVE_MMX && HAVE_MM_EMPTY
+-#   include <mmintrin.h>
+-#   define emms_c _mm_empty
+-#elif HAVE_MMX_EXTERNAL
+-#   define emms_c avpriv_emms_asm
+-#endif /* HAVE_MMX_INLINE */
+-
+-#endif /* AVUTIL_X86_EMMS_H */
+diff --git a/media/ffvpx/libavutil/x86/fixed_dsp_init.c b/media/ffvpx/libavutil/x86/fixed_dsp_init.c
+--- a/media/ffvpx/libavutil/x86/fixed_dsp_init.c
++++ b/media/ffvpx/libavutil/x86/fixed_dsp_init.c
+@@ -11,24 +11,22 @@
+  * 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
+  */
+ 
+-#include "config.h"
+-
+ #include "libavutil/attributes.h"
+ #include "libavutil/cpu.h"
+ #include "libavutil/fixed_dsp.h"
+ #include "cpu.h"
+ 
+-void ff_butterflies_fixed_sse2(int *av_restrict src0, int *av_restrict src1, int len);
++void ff_butterflies_fixed_sse2(int *restrict src0, int *restrict src1, int len);
+ 
+ av_cold void ff_fixed_dsp_init_x86(AVFixedDSPContext *fdsp)
+ {
+     int cpu_flags = av_get_cpu_flags();
+ 
+     if (EXTERNAL_SSE2(cpu_flags)) {
+         fdsp->butterflies_fixed = ff_butterflies_fixed_sse2;
+     }
+diff --git a/media/ffvpx/libavutil/x86/float_dsp_init.c b/media/ffvpx/libavutil/x86/float_dsp_init.c
+--- a/media/ffvpx/libavutil/x86/float_dsp_init.c
++++ b/media/ffvpx/libavutil/x86/float_dsp_init.c
+@@ -11,23 +11,20 @@
+  * 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
+  */
+ 
+-#include "config.h"
+-
+ #include "libavutil/attributes.h"
+ #include "libavutil/cpu.h"
+ #include "libavutil/float_dsp.h"
+ #include "cpu.h"
+-#include "asm.h"
+ 
+ void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
+                         int len);
+ void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1,
+                         int len);
+ 
+ void ff_vector_dmul_sse2(double *dst, const double *src0, const double *src1,
+                          int len);
+@@ -71,17 +68,17 @@ void ff_vector_fmul_reverse_sse(float *d
+ void ff_vector_fmul_reverse_avx(float *dst, const float *src0,
+                                 const float *src1, int len);
+ void ff_vector_fmul_reverse_avx2(float *dst, const float *src0,
+                                  const float *src1, int len);
+ 
+ float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
+ float ff_scalarproduct_float_fma3(const float *v1, const float *v2, int order);
+ 
+-void ff_butterflies_float_sse(float *av_restrict src0, float *av_restrict src1, int len);
++void ff_butterflies_float_sse(float *restrict src0, float *restrict src1, int len);
+ 
+ av_cold void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
+ {
+     int cpu_flags = av_get_cpu_flags();
+ 
+     if (EXTERNAL_SSE(cpu_flags)) {
+         fdsp->vector_fmul = ff_vector_fmul_sse;
+         fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse;
+diff --git a/media/ffvpx/libavutil/x86/intreadwrite.h b/media/ffvpx/libavutil/x86/intreadwrite.h
+--- a/media/ffvpx/libavutil/x86/intreadwrite.h
++++ b/media/ffvpx/libavutil/x86/intreadwrite.h
+@@ -22,52 +22,16 @@
+ #define AVUTIL_X86_INTREADWRITE_H
+ 
+ #include <stdint.h>
+ #include "config.h"
+ #include "libavutil/attributes.h"
+ 
+ #if HAVE_MMX
+ 
+-#if !HAVE_FAST_64BIT && defined(__MMX__)
+-
+-#define FF_COPY_SWAP_ZERO_USES_MMX
+-
+-#define AV_COPY64 AV_COPY64
+-static av_always_inline void AV_COPY64(void *d, const void *s)
+-{
+-    __asm__("movq   %1, %%mm0  \n\t"
+-            "movq   %%mm0, %0  \n\t"
+-            : "=m"(*(uint64_t*)d)
+-            : "m" (*(const uint64_t*)s)
+-            : "mm0");
+-}
+-
+-#define AV_SWAP64 AV_SWAP64
+-static av_always_inline void AV_SWAP64(void *a, void *b)
+-{
+-    __asm__("movq   %1, %%mm0  \n\t"
+-            "movq   %0, %%mm1  \n\t"
+-            "movq   %%mm0, %0  \n\t"
+-            "movq   %%mm1, %1  \n\t"
+-            : "+m"(*(uint64_t*)a), "+m"(*(uint64_t*)b)
+-            ::"mm0", "mm1");
+-}
+-
+-#define AV_ZERO64 AV_ZERO64
+-static av_always_inline void AV_ZERO64(void *d)
+-{
+-    __asm__("pxor %%mm0, %%mm0  \n\t"
+-            "movq %%mm0, %0     \n\t"
+-            : "=m"(*(uint64_t*)d)
+-            :: "mm0");
+-}
+-
+-#endif /* !HAVE_FAST_64BIT && defined(__MMX__) */
+-
+ #ifdef __SSE__
+ 
+ #define AV_COPY128 AV_COPY128
+ static av_always_inline void AV_COPY128(void *d, const void *s)
+ {
+     struct v {uint64_t v[2];};
+ 
+     __asm__("movaps   %1, %%xmm0  \n\t"
+diff --git a/media/ffvpx/libavutil/x86/moz.build b/media/ffvpx/libavutil/x86/moz.build
+--- a/media/ffvpx/libavutil/x86/moz.build
++++ b/media/ffvpx/libavutil/x86/moz.build
+@@ -11,15 +11,17 @@ SOURCES += [
+     'fixed_dsp.asm',
+     'fixed_dsp_init.c',
+     'float_dsp.asm',
+     'float_dsp_init.c',
+     'imgutils.asm',
+     'imgutils_init.c',
+     'lls.asm',
+     'lls_init.c',
++    'pixelutils.asm',
++    'pixelutils_init.c',
+     'tx_float.asm',
+     'tx_float_init.c',
+ ]
+ 
+ FINAL_LIBRARY = 'mozavutil'
+ 
+ include('/media/ffvpx/ffvpxcommon.mozbuild')
+diff --git a/media/ffvpx/libavutil/x86/tx_float.asm b/media/ffvpx/libavutil/x86/tx_float.asm
+--- a/media/ffvpx/libavutil/x86/tx_float.asm
++++ b/media/ffvpx/libavutil/x86/tx_float.asm
+@@ -41,17 +41,17 @@
+ 
+ %if ARCH_X86_64
+ %define ptr resq
+ %else
+ %define ptr resd
+ %endif
+ 
+ %assign i 16
+-%rep 14
++%rep 18
+ cextern tab_ %+ i %+ _float ; ff_tab_i_float...
+ %assign i (i << 1)
+ %endrep
+ 
+ cextern tab_53_float
+ 
+ struc AVTXContext
+     .len:          resd 1 ; Length
+@@ -1380,17 +1380,21 @@ ALIGN 16
+ 
+ ; 2048 to 131072-point transforms ==============================================
+ FFT_SPLIT_RADIX_DEF 2048,  .4096pt
+ FFT_SPLIT_RADIX_DEF 4096,  .8192pt
+ FFT_SPLIT_RADIX_DEF 8192,  .16384pt
+ FFT_SPLIT_RADIX_DEF 16384, .32768pt
+ FFT_SPLIT_RADIX_DEF 32768, .65536pt
+ FFT_SPLIT_RADIX_DEF 65536, .131072pt
+-FFT_SPLIT_RADIX_DEF 131072
++FFT_SPLIT_RADIX_DEF 131072, .262144pt
++FFT_SPLIT_RADIX_DEF 262144, .524288pt
++FFT_SPLIT_RADIX_DEF 524288, .1048576pt
++FFT_SPLIT_RADIX_DEF 1048576, .2097152pt
++FFT_SPLIT_RADIX_DEF 2097152
+ 
+ ;===============================================================================
+ ; Final synthesis + deinterleaving code
+ ;===============================================================================
+ .deinterleave:
+ %if %2
+     PUSH strideq
+ %endif
+diff --git a/media/ffvpx/libavutil/x86/tx_float_init.c b/media/ffvpx/libavutil/x86/tx_float_init.c
+--- a/media/ffvpx/libavutil/x86/tx_float_init.c
++++ b/media/ffvpx/libavutil/x86/tx_float_init.c
+@@ -14,16 +14,17 @@
+  * 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
+  */
+ 
+ #define TX_FLOAT
+ #include "libavutil/tx_priv.h"
+ #include "libavutil/attributes.h"
++#include "libavutil/mem.h"
+ #include "libavutil/x86/cpu.h"
+ 
+ #include "config.h"
+ 
+ TX_DECL_FN(fft2,      sse3)
+ TX_DECL_FN(fft4_fwd,  sse2)
+ TX_DECL_FN(fft4_inv,  sse2)
+ TX_DECL_FN(fft8,      sse3)
+@@ -265,38 +266,38 @@ const FFTXCodelet * const ff_tx_codelet_
+            AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
+     TX_DEF(fft32_ns, FFT, 32, 32, 2, 0, 320, b8_i2, avx,  AVX,  AV_TX_INPLACE | FF_TX_PRESHUFFLE,
+            AV_CPU_FLAG_AVXSLOW),
+     TX_DEF(fft32,    FFT, 32, 32, 2, 0, 288, b8_i2, fma3, FMA3, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW),
+     TX_DEF(fft32_asm, FFT, 32, 32, 2, 0, 352, b8_i2, fma3, FMA3,
+            AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
+     TX_DEF(fft32_ns, FFT, 32, 32, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
+            AV_CPU_FLAG_AVXSLOW),
+-    TX_DEF(fft_sr,    FFT, 64, 131072, 2, 0, 256, b8_i2, avx, AVX,  0, AV_CPU_FLAG_AVXSLOW),
+-    TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 320, b8_i2, avx, AVX,
++    TX_DEF(fft_sr,    FFT, 64, 2097152, 2, 0, 256, b8_i2, avx, AVX,  0, AV_CPU_FLAG_AVXSLOW),
++    TX_DEF(fft_sr_asm, FFT, 64, 2097152, 2, 0, 320, b8_i2, avx, AVX,
+            AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
+-    TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 320, b8_i2, avx, AVX,  AV_TX_INPLACE | FF_TX_PRESHUFFLE,
++    TX_DEF(fft_sr_ns, FFT, 64, 2097152, 2, 0, 320, b8_i2, avx, AVX,  AV_TX_INPLACE | FF_TX_PRESHUFFLE,
+            AV_CPU_FLAG_AVXSLOW),
+-    TX_DEF(fft_sr,    FFT, 64, 131072, 2, 0, 288, b8_i2, fma3,  FMA3,  0, AV_CPU_FLAG_AVXSLOW),
+-    TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 352, b8_i2, fma3,  FMA3,
++    TX_DEF(fft_sr,    FFT, 64, 2097152, 2, 0, 288, b8_i2, fma3,  FMA3,  0, AV_CPU_FLAG_AVXSLOW),
++    TX_DEF(fft_sr_asm, FFT, 64, 2097152, 2, 0, 352, b8_i2, fma3,  FMA3,
+            AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
+-    TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 352, b8_i2, fma3,  FMA3,  AV_TX_INPLACE | FF_TX_PRESHUFFLE,
++    TX_DEF(fft_sr_ns, FFT, 64, 2097152, 2, 0, 352, b8_i2, fma3,  FMA3,  AV_TX_INPLACE | FF_TX_PRESHUFFLE,
+            AV_CPU_FLAG_AVXSLOW),
+ 
+ #if HAVE_AVX2_EXTERNAL
+     TX_DEF(fft15, FFT, 15, 15, 15, 0, 320, factor_init, avx2, AVX2,
+            AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW),
+     TX_DEF(fft15_ns, FFT, 15, 15, 15, 0, 384, factor_init, avx2, AVX2,
+            AV_TX_INPLACE | FF_TX_PRESHUFFLE, AV_CPU_FLAG_AVXSLOW),
+ 
+-    TX_DEF(fft_sr,    FFT, 64, 131072, 2, 0, 320, b8_i2, avx2, AVX2, 0,
++    TX_DEF(fft_sr,    FFT, 64, 2097152, 2, 0, 320, b8_i2, avx2, AVX2, 0,
+            AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
+-    TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 384, b8_i2, avx2, AVX2,
++    TX_DEF(fft_sr_asm, FFT, 64, 2097152, 2, 0, 384, b8_i2, avx2, AVX2,
+            AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
+-    TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 384, b8_i2, avx2, AVX2, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
++    TX_DEF(fft_sr_ns, FFT, 64, 2097152, 2, 0, 384, b8_i2, avx2, AVX2, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
+            AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
+ 
+     TX_DEF(fft_pfa_15xM, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 320, fft_pfa_init, avx2, AVX2,
+            AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
+     TX_DEF(fft_pfa_15xM_asm, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 384, fft_pfa_init, avx2, AVX2,
+            AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
+     TX_DEF(fft_pfa_15xM_ns, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 384, fft_pfa_init, avx2, AVX2,
+            AV_TX_INPLACE | FF_TX_PRESHUFFLE, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
+diff --git a/media/ffvpx/libavutil/x86/x86inc.asm b/media/ffvpx/libavutil/x86/x86inc.asm
+--- a/media/ffvpx/libavutil/x86/x86inc.asm
++++ b/media/ffvpx/libavutil/x86/x86inc.asm
+@@ -1,12 +1,12 @@
+ ;*****************************************************************************
+-;* x86inc.asm: x264asm abstraction layer
++;* x86inc.asm: x86 abstraction layer
+ ;*****************************************************************************
+-;* Copyright (C) 2005-2018 x264 project
++;* Copyright (C) 2005-2024 x264 project
+ ;*
+ ;* Authors: Loren Merritt <lorenm@u.washington.edu>
+ ;*          Henrik Gramner <henrik@gramner.com>
+ ;*          Anton Mitrofanov <BugMaster@narod.ru>
+ ;*          Fiona Glaser <fiona@x264.com>
+ ;*
+ ;* Permission to use, copy, modify, and/or distribute this software for any
+ ;* purpose with or without fee is hereby granted, provided that the above
+@@ -16,31 +16,24 @@
+ ;* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ ;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ;* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ ;* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ;* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ ;* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ ;*****************************************************************************
+ 
+-; This is a header file for the x264ASM assembly language, which uses
++; This is a header file for the x86inc.asm assembly language, which uses
+ ; NASM/YASM syntax combined with a large number of macros to provide easy
+ ; abstraction between different calling conventions (x86_32, win64, linux64).
+ ; It also has various other useful features to simplify writing the kind of
+-; DSP functions that are most often used in x264.
+-
+-; Unlike the rest of x264, this file is available under an ISC license, as it
+-; has significant usefulness outside of x264 and we want it to be available
+-; to the largest audience possible.  Of course, if you modify it for your own
+-; purposes to add a new feature, we strongly encourage contributing a patch
+-; as this feature might be useful for others as well.  Send patches or ideas
+-; to x264-devel@videolan.org .
++; DSP functions that are most often used.
+ 
+ %ifndef private_prefix
+-    %define private_prefix x264
++    %error private_prefix not defined
+ %endif
+ 
+ %ifndef public_prefix
+     %define public_prefix private_prefix
+ %endif
+ 
+ %if HAVE_ALIGNED_STACK
+     %define STACK_ALIGNMENT 16
+@@ -63,30 +56,42 @@
+     %elifidn __OUTPUT_FORMAT__,x64
+         %define WIN64  1
+     %else
+         %define UNIX64 1
+     %endif
+ %endif
+ 
+ %define FORMAT_ELF 0
++%define FORMAT_MACHO 0
+ %ifidn __OUTPUT_FORMAT__,elf
+     %define FORMAT_ELF 1
+ %elifidn __OUTPUT_FORMAT__,elf32
+     %define FORMAT_ELF 1
+ %elifidn __OUTPUT_FORMAT__,elf64
+     %define FORMAT_ELF 1
++%elifidn __OUTPUT_FORMAT__,macho
++    %define FORMAT_MACHO 1
++%elifidn __OUTPUT_FORMAT__,macho32
++    %define FORMAT_MACHO 1
++%elifidn __OUTPUT_FORMAT__,macho64
++    %define FORMAT_MACHO 1
+ %endif
+ 
+ %ifdef PREFIX
+     %define mangle(x) _ %+ x
+ %else
+     %define mangle(x) x
+ %endif
+ 
++; Use VEX-encoding even in non-AVX functions
++%ifndef FORCE_VEX_ENCODING
++    %define FORCE_VEX_ENCODING 0
++%endif
++
+ ; aout does not support align=
+ ; NOTE: This section is out of sync with x264, in order to
+ ; keep supporting OS/2.
+ %macro SECTION_RODATA 0-1 16
+     %ifidn __OUTPUT_FORMAT__,aout
+         SECTION .text
+     %elifidn __OUTPUT_FORMAT__,coff
+         SECTION .text
+@@ -94,38 +99,37 @@
+         SECTION .rdata align=%1
+     %elif WIN64
+         SECTION .rdata align=%1
+     %else
+         SECTION .rodata align=%1
+     %endif
+ %endmacro
+ 
+-%if WIN64
+-    %define PIC
+-%elif ARCH_X86_64 == 0
+-; x86_32 doesn't require PIC.
+-; Some distros prefer shared objects to be PIC, but nothing breaks if
+-; the code contains a few textrels, so we'll skip that complexity.
+-    %undef PIC
+-%endif
+-%ifdef PIC
++%if ARCH_X86_64
++    %define PIC 1 ; always use PIC on x86-64
+     default rel
++%elifidn __OUTPUT_FORMAT__,win32
++    %define PIC 0 ; PIC isn't used on 32-bit Windows
++%elifndef PIC
++    %define PIC 0
+ %endif
+ 
+-%macro CPUNOP 1
+-    %if HAVE_CPUNOP
+-        CPU %1
++%define HAVE_PRIVATE_EXTERN 1
++%ifdef __NASM_VERSION_ID__
++    %use smartalign
++    %if __NASM_VERSION_ID__ < 0x020e0000 ; 2.14
++        %define HAVE_PRIVATE_EXTERN 0
+     %endif
+-%endmacro
++%endif
+ 
+ ; Macros to eliminate most code duplication between x86_32 and x86_64:
+ ; Currently this works only for leaf functions which load all their arguments
+ ; into registers at the start, and make no other use of the stack. Luckily that
+-; covers most of x264's asm.
++; covers most use cases.
+ 
+ ; PROLOGUE:
+ ; %1 = number of arguments. loads them from stack if needed.
+ ; %2 = number of registers used. pushes callee-saved regs if needed.
+ ; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed.
+ ; %4 = (optional) stack size to be allocated. The stack will be aligned before
+ ;      allocating the specified stack size. If the required stack alignment is
+ ;      larger than the known stack alignment the stack will be manually aligned
+@@ -227,16 +231,28 @@ DECLARE_REG_SIZE bp, bpl, null
+ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
+ 
+ %if ARCH_X86_64
+     %define gprsize 8
+ %else
+     %define gprsize 4
+ %endif
+ 
++%macro LEA 2
++%if ARCH_X86_64
++    lea %1, [%2]
++%elif PIC
++    call $+5 ; special-cased to not affect the RSB on most CPU:s
++    pop %1
++    add %1, (%2)-$+1
++%else
++    mov %1, %2
++%endif
++%endmacro
++
+ ; Repeats an instruction/operation for multiple arguments.
+ ; Example usage: "REPX {psrlw x, 8}, m0, m1, m2, m3"
+ %macro REPX 2-* ; operation, args
+     %xdefine %%f(x) %1
+     %rep %0 - 1
+         %rotate 1
+         %%f(%1)
+     %endrep
+@@ -298,16 +314,20 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9
+ %endmacro
+ 
+ %macro movifnidn 2
+     %ifnidn %1, %2
+         mov %1, %2
+     %endif
+ %endmacro
+ 
++%if ARCH_X86_64 == 0
++    %define movsxd movifnidn
++%endif
++
+ %macro movsxdifnidn 2
+     %ifnidn %1, %2
+         movsxd %1, %2
+     %endif
+ %endmacro
+ 
+ %macro ASSERT 1
+     %if (%1) == 0
+@@ -349,62 +369,100 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9
+     %xdefine stack_offset %%stack_offset
+     %assign n_arg_names %0
+ %endmacro
+ 
+ %define required_stack_alignment ((mmsize + 15) & ~15)
+ %define vzeroupper_required (mmsize > 16 && (ARCH_X86_64 == 0 || xmm_regs_used > 16 || notcpuflag(avx512)))
+ %define high_mm_regs (16*cpuflag(avx512))
+ 
+-%macro ALLOC_STACK 1-2 0 ; stack_size, n_xmm_regs (for win64 only)
++; Large stack allocations on Windows need to use stack probing in order
++; to guarantee that all stack memory is committed before accessing it.
++; This is done by ensuring that the guard page(s) at the end of the
++; currently committed pages are touched prior to any pages beyond that.
++%if WIN64
++    %assign STACK_PROBE_SIZE 8192
++%elifidn __OUTPUT_FORMAT__, win32
++    %assign STACK_PROBE_SIZE 4096
++%else
++    %assign STACK_PROBE_SIZE 0
++%endif
++
++%macro PROBE_STACK 1 ; stack_size
++    %if STACK_PROBE_SIZE
++        %assign %%i STACK_PROBE_SIZE
++        %rep %1 / STACK_PROBE_SIZE
++            mov eax, [rsp-%%i]
++            %assign %%i %%i+STACK_PROBE_SIZE
++        %endrep
++    %endif
++%endmacro
++
++%macro RESET_STACK_STATE 0
++    %ifidn rstk, rsp
++        %assign stack_offset stack_offset - stack_size_padded
++    %else
++        %xdefine rstk rsp
++    %endif
++    %assign stack_size 0
++    %assign stack_size_padded 0
++    %assign xmm_regs_used 0
++%endmacro
++
++%macro ALLOC_STACK 0-2 0, 0 ; stack_size, n_xmm_regs
++    RESET_STACK_STATE
++    %ifnum %2
++        %if mmsize != 8
++            %assign xmm_regs_used %2
++        %endif
++    %endif
+     %ifnum %1
+         %if %1 != 0
+             %assign %%pad 0
+             %assign stack_size %1
+             %if stack_size < 0
+                 %assign stack_size -stack_size
+             %endif
+             %if WIN64
+                 %assign %%pad %%pad + 32 ; shadow space
+-                %if mmsize != 8
+-                    %assign xmm_regs_used %2
+-                    %if xmm_regs_used > 8
+-                        %assign %%pad %%pad + (xmm_regs_used-8)*16 ; callee-saved xmm registers
+-                    %endif
++                %if xmm_regs_used > 8
++                    %assign %%pad %%pad + (xmm_regs_used-8)*16 ; callee-saved xmm registers
+                 %endif
+             %endif
+             %if required_stack_alignment <= STACK_ALIGNMENT
+                 ; maintain the current stack alignment
+                 %assign stack_size_padded stack_size + %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1))
++                PROBE_STACK stack_size_padded
+                 SUB rsp, stack_size_padded
+             %else
+                 %assign %%reg_num (regs_used - 1)
+                 %xdefine rstk r %+ %%reg_num
+                 ; align stack, and save original stack location directly above
+                 ; it, i.e. in [rsp+stack_size_padded], so we can restore the
+                 ; stack in a single instruction (i.e. mov rsp, rstk or mov
+                 ; rsp, [rsp+stack_size_padded])
+                 %if %1 < 0 ; need to store rsp on stack
+                     %xdefine rstkm [rsp + stack_size + %%pad]
+                     %assign %%pad %%pad + gprsize
+                 %else ; can keep rsp in rstk during whole function
+                     %xdefine rstkm rstk
+                 %endif
+                 %assign stack_size_padded stack_size + ((%%pad + required_stack_alignment-1) & ~(required_stack_alignment-1))
++                PROBE_STACK stack_size_padded
+                 mov rstk, rsp
+                 and rsp, ~(required_stack_alignment-1)
+                 sub rsp, stack_size_padded
+                 movifnidn rstkm, rstk
+             %endif
+             WIN64_PUSH_XMM
+         %endif
+     %endif
+ %endmacro
+ 
+-%macro SETUP_STACK_POINTER 1
++%macro SETUP_STACK_POINTER 0-1 0
+     %ifnum %1
+         %if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT
+             %if %1 > 0
+                 ; Reserve an additional register for storing the original stack pointer, but avoid using
+                 ; eax/rax for this purpose since it can potentially get overwritten as a return value.
+                 %assign regs_used (regs_used + 1)
+                 %if ARCH_X86_64 && regs_used == 7
+                     %assign regs_used 8
+@@ -457,45 +515,72 @@ DECLARE_REG 14, R13, 120
+         %else
+             DEFINE_ARGS %4, %5
+         %endif
+     %elifnnum %4
+         DEFINE_ARGS %4
+     %endif
+ %endmacro
+ 
+-%macro WIN64_PUSH_XMM 0
+-    ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated.
+-    %if xmm_regs_used > 6 + high_mm_regs
+-        movaps [rstk + stack_offset +  8], xmm6
+-    %endif
+-    %if xmm_regs_used > 7 + high_mm_regs
+-        movaps [rstk + stack_offset + 24], xmm7
+-    %endif
+-    %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8
+-    %if %%xmm_regs_on_stack > 0
+-        %assign %%i 8
+-        %rep %%xmm_regs_on_stack
+-            movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i
+-            %assign %%i %%i+1
+-        %endrep
++; Push XMM registers to the stack. If no argument is specified all used register
++; will be pushed, otherwise only push previously unpushed registers.
++%macro WIN64_PUSH_XMM 0-2 ; new_xmm_regs_used, xmm_regs_pushed
++    %if mmsize != 8
++        %if %0 == 2
++            %assign %%pushed %2
++            %assign xmm_regs_used %1
++        %elif %0 == 1
++            %assign %%pushed xmm_regs_used
++            %assign xmm_regs_used %1
++        %else
++            %assign %%pushed 0
++        %endif
++        ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated.
++        %if %%pushed <= 6 + high_mm_regs && xmm_regs_used > 6 + high_mm_regs
++            movaps [rstk + stack_offset +  8], xmm6
++        %endif
++        %if %%pushed <= 7 + high_mm_regs && xmm_regs_used > 7 + high_mm_regs
++            movaps [rstk + stack_offset + 24], xmm7
++        %endif
++        %assign %%pushed %%pushed - high_mm_regs - 8
++        %if %%pushed < 0
++            %assign %%pushed 0
++        %endif
++        %assign %%regs_to_push xmm_regs_used - %%pushed - high_mm_regs - 8
++        %if %%regs_to_push > 0
++            ASSERT (%%regs_to_push + %%pushed) * 16 <= stack_size_padded - stack_size - 32
++            %assign %%i %%pushed + 8
++            %rep %%regs_to_push
++                movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i
++                %assign %%i %%i+1
++            %endrep
++        %endif
+     %endif
+ %endmacro
+ 
+-%macro WIN64_SPILL_XMM 1
+-    %assign xmm_regs_used %1
+-    ASSERT xmm_regs_used <= 16 + high_mm_regs
+-    %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8
+-    %if %%xmm_regs_on_stack > 0
+-        ; Allocate stack space for callee-saved xmm registers plus shadow space and align the stack.
+-        %assign %%pad %%xmm_regs_on_stack*16 + 32
+-        %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1))
+-        SUB rsp, stack_size_padded
++; Allocated stack space for XMM registers and push all, or a subset, of those
++%macro WIN64_SPILL_XMM 1-2 ; xmm_regs_used, xmm_regs_reserved
++    RESET_STACK_STATE
++    %if mmsize != 8
++        %assign xmm_regs_used %1
++        ASSERT xmm_regs_used <= 16 + high_mm_regs
++        %if %0 == 2
++            ASSERT %2 >= %1
++            %assign %%xmm_regs_on_stack %2 - high_mm_regs - 8
++        %else
++            %assign %%xmm_regs_on_stack %1 - high_mm_regs - 8
++        %endif
++        %if %%xmm_regs_on_stack > 0
++            ; Allocate stack space for callee-saved xmm registers plus shadow space and align the stack.
++            %assign %%pad %%xmm_regs_on_stack*16 + 32
++            %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1))
++            SUB rsp, stack_size_padded
++        %endif
++        WIN64_PUSH_XMM
+     %endif
+-    WIN64_PUSH_XMM
+ %endmacro
+ 
+ %macro WIN64_RESTORE_XMM_INTERNAL 0
+     %assign %%pad_size 0
+     %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8
+     %if %%xmm_regs_on_stack > 0
+         %assign %%i xmm_regs_used - high_mm_regs
+         %rep %%xmm_regs_on_stack
+@@ -516,19 +601,17 @@ DECLARE_REG 14, R13, 120
+     %endif
+     %if xmm_regs_used > 6 + high_mm_regs
+         movaps xmm6, [rsp + stack_offset - %%pad_size +  8]
+     %endif
+ %endmacro
+ 
+ %macro WIN64_RESTORE_XMM 0
+     WIN64_RESTORE_XMM_INTERNAL
+-    %assign stack_offset (stack_offset-stack_size_padded)
+-    %assign stack_size_padded 0
+-    %assign xmm_regs_used 0
++    RESET_STACK_STATE
+ %endmacro
+ 
+ %define has_epilogue regs_used > 7 || stack_size > 0 || vzeroupper_required || xmm_regs_used > 6+high_mm_regs
+ 
+ %macro RET 0
+     WIN64_RESTORE_XMM_INTERNAL
+     POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7
+     %if vzeroupper_required
+@@ -553,22 +636,21 @@ DECLARE_REG 10, rbp, 40
+ DECLARE_REG 11, R14, 48
+ DECLARE_REG 12, R15, 56
+ DECLARE_REG 13, R12, 64
+ DECLARE_REG 14, R13, 72
+ 
+ %macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names...
+     %assign num_args %1
+     %assign regs_used %2
+-    %assign xmm_regs_used %3
+     ASSERT regs_used >= num_args
+     SETUP_STACK_POINTER %4
+     ASSERT regs_used <= 15
+     PUSH_IF_USED 9, 10, 11, 12, 13, 14
+-    ALLOC_STACK %4
++    ALLOC_STACK %4, %3
+     LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14
+     %if %0 > 4
+         %ifnum %4
+             DEFINE_ARGS %5
+         %else
+             DEFINE_ARGS %4, %5
+         %endif
+     %elifnnum %4
+@@ -622,17 +704,17 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
+         %assign num_args 7
+     %endif
+     %if regs_used > 7
+         %assign regs_used 7
+     %endif
+     SETUP_STACK_POINTER %4
+     ASSERT regs_used <= 7
+     PUSH_IF_USED 3, 4, 5, 6
+-    ALLOC_STACK %4
++    ALLOC_STACK %4, %3
+     LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6
+     %if %0 > 4
+         %ifnum %4
+             DEFINE_ARGS %5
+         %else
+             DEFINE_ARGS %4, %5
+         %endif
+     %elifnnum %4
+@@ -655,21 +737,29 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
+         vzeroupper
+     %endif
+     AUTO_REP_RET
+ %endmacro
+ 
+ %endif ;======================================================================
+ 
+ %if WIN64 == 0
+-    %macro WIN64_SPILL_XMM 1
++    %macro WIN64_SPILL_XMM 1-2
++        RESET_STACK_STATE
++        %if mmsize != 8
++            %assign xmm_regs_used %1
++        %endif
+     %endmacro
+     %macro WIN64_RESTORE_XMM 0
++        RESET_STACK_STATE
+     %endmacro
+-    %macro WIN64_PUSH_XMM 0
++    %macro WIN64_PUSH_XMM 0-2
++        %if mmsize != 8 && %0 >= 1
++            %assign xmm_regs_used %1
++        %endif
+     %endmacro
+ %endif
+ 
+ ; On AMD cpus <=K10, an ordinary ret is slow if it immediately follows either
+ ; a branch or a branch target. So switch to a 2-byte form of ret in that case.
+ ; We can automatically detect "follows a branch", but not a branch target.
+ ; (SSSE3 is a sufficient condition to know that your cpu doesn't have this problem.)
+ %macro REP_RET 0
+@@ -700,17 +790,17 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
+             %endif
+         %endmacro
+         %rotate 1
+     %endrep
+ %endmacro
+ 
+ BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, jna, jnae, jb, jbe, jnb, jnbe, jc, jnc, js, jns, jo, jno, jp, jnp
+ 
+-%macro TAIL_CALL 2 ; callee, is_nonadjacent
++%macro TAIL_CALL 1-2 1 ; callee, is_nonadjacent
+     %if has_epilogue
+         call %1
+         RET
+     %elif %2
+         jmp %1
+     %endif
+     annotate_function_size
+ %endmacro
+@@ -730,32 +820,35 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, 
+ %macro cglobal 1-2+ "" ; name, [PROLOGUE args]
+     cglobal_internal 1, %1 %+ SUFFIX, %2
+ %endmacro
+ %macro cvisible 1-2+ "" ; name, [PROLOGUE args]
+     cglobal_internal 0, %1 %+ SUFFIX, %2
+ %endmacro
+ %macro cglobal_internal 2-3+
+     annotate_function_size
+-    %if %1
+-        %xdefine %%FUNCTION_PREFIX private_prefix
+-        %xdefine %%VISIBILITY hidden
+-    %else
+-        %xdefine %%FUNCTION_PREFIX public_prefix
+-        %xdefine %%VISIBILITY
+-    %endif
+     %ifndef cglobaled_%2
+-        %xdefine %2 mangle(%%FUNCTION_PREFIX %+ _ %+ %2)
++        %if %1
++            %xdefine %2 mangle(private_prefix %+ _ %+ %2)
++        %else
++            %xdefine %2 mangle(public_prefix %+ _ %+ %2)
++        %endif
+         %xdefine %2.skip_prologue %2 %+ .skip_prologue
+         CAT_XDEFINE cglobaled_, %2, 1
+     %endif
+     %xdefine current_function %2
+     %xdefine current_function_section __SECT__
+     %if FORMAT_ELF
+-        global %2:function %%VISIBILITY
++        %if %1
++            global %2:function hidden
++        %else
++            global %2:function
++        %endif
++    %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN && %1
++        global %2:private_extern
+     %else
+         global %2
+     %endif
+     align function_align
+     %2:
+     RESET_MM_PERMUTATION        ; needed for x86-64, also makes disassembly somewhat nicer
+     %xdefine rstk rsp           ; copy of the original stack pointer, used when greater alignment than the known stack alignment is required
+     %assign stack_offset 0      ; stack pointer offset relative to the return address
+@@ -766,16 +859,18 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, 
+         PROLOGUE %3
+     %endif
+ %endmacro
+ 
+ ; Create a global symbol from a local label with the correct name mangling and type
+ %macro cglobal_label 1
+     %if FORMAT_ELF
+         global current_function %+ %1:function hidden
++    %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN
++        global current_function %+ %1:private_extern
+     %else
+         global current_function %+ %1
+     %endif
+     %1:
+ %endmacro
+ 
+ %macro cextern 1
+     %xdefine %1 mangle(private_prefix %+ _ %+ %1)
+@@ -791,25 +886,44 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, 
+     CAT_XDEFINE cglobaled_, %1, 1
+     extern %1
+ %endmacro
+ 
+ %macro const 1-2+
+     %xdefine %1 mangle(private_prefix %+ _ %+ %1)
+     %if FORMAT_ELF
+         global %1:data hidden
++    %elif FORMAT_MACHO && HAVE_PRIVATE_EXTERN
++        global %1:private_extern
+     %else
+         global %1
+     %endif
+     %1: %2
+ %endmacro
+ 
+-; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default.
+ %if FORMAT_ELF
++    ; The GNU linker assumes the stack is executable by default.
+     [SECTION .note.GNU-stack noalloc noexec nowrite progbits]
++
++    %ifdef __NASM_VERSION_ID__
++        %if __NASM_VERSION_ID__ >= 0x020e0300 ; 2.14.03
++            %if ARCH_X86_64
++                ; Control-flow Enforcement Technology (CET) properties.
++                [SECTION .note.gnu.property alloc noexec nowrite note align=gprsize]
++                dd 0x00000004  ; n_namesz
++                dd gprsize + 8 ; n_descsz
++                dd 0x00000005  ; n_type = NT_GNU_PROPERTY_TYPE_0
++                db "GNU",0     ; n_name
++                dd 0xc0000002  ; pr_type = GNU_PROPERTY_X86_FEATURE_1_AND
++                dd 0x00000004  ; pr_datasz
++                dd 0x00000002  ; pr_data = GNU_PROPERTY_X86_FEATURE_1_SHSTK
++                dd 0x00000000  ; pr_padding
++            %endif
++        %endif
++    %endif
+ %endif
+ 
+ ; Tell debuggers how large the function was.
+ ; This may be invoked multiple times per function; we rely on later instances overriding earlier ones.
+ ; This is invoked by RET and similar macros, and also cglobal does it for the previous function,
+ ; but if the last function in a source file doesn't use any of the standard macros for its epilogue,
+ ; then its size might be unspecified.
+ %macro annotate_function_size 0
+@@ -823,42 +937,44 @@ BRANCH_INSTR jz, je, jnz, jne, jl, jle, 
+             %endif
+         %endif
+     %endif
+ %endmacro
+ 
+ ; cpuflags
+ 
+ %assign cpuflags_mmx       (1<<0)
+-%assign cpuflags_mmx2      (1<<1) | cpuflags_mmx
+-%assign cpuflags_3dnow     (1<<2) | cpuflags_mmx
+-%assign cpuflags_3dnowext  (1<<3) | cpuflags_3dnow
+-%assign cpuflags_sse       (1<<4) | cpuflags_mmx2
+-%assign cpuflags_sse2      (1<<5) | cpuflags_sse
+-%assign cpuflags_sse2slow  (1<<6) | cpuflags_sse2
+-%assign cpuflags_lzcnt     (1<<7) | cpuflags_sse2
+-%assign cpuflags_sse3      (1<<8) | cpuflags_sse2
+-%assign cpuflags_ssse3     (1<<9) | cpuflags_sse3
+-%assign cpuflags_sse4      (1<<10)| cpuflags_ssse3
+-%assign cpuflags_sse42     (1<<11)| cpuflags_sse4
+-%assign cpuflags_aesni     (1<<12)| cpuflags_sse42
+-%assign cpuflags_avx       (1<<13)| cpuflags_sse42
+-%assign cpuflags_xop       (1<<14)| cpuflags_avx
+-%assign cpuflags_fma4      (1<<15)| cpuflags_avx
+-%assign cpuflags_fma3      (1<<16)| cpuflags_avx
+-%assign cpuflags_bmi1      (1<<17)| cpuflags_avx|cpuflags_lzcnt
+-%assign cpuflags_bmi2      (1<<18)| cpuflags_bmi1
+-%assign cpuflags_avx2      (1<<19)| cpuflags_fma3|cpuflags_bmi2
+-%assign cpuflags_avx512    (1<<20)| cpuflags_avx2 ; F, CD, BW, DQ, VL
+-%assign cpuflags_avx512icl (1<<25)| cpuflags_avx512
++%assign cpuflags_mmx2      (1<<1)  | cpuflags_mmx
++%assign cpuflags_3dnow     (1<<2)  | cpuflags_mmx
++%assign cpuflags_3dnowext  (1<<3)  | cpuflags_3dnow
++%assign cpuflags_sse       (1<<4)  | cpuflags_mmx2
++%assign cpuflags_sse2      (1<<5)  | cpuflags_sse
++%assign cpuflags_sse2slow  (1<<6)  | cpuflags_sse2
++%assign cpuflags_lzcnt     (1<<7)  | cpuflags_sse2
++%assign cpuflags_sse3      (1<<8)  | cpuflags_sse2
++%assign cpuflags_ssse3     (1<<9)  | cpuflags_sse3
++