)]}'
{
  "commit": "331c56b1cafa306552834e0ffbd4f516ec3e61fd",
  "tree": "f0f388c576d836ca9b9bde4d5a724f9cd4c816e6",
  "parents": [
    "8669fa8a9c40eae9c2980190dd61062d9f7bc8cb"
  ],
  "author": {
    "name": "Ihor Buhaiov",
    "email": "freedbrt@gmail.com",
    "time": "Mon Oct 26 12:49:22 2026 +0100"
  },
  "committer": {
    "name": "Jerome Jiang",
    "email": "jianj@google.com",
    "time": "Fri Nov 13 08:11:10 2026 -0800"
  },
  "message": "Keep the range coder state in registers\n\nEvery symbol the bitstream writer codes goes through an out of line\nod_ec_encode_cdf_q15() or od_ec_encode_bool_q15(). Each call loads low,\nrng and cnt from the od_ec_enc struct, branches on the symbol value,\nrenormalizes in od_ec_enc_normalize() and stores the state back. The\nnext symbol needs that state, so the store and the reload sit on the\ncritical chain, and the branches on coefficient levels and signs\nmispredict often. In real time screen encodes 61% to 88% of all symbols\ncome from av1_write_coeffs_txb().\n\nAdd od_ec_enc_state with low, rng and cnt, and inline symbol and bool\ncoders that work on it. A caller takes the state with\nod_ec_enc_get_state(), codes many symbols and puts it back with\nod_ec_enc_set_state() before any other call on the encoder. The byte\noutput part of the old normalize moves to od_ec_enc_flush(), which stays\nout of line and runs about once every 50 to 75 symbols. The new symbol\ncoder computes both ends of the range and selects, so it has no branch\non the symbol. The plain od_ec_encode_cdf_q15() and\nod_ec_encode_bool_q15() become wrappers over the same code.\n\nav1_write_coeffs_txb() keeps one state from the eob symbol to the last\nsign. It collects the nonzero coefficients without branches, so the sign\nloop has no data dependent branch, and writes the base range and golomb\ncodes with inline helpers. pack_map_tokens() keeps the state over the\npalette color indices. update_cdf() now computes both updates and\nselects one. The decoder shares it and runs at the same speed.\n\nThe output doesn\u0027t change: the arithmetic and the symbol order are the\nsame. Checked with stream hashes on Arm and x86, with MSVC and clang,\nand with the new EC_TEST.state_functions_match and\nAV1.TestWriteSymbolState tests. After a failed buffer realloc the state\nnow keeps changing where the old code froze it; od_ec_enc_done() still\nreturns NULL in both cases.\n\nRT speed 11, screen content, 3 screen recordings, fewer encoder cycles\nthan before, median of interleaved runs:\n\n  Apple M3 Pro, clang       4:2:0          4:4:4\n  1 thread                  2.1% to 4.5%   2.3% to 6.1%\n  4 threads                 2.4% to 3.2%   2.5% to 5.6%\n\n  AMD Ryzen 9 5900X, MSVC   4:2:0          4:4:4\n  1 thread                  3.0% to 4.5%   2.9% to 5.6%\n  4 threads                 2.0% to 4.1%   2.1% to 5.8%\n\nThe writer itself takes 28% to 32% fewer cycles on the M3 Pro. On a\n32 bit Arm phone the coder replay of recorded symbol streams is 1.37x\nto 1.40x faster on a Cortex A75 and 1.67x to 1.69x on a Cortex A55,\neven though the 64 bit low takes two registers there.\n\nChange-Id: Ib7db1b7a9e6081d9038e2ede9e679f9ff4a2b584\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "ea6a2cecdd8f4a5997cdb06b135be51c762dc023",
      "old_mode": 33188,
      "old_path": "aom_dsp/aom_dsp_common.h",
      "new_id": "7acd41f6bf5c565f90418d47be05a29fcffdd2d7",
      "new_mode": 33188,
      "new_path": "aom_dsp/aom_dsp_common.h"
    },
    {
      "type": "modify",
      "old_id": "35f82daefcd70e444957c4323c623620e9991d73",
      "old_mode": 33188,
      "old_path": "aom_dsp/bitwriter.h",
      "new_id": "d017da79d68199465e6e5f3f9f0c6ad77bf20800",
      "new_mode": 33188,
      "new_path": "aom_dsp/bitwriter.h"
    },
    {
      "type": "modify",
      "old_id": "a56fb89c490cb7f35758f7fc0e0fbe120aaecfbe",
      "old_mode": 33188,
      "old_path": "aom_dsp/entenc.c",
      "new_id": "f717aa5579ff951443fd746af067b99393ac73cf",
      "new_mode": 33188,
      "new_path": "aom_dsp/entenc.c"
    },
    {
      "type": "modify",
      "old_id": "dffe32dae554035a75bb1732b01614a7b0409184",
      "old_mode": 33188,
      "old_path": "aom_dsp/entenc.h",
      "new_id": "3976b3ad8315090d4349a5c3da0e07a5cfc0267b",
      "new_mode": 33188,
      "new_path": "aom_dsp/entenc.h"
    },
    {
      "type": "modify",
      "old_id": "8bec067ca802d1334b791ee395d78e02750dc4f1",
      "old_mode": 33188,
      "old_path": "aom_dsp/prob.h",
      "new_id": "5d6903c5b721440a30c022b409c26d1572ae8baf",
      "new_mode": 33188,
      "new_path": "aom_dsp/prob.h"
    },
    {
      "type": "modify",
      "old_id": "efac97a0367068d433b7dc971564a5ba007d673d",
      "old_mode": 33188,
      "old_path": "av1/encoder/bitstream.c",
      "new_id": "991ba725908a1e29ace0f3ccbcf39f6acec4f8b3",
      "new_mode": 33188,
      "new_path": "av1/encoder/bitstream.c"
    },
    {
      "type": "modify",
      "old_id": "baedd1320d169cefe15d6cd61f1020a22bc90b02",
      "old_mode": 33188,
      "old_path": "av1/encoder/encodetxb.c",
      "new_id": "41246d6973c0522ab796672c8ea012bda16464b7",
      "new_mode": 33188,
      "new_path": "av1/encoder/encodetxb.c"
    },
    {
      "type": "modify",
      "old_id": "3629bd71403dd50f533876651224119c4563776d",
      "old_mode": 33188,
      "old_path": "test/boolcoder_test.cc",
      "new_id": "6e5c8db6b551008079938e9f5090420efd5ed544",
      "new_mode": 33188,
      "new_path": "test/boolcoder_test.cc"
    },
    {
      "type": "modify",
      "old_id": "5586a60aae0a0f9c1cc17e7c01d6be2febd28c0b",
      "old_mode": 33188,
      "old_path": "test/ec_test.cc",
      "new_id": "65311cbbde2b227dd0134fc605d7bce593f5e3d1",
      "new_mode": 33188,
      "new_path": "test/ec_test.cc"
    }
  ]
}
