Create `video/timing` dir and implement `RtpPacketSimulator`.

This CL is the first in a chain, where the end goal is to create a video timing simulator. The simulator will take a `ParsedRtcEventLog` and produce a sequence of "rendered" frames, where the timing of the rendering should be completely determined by the logged RTP packets and the video jitter buffer components.

Big picture can be seen here: https://webrtc-review.googlesource.com/c/src/+/413840

In this CL, I'm creating the folder structure and implementing the `RtpPacketSimulator`. The `RtpPacketSimulator` is responsible for creating an `RtpPacketReceived` from a `LoggedRtpPacketIncoming`.

I'm also creating a new `rtc_test` binary (called `video_timing_tests`) that will contain all the unit tests for the upcoming simulator. For that, I followed https://webrtc.googlesource.com/src/+/refs/heads/main/g3doc/add-new-test-binary.md.

Tested: https://ci.chromium.org/ui/p/webrtc/builders/try/linux_rel/86942/test-results?q=RtpPacketSimulator+
Bug: b/423646186
Change-Id: I199e296f7bf2374f6f07638af3a23575c2a116cc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/413700
Reviewed-by: Jeremy Leconte <jleconte@google.com>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Commit-Queue: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#45822}
diff --git a/BUILD.gn b/BUILD.gn
index 8488cf0..5bbc5b7 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -78,6 +78,7 @@
         "video:screenshare_loopback",
         "video:sv_loopback",
         "video:video_loopback",
+        "video/timing:video_timing_tests",
       ]
       if (use_libfuzzer) {
         deps += [ "test/fuzzers" ]
diff --git a/infra/specs/client.webrtc.json b/infra/specs/client.webrtc.json
index c4824cd..90c56be 100644
--- a/infra/specs/client.webrtc.json
+++ b/infra/specs/client.webrtc.json
@@ -413,6 +413,26 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "android_devices": "1",
+            "device_type": "walleye",
+            "os": "Android"
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "enable": true,
@@ -908,6 +928,26 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "android_devices": "1",
+            "device_type": "walleye",
+            "os": "Android"
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "enable": true,
@@ -1431,6 +1471,26 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "android_devices": "1",
+            "device_type": "walleye",
+            "os": "Android"
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "enable": true,
@@ -1926,6 +1986,26 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "android_devices": "1",
+            "device_type": "walleye",
+            "os": "Android"
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "enable": true,
@@ -2664,6 +2744,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -3015,6 +3112,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -3366,6 +3480,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -3734,6 +3865,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -4102,6 +4250,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -4453,6 +4618,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -4805,6 +4987,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -5175,6 +5374,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -5544,6 +5760,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -5915,6 +6148,24 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cores": "12",
+            "cpu": "x86-64",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -6287,6 +6538,24 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cores": "12",
+            "cpu": "x86-64",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -6640,6 +6909,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -6991,6 +7277,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "arm64-64-Apple_M1",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -7367,6 +7670,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -7718,6 +8038,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -8069,6 +8406,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -8420,6 +8774,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -8462,7 +8833,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8493,7 +8864,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8511,7 +8882,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8542,7 +8913,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8559,7 +8930,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8590,7 +8961,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8607,7 +8978,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8638,7 +9009,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8655,7 +9026,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8686,7 +9057,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8703,7 +9074,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8734,7 +9105,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8751,7 +9122,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8782,7 +9153,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8799,7 +9170,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8830,7 +9201,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8847,7 +9218,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8878,7 +9249,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8895,7 +9266,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8926,7 +9297,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8943,7 +9314,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -8974,7 +9345,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -8992,7 +9363,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9023,7 +9394,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9041,7 +9412,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9073,7 +9444,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9091,7 +9462,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9123,7 +9494,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9141,7 +9512,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9172,7 +9543,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9189,7 +9560,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9220,7 +9591,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9237,7 +9608,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9268,7 +9639,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9285,7 +9656,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9316,7 +9687,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9333,7 +9704,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9364,7 +9735,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9381,7 +9752,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9412,7 +9783,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9429,7 +9800,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9460,7 +9831,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9477,7 +9848,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9508,7 +9879,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9526,7 +9897,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9557,7 +9928,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9575,7 +9946,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9606,7 +9977,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9624,7 +9995,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9655,7 +10026,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9673,7 +10044,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9704,7 +10075,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9721,7 +10092,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9753,7 +10124,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9771,7 +10142,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9803,7 +10174,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9821,7 +10192,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9852,7 +10223,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9869,7 +10240,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9900,7 +10271,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9917,7 +10288,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9948,7 +10319,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -9965,7 +10336,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -9996,7 +10367,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -10013,7 +10384,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -10044,7 +10415,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -10061,7 +10432,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -10092,7 +10463,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -10109,7 +10480,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -10140,7 +10511,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -10158,7 +10529,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -10189,7 +10560,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -10207,7 +10578,103 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xctest"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "video_timing_tests iPhone 14 17.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:4c7290150d1c360cecc6a93c0214dc531585c3ab"
+            }
+          ],
+          "dimensions": {
+            "cpu": "arm64",
+            "os": "Mac-15"
+          },
+          "named_caches": [
+            {
+              "name": "runtime_ios_17_5",
+              "path": "Runtime-ios-17.5"
+            },
+            {
+              "name": "xcode_ios_17a324",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/",
+        "variant_id": "iPhone 14 17.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 15",
+          "--version",
+          "18.2",
+          "--xcode-build-version",
+          "17a324",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xctest"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "video_timing_tests iPhone 15 18.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:4c7290150d1c360cecc6a93c0214dc531585c3ab"
+            }
+          ],
+          "dimensions": {
+            "cpu": "arm64",
+            "os": "Mac-15"
+          },
+          "named_caches": [
+            {
+              "name": "runtime_ios_18_2",
+              "path": "Runtime-ios-18.2"
+            },
+            {
+              "name": "xcode_ios_17a324",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/",
+        "variant_id": "iPhone 15 18.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 14",
+          "--version",
+          "17.5",
+          "--xcode-build-version",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -10238,7 +10705,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -10255,7 +10722,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -10286,7 +10753,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -10303,7 +10770,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -10334,7 +10801,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -10351,7 +10818,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -10382,7 +10849,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
diff --git a/infra/specs/gn_isolate_map.pyl b/infra/specs/gn_isolate_map.pyl
index 20de759..7e751ba 100644
--- a/infra/specs/gn_isolate_map.pyl
+++ b/infra/specs/gn_isolate_map.pyl
@@ -140,6 +140,10 @@
     "label": "//:video_engine_tests",
     "type": "console_test_launcher",
   },
+  "video_timing_tests": {
+    "label": "//video/timing:video_timing_tests",
+    "type": "console_test_launcher",
+  },
   "voip_unittests": {
     "label": "//:voip_unittests",
     "type": "console_test_launcher",
diff --git a/infra/specs/internal.client.webrtc.json b/infra/specs/internal.client.webrtc.json
index d8e9e77..54c6712 100644
--- a/infra/specs/internal.client.webrtc.json
+++ b/infra/specs/internal.client.webrtc.json
@@ -7,7 +7,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -33,7 +33,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -46,7 +46,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -72,7 +72,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -86,7 +86,7 @@
           "--readline-timeout=1200",
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -114,7 +114,7 @@
           "io_timeout": 7200,
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -128,7 +128,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -154,7 +154,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -168,7 +168,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -194,7 +194,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -207,7 +207,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -233,7 +233,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -246,7 +246,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -272,7 +272,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -285,7 +285,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -311,7 +311,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -324,7 +324,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -350,7 +350,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -363,7 +363,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -389,7 +389,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -402,7 +402,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -428,7 +428,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -448,7 +448,7 @@
           "--write_perf_output_on_ios",
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -482,7 +482,7 @@
           "io_timeout": 10800,
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -499,7 +499,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -525,7 +525,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -538,7 +538,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -564,7 +564,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -578,7 +578,7 @@
           "--readline-timeout=1200",
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -606,7 +606,7 @@
           "io_timeout": 7200,
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -620,7 +620,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -646,7 +646,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -660,7 +660,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -686,7 +686,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -699,7 +699,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -725,7 +725,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -738,7 +738,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -764,7 +764,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -777,7 +777,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -803,7 +803,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -816,7 +816,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -842,7 +842,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -855,7 +855,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -881,7 +881,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -894,7 +894,7 @@
         "args": [
           "--xctest",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}"
         ],
@@ -920,7 +920,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
diff --git a/infra/specs/mixins.pyl b/infra/specs/mixins.pyl
index ae09488..51b1bf7 100644
--- a/infra/specs/mixins.pyl
+++ b/infra/specs/mixins.pyl
@@ -300,10 +300,10 @@
     }
   },
   'xcode_26_main': {
-    'args': ['--xcode-build-version', '17a5305f'],
+    'args': ['--xcode-build-version', '17a324'],
     'swarming': {
       'named_caches': [{
-        'name': 'xcode_ios_17a5305f',
+        'name': 'xcode_ios_17a324',
         'path': 'Xcode.app'
       }]
     }
diff --git a/infra/specs/test_suites.pyl b/infra/specs/test_suites.pyl
index 0dc2ab9..e8a45c5 100644
--- a/infra/specs/test_suites.pyl
+++ b/infra/specs/test_suites.pyl
@@ -52,6 +52,7 @@
       'video_engine_tests': {
         'mixins': ['shards-4'],
       },
+      'video_timing_tests': {},
       'voip_unittests': {},
       'webrtc_nonparallel_tests': {},
     },
@@ -96,6 +97,7 @@
       'video_engine_tests': {
         'mixins': ['shards-4'],
       },
+      'video_timing_tests': {},
       'voip_unittests': {},
       'webrtc_nonparallel_tests': {},
     },
@@ -205,6 +207,7 @@
       'video_engine_tests': {
         'mixins': ['shards-4'],
       },
+      'video_timing_tests': {},
       'voip_unittests': {},
       'webrtc_nonparallel_tests': {},
     },
diff --git a/infra/specs/tryserver.webrtc.json b/infra/specs/tryserver.webrtc.json
index e4e4f36..721ec29 100644
--- a/infra/specs/tryserver.webrtc.json
+++ b/infra/specs/tryserver.webrtc.json
@@ -438,6 +438,26 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "android_devices": "1",
+            "device_type": "walleye",
+            "os": "Android"
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "enable": true,
@@ -982,6 +1002,26 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "android_devices": "1",
+            "device_type": "walleye",
+            "os": "Android"
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "enable": true,
@@ -1526,6 +1566,26 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "android_devices": "1",
+            "device_type": "walleye",
+            "os": "Android"
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "enable": true,
@@ -2095,6 +2155,26 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "android_devices": "1",
+            "device_type": "walleye",
+            "os": "Android"
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "enable": true,
@@ -2516,7 +2596,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2547,7 +2627,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2565,7 +2645,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2596,7 +2676,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2613,7 +2693,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2644,7 +2724,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2661,7 +2741,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2692,7 +2772,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2709,7 +2789,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2740,7 +2820,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2757,7 +2837,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2788,7 +2868,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2805,7 +2885,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2836,7 +2916,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2853,7 +2933,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2884,7 +2964,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2901,7 +2981,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2932,7 +3012,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2949,7 +3029,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -2980,7 +3060,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -2997,7 +3077,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3028,7 +3108,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3046,7 +3126,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3077,7 +3157,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3095,7 +3175,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3127,7 +3207,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3145,7 +3225,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3177,7 +3257,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3195,7 +3275,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3226,7 +3306,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3243,7 +3323,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3274,7 +3354,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3291,7 +3371,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3322,7 +3402,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3339,7 +3419,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3370,7 +3450,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3387,7 +3467,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3418,7 +3498,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3435,7 +3515,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3466,7 +3546,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3483,7 +3563,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3514,7 +3594,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3531,7 +3611,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3562,7 +3642,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3580,7 +3660,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3611,7 +3691,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3629,7 +3709,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3660,7 +3740,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3678,7 +3758,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3709,7 +3789,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3727,7 +3807,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3758,7 +3838,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3775,7 +3855,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3807,7 +3887,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3825,7 +3905,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3857,7 +3937,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3875,7 +3955,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3906,7 +3986,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3923,7 +4003,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -3954,7 +4034,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -3971,7 +4051,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4002,7 +4082,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4019,7 +4099,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4050,7 +4130,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4067,7 +4147,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4098,7 +4178,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4115,7 +4195,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4146,7 +4226,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4163,7 +4243,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4194,7 +4274,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4212,7 +4292,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4243,7 +4323,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4261,7 +4341,103 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xctest"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "video_timing_tests iPhone 14 17.5",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:4c7290150d1c360cecc6a93c0214dc531585c3ab"
+            }
+          ],
+          "dimensions": {
+            "cpu": "arm64",
+            "os": "Mac-15"
+          },
+          "named_caches": [
+            {
+              "name": "runtime_ios_17_5",
+              "path": "Runtime-ios-17.5"
+            },
+            {
+              "name": "xcode_ios_17a324",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/",
+        "variant_id": "iPhone 14 17.5"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 15",
+          "--version",
+          "18.2",
+          "--xcode-build-version",
+          "17a324",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xctest"
+        ],
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "video_timing_tests iPhone 15 18.2",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:4c7290150d1c360cecc6a93c0214dc531585c3ab"
+            }
+          ],
+          "dimensions": {
+            "cpu": "arm64",
+            "os": "Mac-15"
+          },
+          "named_caches": [
+            {
+              "name": "runtime_ios_18_2",
+              "path": "Runtime-ios-18.2"
+            },
+            {
+              "name": "xcode_ios_17a324",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/",
+        "variant_id": "iPhone 15 18.2"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 14",
+          "--version",
+          "17.5",
+          "--xcode-build-version",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4292,7 +4468,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4309,7 +4485,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4340,7 +4516,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4357,7 +4533,7 @@
           "--version",
           "17.5",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4388,7 +4564,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4405,7 +4581,7 @@
           "--version",
           "18.2",
           "--xcode-build-version",
-          "17a5305f",
+          "17a324",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xctest"
@@ -4436,7 +4612,7 @@
               "path": "Runtime-ios-18.2"
             },
             {
-              "name": "xcode_ios_17a5305f",
+              "name": "xcode_ios_17a324",
               "path": "Xcode.app"
             }
           ],
@@ -4785,6 +4961,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -5203,6 +5396,24 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "isolate_profile_data": true,
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -5596,6 +5807,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -5970,6 +6198,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -6361,6 +6606,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -6735,6 +6997,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -7103,6 +7382,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -7471,6 +7767,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -7822,6 +8135,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -8173,6 +8503,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Ubuntu-22.04"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -8542,6 +8889,24 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cores": "12",
+            "cpu": "x86-64",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -8915,6 +9280,24 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cores": "12",
+            "cpu": "x86-64",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -9268,6 +9651,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "arm64-64-Apple_M1",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -9642,6 +10042,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -10016,6 +10433,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "arm64-64-Apple_M1",
+            "os": "Mac-15"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -10367,6 +10801,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-11-22000"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -10741,6 +11192,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-11-22000"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -11115,6 +11583,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -11470,6 +11955,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -11821,6 +12323,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -12172,6 +12691,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
@@ -12546,6 +13082,23 @@
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
+        "name": "video_timing_tests",
+        "resultdb": {
+          "result_format": "json"
+        },
+        "swarming": {
+          "dimensions": {
+            "cpu": "x86-64",
+            "os": "Windows-10-19045"
+          }
+        },
+        "test": "video_timing_tests",
+        "test_id_prefix": "ninja://video/timing:video_timing_tests/"
+      },
+      {
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
         "name": "voip_unittests",
         "resultdb": {
           "result_format": "json"
diff --git a/video/timing/BUILD.gn b/video/timing/BUILD.gn
new file mode 100644
index 0000000..3228914
--- /dev/null
+++ b/video/timing/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS.  All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+if (rtc_include_tests) {
+  rtc_test("video_timing_tests") {
+    testonly = true
+    deps = [ "../../test:test_main" ]
+
+    if (rtc_enable_protobuf) {
+      deps += [ "simulator:simulator_tests" ]
+    }
+  }
+}
diff --git a/video/timing/OWNERS b/video/timing/OWNERS
new file mode 100644
index 0000000..fe76628
--- /dev/null
+++ b/video/timing/OWNERS
@@ -0,0 +1 @@
+brandtr@webrtc.org
diff --git a/video/timing/README.md b/video/timing/README.md
new file mode 100644
index 0000000..1e83ae1
--- /dev/null
+++ b/video/timing/README.md
@@ -0,0 +1,6 @@
+# `video/timing`
+
+This directory contains classes related to the video timing components of the
+video jitter buffer.
+
+* `simulator/`: An RtcEventLog-based simulator of the video jitter buffer.
\ No newline at end of file
diff --git a/video/timing/simulator/BUILD.gn b/video/timing/simulator/BUILD.gn
new file mode 100644
index 0000000..0436571
--- /dev/null
+++ b/video/timing/simulator/BUILD.gn
@@ -0,0 +1,43 @@
+# Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS.  All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+if (rtc_enable_protobuf) {
+  rtc_library("simulator") {
+    sources = [
+      "rtp_packet_simulator.cc",
+      "rtp_packet_simulator.h",
+    ]
+    deps = [
+      "../../../api:rtp_headers",
+      "../../../api/environment",
+      "../../../logging:rtc_event_log_parser",
+      "../../../logging:rtc_event_rtp_rtcp",
+      "../../../modules/rtp_rtcp:rtp_rtcp_format",
+    ]
+  }
+
+  if (rtc_include_tests) {
+    rtc_library("simulator_tests") {
+      testonly = true
+      sources = [ "rtp_packet_simulator_unittest.cc" ]
+      deps = [
+        ":simulator",
+        "../../../api:rtp_headers",
+        "../../../api/environment",
+        "../../../api/units:timestamp",
+        "../../../logging:rtc_event_rtp_rtcp",
+        "../../../modules/rtp_rtcp:rtp_rtcp_format",
+        "../../../system_wrappers",
+        "../../../test:create_test_environment",
+        "../../../test:test_support",
+      ]
+    }
+  }
+}
diff --git a/video/timing/simulator/README.md b/video/timing/simulator/README.md
new file mode 100644
index 0000000..420e040
--- /dev/null
+++ b/video/timing/simulator/README.md
@@ -0,0 +1,20 @@
+# `video/timing/simulator`
+
+This directory contains classes related to RtcEventLog-based simulation of video
+timing and video jitter buffering.
+
+The simulator uses recorded RtcEventLog files, which contain time-stamped events
+from a WebRTC session, to reconstruct and simulate the timing aspects of
+received video streams. This allows for:
+
+* Replaying Scenarios: Analyzing how different timing algorithms or network
+  conditions would affect video performance by replaying logs from real-world
+  sessions.
+* Algorithm Evaluation: Testing and comparing different timing algorithms
+  offline using realistic event sequences.
+* Debugging: Understanding timing-related issues observed in production by
+  stepping through the events as they occurred.
+
+The simulation focuses on aspects like frame arrival times, decoding times,
+rendering times, and the overall flow of video frames through a simulated
+pipeline, driven by the events logged in the RtcEventLog.
diff --git a/video/timing/simulator/rtp_packet_simulator.cc b/video/timing/simulator/rtp_packet_simulator.cc
new file mode 100644
index 0000000..cfdb94b
--- /dev/null
+++ b/video/timing/simulator/rtp_packet_simulator.cc
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#include "video/timing/simulator/rtp_packet_simulator.h"
+
+#include "api/environment/environment.h"
+#include "api/rtp_headers.h"
+#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
+#include "logging/rtc_event_log/rtc_event_log_parser.h"
+#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
+#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
+#include "modules/rtp_rtcp/source/rtp_packet_received.h"
+
+namespace webrtc::video_frame_simulator {
+
+RtpPacketSimulator::RtpPacketSimulator(Environment env)
+    : env_(env),
+      rtp_header_extension_map_(
+          ParsedRtcEventLog::GetDefaultHeaderExtensionMap()) {}
+
+RtpPacketReceived RtpPacketSimulator::SimulateRtpPacketReceived(
+    const LoggedRtpPacketIncoming& logged_packet) {
+  RtpPacketReceived rtp_packet(&rtp_header_extension_map_);
+  rtp_packet.set_arrival_time(env_.clock().CurrentTime());
+
+  // RTP header.
+  const RTPHeader& header = logged_packet.rtp.header;
+  rtp_packet.SetMarker(header.markerBit);
+  rtp_packet.SetPayloadType(header.payloadType);
+  rtp_packet.SetSequenceNumber(header.sequenceNumber);
+  rtp_packet.SetTimestamp(header.timestamp);
+  rtp_packet.SetSsrc(header.ssrc);
+
+  // RTP header extensions.
+  const RTPHeaderExtension& extension = header.extension;
+  if (extension.hasTransportSequenceNumber) {
+    rtp_packet.SetExtension<TransportSequenceNumber>(
+        extension.transportSequenceNumber);
+  }
+  if (extension.hasTransmissionTimeOffset) {
+    rtp_packet.SetExtension<TransmissionOffset>(
+        extension.transmissionTimeOffset);
+  }
+  if (extension.hasAbsoluteSendTime) {
+    rtp_packet.SetExtension<AbsoluteSendTime>(extension.absoluteSendTime);
+  }
+  rtp_packet.SetRawExtension<RtpDependencyDescriptorExtension>(
+      logged_packet.rtp.dependency_descriptor_wire_format);
+
+  // Payload and padding.
+  rtp_packet.AllocatePayload(logged_packet.rtp.total_length -
+                             logged_packet.rtp.header_length -
+                             header.paddingLength);
+  rtp_packet.SetPadding(header.paddingLength);
+
+  return rtp_packet;
+}
+
+}  // namespace webrtc::video_frame_simulator
diff --git a/video/timing/simulator/rtp_packet_simulator.h b/video/timing/simulator/rtp_packet_simulator.h
new file mode 100644
index 0000000..572b06a
--- /dev/null
+++ b/video/timing/simulator/rtp_packet_simulator.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef VIDEO_TIMING_SIMULATOR_RTP_PACKET_SIMULATOR_H_
+#define VIDEO_TIMING_SIMULATOR_RTP_PACKET_SIMULATOR_H_
+
+#include "api/environment/environment.h"
+#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
+#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
+#include "modules/rtp_rtcp/source/rtp_packet_received.h"
+
+namespace webrtc::video_frame_simulator {
+
+class RtpPacketSimulator {
+ public:
+  explicit RtpPacketSimulator(Environment env);
+  ~RtpPacketSimulator() = default;
+
+  RtpPacketSimulator(const RtpPacketSimulator&) = delete;
+  RtpPacketSimulator& operator=(const RtpPacketSimulator&) = delete;
+
+  // Builds a simulated `RtpPacketReceived` from a `LoggedRtpPacketIncoming`.
+  // Notably, the simulated arrival time is taken from `env_.clock()` and not
+  // from `logged_packet.log_time()`. This allows the caller to provide its own
+  // clock offset, that might be different from the logged time base.
+  RtpPacketReceived SimulateRtpPacketReceived(
+      const LoggedRtpPacketIncoming& logged_packet);
+
+ private:
+  const Environment env_;
+  const RtpHeaderExtensionMap rtp_header_extension_map_;
+};
+
+}  // namespace webrtc::video_frame_simulator
+
+#endif  // VIDEO_TIMING_SIMULATOR_RTP_PACKET_SIMULATOR_H_
diff --git a/video/timing/simulator/rtp_packet_simulator_unittest.cc b/video/timing/simulator/rtp_packet_simulator_unittest.cc
new file mode 100644
index 0000000..4cd27d2
--- /dev/null
+++ b/video/timing/simulator/rtp_packet_simulator_unittest.cc
@@ -0,0 +1,122 @@
+/*
+ *  Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#include "video/timing/simulator/rtp_packet_simulator.h"
+
+#include "api/environment/environment.h"
+#include "api/rtp_headers.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
+#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
+#include "modules/rtp_rtcp/source/rtp_packet_received.h"
+#include "system_wrappers/include/clock.h"
+#include "test/create_test_environment.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc::video_frame_simulator {
+namespace {
+
+constexpr int kBaseRtpHeaderSize = 12;
+
+using ::testing::Eq;
+
+TEST(RtpPacketSimulatorTest, SimulatesArrivalTimeFromEnvironmentClock) {
+  SimulatedClock clock(/*initial_time=*/Timestamp::Seconds(10000));
+  Environment env =
+      CreateTestEnvironment(CreateTestEnvironmentOptions{.time = &clock});
+  RtpPacketSimulator simulator(env);
+
+  LoggedRtpPacketIncoming logged_packet(
+      /*timestamp=*/Timestamp::Millis(123456789), RTPHeader(),
+      /*header_length=*/kBaseRtpHeaderSize,
+      /*total_length=*/kBaseRtpHeaderSize);
+  RtpPacketReceived rtp_packet =
+      simulator.SimulateRtpPacketReceived(logged_packet);
+
+  EXPECT_EQ(rtp_packet.arrival_time(), Timestamp::Seconds(10000));
+}
+
+TEST(RtpPacketSimulatorTest, SimulatesRtpHeader) {
+  SimulatedClock clock(/*initial_time=*/Timestamp::Seconds(10000));
+  Environment env =
+      CreateTestEnvironment(CreateTestEnvironmentOptions{.time = &clock});
+  RtpPacketSimulator simulator(env);
+
+  RTPHeader logged_rtp_header;
+  logged_rtp_header.markerBit = 1;
+  logged_rtp_header.payloadType = 98;
+  logged_rtp_header.sequenceNumber = 123;
+  logged_rtp_header.timestamp = 5235235;
+  logged_rtp_header.ssrc = 83653358;
+  LoggedRtpPacketIncoming logged_packet(
+      /*timestamp=*/Timestamp::Millis(123456789), logged_rtp_header,
+      /*header_length=*/kBaseRtpHeaderSize,
+      /*total_length=*/kBaseRtpHeaderSize);
+  RtpPacketReceived rtp_packet =
+      simulator.SimulateRtpPacketReceived(logged_packet);
+
+  EXPECT_TRUE(rtp_packet.Marker());
+  EXPECT_THAT(rtp_packet.PayloadType(), Eq(98));
+  EXPECT_THAT(rtp_packet.SequenceNumber(), Eq(123));
+  EXPECT_THAT(rtp_packet.Timestamp(), Eq(5235235));
+  EXPECT_THAT(rtp_packet.Ssrc(), Eq(83653358));
+}
+
+TEST(RtpPacketSimulatorTest, SimulatesBasicRtpHeaderExtensions) {
+  SimulatedClock clock(/*initial_time=*/Timestamp::Seconds(10000));
+  Environment env =
+      CreateTestEnvironment(CreateTestEnvironmentOptions{.time = &clock});
+  RtpPacketSimulator simulator(env);
+
+  RTPHeader logged_rtp_header;
+  auto& logged_extension = logged_rtp_header.extension;
+  logged_extension.transportSequenceNumber = 99;
+  logged_extension.hasTransportSequenceNumber = true;
+  logged_extension.transmissionTimeOffset = 887766;
+  logged_extension.hasTransmissionTimeOffset = true;
+  logged_extension.absoluteSendTime = 11223344;
+  logged_extension.hasAbsoluteSendTime = true;
+  LoggedRtpPacketIncoming logged_packet(
+      /*timestamp=*/Timestamp::Millis(123456789), logged_rtp_header,
+      /*header_length=*/kBaseRtpHeaderSize,
+      /*total_length=*/kBaseRtpHeaderSize);
+  RtpPacketReceived rtp_packet =
+      simulator.SimulateRtpPacketReceived(logged_packet);
+
+  EXPECT_THAT(rtp_packet.GetExtension<TransportSequenceNumber>(), Eq(99));
+  EXPECT_THAT(rtp_packet.GetExtension<TransmissionOffset>(), Eq(887766));
+  EXPECT_THAT(rtp_packet.GetExtension<AbsoluteSendTime>(), Eq(11223344));
+}
+
+// TODO(b/423646186): Add test for dependency descriptor.
+
+TEST(RtpPacketSimulatorTest, SimulatesSizes) {
+  SimulatedClock clock(/*initial_time=*/Timestamp::Seconds(10000));
+  Environment env =
+      CreateTestEnvironment(CreateTestEnvironmentOptions{.time = &clock});
+  RtpPacketSimulator simulator(env);
+
+  RTPHeader logged_header;
+  logged_header.paddingLength = 100;
+  LoggedRtpPacketIncoming logged_packet(
+      /*timestamp=*/Timestamp::Millis(123456789), logged_header,
+      /*header_length=*/kBaseRtpHeaderSize,
+      /*total_length=*/1200);
+  RtpPacketReceived rtp_packet =
+      simulator.SimulateRtpPacketReceived(logged_packet);
+
+  EXPECT_THAT(rtp_packet.size(), Eq(1200));
+  EXPECT_THAT(rtp_packet.payload_size(), Eq(1088));
+  EXPECT_THAT(rtp_packet.padding_size(), Eq(100));
+}
+
+}  // namespace
+
+}  // namespace webrtc::video_frame_simulator