From 7a9e9627c3e62092499f7f1a8593622a6ccfb053 Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 09:32:32 -0800 Subject: [PATCH 01/12] Added EDL test cases --- tests/edls/cdl_example01.edl | 226 ++++++++++++++++++++++++++++++ tests/edls/cdl_example02.cdl | 17 +++ tests/edls/cdl_frmc_example01.edl | 7 + tests/edls/cdl_frmc_example02.edl | 123 ++++++++++++++++ 4 files changed, 373 insertions(+) create mode 100644 tests/edls/cdl_example01.edl create mode 100644 tests/edls/cdl_example02.cdl create mode 100644 tests/edls/cdl_frmc_example01.edl create mode 100644 tests/edls/cdl_frmc_example02.edl diff --git a/tests/edls/cdl_example01.edl b/tests/edls/cdl_example01.edl new file mode 100644 index 0000000..4b111fe --- /dev/null +++ b/tests/edls/cdl_example01.edl @@ -0,0 +1,226 @@ +TITLE: cdl_example01 +FCM: NON-DROP FRAME +000001 B_0031C010_241010_133208_h1C2T V C 13:30:27:13 13:30:29:01 02:13:08:12 02:13:10:00 +*FROM CLIP NAME: 117C-3-B +*LOC: 02:13:08:12 Green Sc 117 INTERCUT +*ASC_SOP (0.9405 0.9439 0.9424)(-0.0500 -0.0276 -0.0144)(0.8888 0.9138 0.9896) +*ASC_SAT 0.9640 +000002 B_0031C009_241010_132827_h1C2T V C 13:26:36:14 13:26:38:03 02:13:10:00 02:13:11:13 +*VFX 117_GUD_0030 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117C-2-B +*LOC: 02:13:10:04 White VFX 117_GUD_0030 add Norway landscape +*ASC_SOP (0.9282 0.9312 0.9296)(-0.0362 -0.0138 -0.0006)(0.8888 0.9138 0.9896) +*ASC_SAT 0.9640 +000003 A_0038C002_241010_114016_h1EHP V C 12:41:35:05 12:41:41:11 02:13:12:13 02:13:18:19 +*VFX 117_GUD_0060 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117A-2-A +*LOC: 02:13:17:01 White VFX 117_GUD_0060 add Norway landscape +*ASC_SOP (0.8315 0.8307 0.8290)(0.0301 0.0416 0.0435)(0.9351 0.9413 0.9816) +*ASC_SAT 0.9640 +000004 A_0038C016_241010_130056_h1EHP V C 14:02:14:03 14:02:15:03 02:13:18:19 02:13:19:19 +*VFX 117_GUD_0070 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117F-2 +*LOC: 02:13:19:02 White VFX 117_GUD_0070 add Norway landscape +*ASC_SOP (0.9129 0.9045 0.8950)(0.0197 0.0394 0.0495)(0.9274 0.9472 0.9931) +*ASC_SAT 0.9640 +000005 A_0038C006_241010_120437_h1EHP V C 13:06:10:07 13:06:11:08 02:13:19:19 02:13:20:20 +*VFX 117_GUD_0080 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117B-4-A +*LOC: 02:13:20:07 White VFX 117_GUD_0080 add Norway landscape +*ASC_SOP (0.8650 0.8604 0.8535)(0.0160 0.0319 0.0397)(0.9235 0.9485 0.9937) +*ASC_SAT 0.9640 +000006 B_0031C005_241010_130536_h1C2T V C 13:03:45:20 13:03:47:14 02:13:20:20 02:13:22:14 +*VFX 117_GUD_0090 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117B-3-B +*LOC: 02:13:21:07 White VFX 117_GUD_0090 add Norway landscape +*ASC_SOP (0.7644 0.7755 0.7640)(0.0194 0.0392 0.0557)(0.8384 0.8687 0.9321) +*ASC_SAT 0.9640 +000007 A_0038C016_241010_130056_h1EHP V C 14:02:21:15 14:02:24:12 02:13:22:14 02:13:25:11 +*VFX 117_GUD_0100 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117F-2 +*LOC: 02:13:24:07 White VFX 117_GUD_0100 add Norway landscape +*ASC_SOP (0.9129 0.9045 0.8950)(0.0197 0.0394 0.0495)(0.9274 0.9472 0.9931) +*ASC_SAT 0.9640 +000008 A_0038C006_241010_120437_h1EHP V C 13:06:16:18 13:06:23:09 02:13:25:11 02:13:32:02 +*VFX 117_GUD_0110 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117B-4-A +*LOC: 02:13:28:06 White VFX 117_GUD_0110 add Norway landscape +*ASC_SOP (0.8650 0.8604 0.8535)(0.0160 0.0319 0.0397)(0.9235 0.9485 0.9937) +*ASC_SAT 0.9640 +000009 A_0038C011_241010_123111_h1EHP V C 13:32:49:04 13:32:51:01 02:13:32:02 02:13:33:23 +*FROM CLIP NAME: 117C-4 +*ASC_SOP (0.8656 0.8610 0.8542)(0.0153 0.0312 0.0389)(0.9318 0.9425 0.9884) +*ASC_SAT 0.9640 +000010 A_0038C006_241010_120437_h1EHP V C 13:06:25:06 13:06:27:14 02:13:33:23 02:13:36:07 +*VFX 117_GUD_0120 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117B-4-A +*LOC: 02:13:35:01 White VFX 117_GUD_0120 add Norway landscape +*ASC_SOP (0.8650 0.8604 0.8535)(0.0160 0.0319 0.0397)(0.9235 0.9485 0.9937) +*ASC_SAT 0.9640 +000011 A_0038C011_241010_123111_h1EHP V C 13:32:53:16 13:32:54:23 02:13:36:07 02:13:37:14 +*FROM CLIP NAME: 117C-4 +*ASC_SOP (0.8656 0.8610 0.8542)(0.0153 0.0312 0.0389)(0.9318 0.9425 0.9884) +*ASC_SAT 0.9640 +000012 A_0038C006_241010_120437_h1EHP V C 13:06:30:14 13:06:34:01 02:13:37:14 02:13:41:01 +*VFX 117_GUD_0130 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117B-4-A +*LOC: 02:13:39:05 White VFX 117_GUD_0130 add Norway landscape +*ASC_SOP (0.8650 0.8604 0.8535)(0.0160 0.0319 0.0397)(0.9235 0.9485 0.9937) +*ASC_SAT 0.9640 +000013 A_0038C012_241010_124231_h1EHP V C 13:44:10:05 13:44:12:06 02:13:41:01 02:13:43:02 +*VFX 117_GUD_0140 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117D-1 +*LOC: 02:13:42:03 White VFX 117_GUD_0140 add Norway landscape +*ASC_SOP (0.8791 0.8754 0.8660)(-0.0000 0.0150 0.0256)(0.9310 0.9432 0.9893) +*ASC_SAT 0.9640 +000014 A_0038C014_241010_125128_h1EHP V C 13:52:56:16 13:53:01:13 02:13:43:02 02:13:47:23 +*VFX 117_GUD_0150 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 117E-2 PU +*LOC: 02:13:45:10 White VFX 117_GUD_0150 add Norway landscape +*ASC_SOP (0.9320 0.9203 0.9093)(-0.0262 -0.0022 0.0097)(0.9196 0.9569 1.0007) +*ASC_SAT 0.9640 +000015 D006C0011_241001_Q3J911 V C 14:26:00:22 14:26:03:23 02:13:47:23 02:13:51:00 +*FROM CLIP NAME: 121B-4* +*LOC: 02:13:47:23 Green Sc 121 +*ASC_SOP (0.9688 0.9286 0.9044)(-0.0050 0.0335 0.0584)(1.0019 1.0499 1.0817) +*ASC_SAT 0.8500 +000016 D006C0013_241001_Q3J911 V C 14:38:25:03 14:38:27:00 02:13:51:00 02:13:52:21 +*FROM CLIP NAME: 121C-2 +*ASC_SOP (0.9700 0.9296 0.9054)(-0.0053 0.0332 0.0581)(0.9871 1.0506 1.0894) +*ASC_SAT 0.8500 +000017 D006C0011_241001_Q3J911 V C 14:26:10:22 14:26:13:15 02:13:52:21 02:13:55:14 +*FROM CLIP NAME: 121B-4* +*ASC_SOP (0.9688 0.9286 0.9044)(-0.0050 0.0335 0.0584)(1.0019 1.0499 1.0817) +*ASC_SAT 0.8500 +000018 A_0038C027_241010_145134_h1EHP V C 15:54:02:03 15:54:13:04 02:13:55:14 02:14:06:15 +*VFX 117_GUD_0160 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 120C-3 +*LOC: 02:13:55:14 Green Sc 120 INTERCUT +*LOC: 02:13:56:13 White VFX 117_GUD_0160 add Norway landscape +*ASC_SOP (0.9812 0.9783 1.0016)(-0.0737 -0.0335 -0.0141)(0.8337 0.8918 1.0014) +*ASC_SAT 0.9640 +000019 A_0044C012_241015_112339_h1EHP V C 12:24:45:15 12:24:55:14 02:14:07:15 02:14:17:14 +*VFX 124_SYF_0010 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124-3-A +*LOC: 02:14:07:15 Green Sc 124 +*LOC: 02:14:12:04 White VFX 124_SYF_0010 add Norway landscape +*ASC_SOP (0.8971 0.8843 0.8818)(0.0070 0.0211 0.0238)(0.9792 0.9850 1.0157) +*ASC_SAT 1.0000 +000020 A_0044C020_241015_115202_h1EHP V C 12:53:11:04 12:53:12:19 02:14:17:14 02:14:19:05 +*FROM CLIP NAME: 124B-5 +*ASC_SOP (0.9201 0.9118 0.9150)(-0.0137 0.0007 0.0036)(0.9530 0.9664 1.0033) +*ASC_SAT 1.0000 +000021 A_0044C013_241015_113513_h1EHP V C 12:36:33:02 12:36:36:13 02:14:19:05 02:14:22:16 +*VFX 124_SYF_0020 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124A-1-A +*LOC: 02:14:20:23 White VFX 124_SYF_0020 add Norway landscape +*ASC_SOP (0.8897 0.8752 0.8668)(0.0033 0.0195 0.0290)(0.9671 0.9811 1.0153) +*ASC_SAT 1.0000 +000022 A_0044C020_241015_115202_h1EHP V C 12:53:18:02 12:53:20:19 02:14:22:16 02:14:25:09 +*FROM CLIP NAME: 124B-5 +*ASC_SOP (0.9201 0.9118 0.9150)(-0.0137 0.0007 0.0036)(0.9530 0.9664 1.0033) +*ASC_SAT 1.0000 +000023 A_0044C013_241015_113513_h1EHP V C 12:36:36:22 12:36:38:07 02:14:25:09 02:14:26:18 +*VFX 124_SYF_0025 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124A-1-A +*LOC: 02:14:25:23 White VFX 124_SYF_0025 add Norway landscape +*ASC_SOP (0.8897 0.8752 0.8668)(0.0033 0.0195 0.0290)(0.9671 0.9811 1.0153) +*ASC_SAT 1.0000 +000024 A_0044C012_241015_112339_h1EHP V C 12:25:01:21 12:25:03:09 02:14:26:18 02:14:28:06 +*VFX 124_SYF_0030 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124-3-A +*LOC: 02:14:27:09 White VFX 124_SYF_0030 add Norway landscape +*ASC_SOP (0.8971 0.8843 0.8818)(0.0070 0.0211 0.0238)(0.9792 0.9850 1.0157) +*ASC_SAT 1.0000 +000025 A_0044C013_241015_113513_h1EHP V C 12:36:39:11 12:36:41:13 02:14:28:06 02:14:30:08 +*VFX 124_SYF_0040 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124A-1-A +*LOC: 02:14:28:22 White VFX 124_SYF_0040 add Norway landscape +*ASC_SOP (0.8897 0.8752 0.8668)(0.0033 0.0195 0.0290)(0.9671 0.9811 1.0153) +*ASC_SAT 1.0000 +000026 A_0044C020_241015_115202_h1EHP V C 12:53:23:11 12:53:25:13 02:14:30:08 02:14:32:10 +*VFX 124_SYF_0043 ADD NORWAY BG +*FROM CLIP NAME: 124B-5 +*LOC: 02:14:31:13 White VFX 124_SYF_0043 add Norway bg +*ASC_SOP (0.9201 0.9118 0.9150)(-0.0137 0.0007 0.0036)(0.9530 0.9664 1.0033) +*ASC_SAT 1.0000 +000027 A_0044C013_241015_113513_h1EHP V C 12:36:41:18 12:36:43:05 02:14:32:10 02:14:33:21 +*VFX 124_SYF_0048 ADD NORWAY BG +*FROM CLIP NAME: 124A-1-A +*LOC: 02:14:33:11 White VFX 124_SYF_0048 add Norway bg +*ASC_SOP (0.8897 0.8752 0.8668)(0.0033 0.0195 0.0290)(0.9671 0.9811 1.0153) +*ASC_SAT 1.0000 +000028 A_0044C019_241015_115048_h1EHP V C 12:52:16:18 12:52:18:13 02:14:33:21 02:14:35:16 +*VFX 124_SYF_0050 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124B-4 +*LOC: 02:14:34:16 White VFX 124_SYF_0050 add Norway landscape +*ASC_SOP (0.9162 0.9080 0.9112)(-0.0095 0.0049 0.0078)(0.9530 0.9664 1.0033) +*ASC_SAT 1.0000 +000029 A_0044C014_241015_113829_h1EHP V C 12:39:54:17 12:39:57:03 02:14:35:16 02:14:38:02 +*VFX 124_SYF_0060 ADD NORWAY BG +*FROM CLIP NAME: 124A-2-A +*LOC: 02:14:36:16 White VFX 124_SYF_0060 Add Norway bg +*ASC_SOP (0.8898 0.8754 0.8669)(0.0032 0.0194 0.0288)(0.9671 0.9811 1.0153) +*ASC_SAT 1.0000 +000030 B_0037C009_241015_122652_h1C2T V C 12:25:10:01 12:25:11:05 02:14:38:02 02:14:39:06 +*VFX 124_SYF_0073 ADD NORWAY BG +*FROM CLIP NAME: 124-3-B +*LOC: 02:14:38:02 Green Sc 125 +*LOC: 02:14:38:22 White VFX 124_SYF_0073 Add Norway bg +*ASC_SOP (0.9201 0.9118 0.9150)(-0.0137 0.0007 0.0036)(0.9530 0.9664 1.0033) +*ASC_SAT 1.0000 +000031 A_0045C002_241015_131216_h1EHP V C 14:13:16:23 14:13:18:23 02:14:39:06 02:14:41:06 +*VFX 124_SYF_0078 ADD NORWAY BG +*FROM CLIP NAME: 124E-2 +*LOC: 02:14:40:01 White VFX 124_SYF_0078 Add Norway bg +*ASC_SOP (0.9201 0.9118 0.9150)(-0.0137 0.0007 0.0036)(0.9530 0.9664 1.0033) +*ASC_SAT 1.0000 +000032 B_0037C009_241015_122652_h1C2T V C 12:25:11:13 12:25:12:06 02:14:41:06 02:14:41:23 +*VFX 124_SYF_0080 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124-3-B +*LOC: 02:14:41:09 White VFX 124_SYF_0080 add Norway landscape +*ASC_SOP (0.9201 0.9118 0.9150)(-0.0137 0.0007 0.0036)(0.9530 0.9664 1.0033) +*ASC_SAT 1.0000 +000033 D007C0005_241008_Q3J912 V C 13:19:00:22 13:19:02:15 02:14:41:23 02:14:43:16 +*VFX 124_SYF_0100 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124C-4 +*LOC: 02:14:42:08 White VFX 124_SYF_0100 add Norway landscape +*ASC_SOP (0.8789 0.8685 0.8723)(0.0094 0.0316 0.0328)(0.9300 0.9406 1.0012) +*ASC_SAT 1.0000 +000034 A_0045C002_241015_131216_h1EHP V C 14:13:20:03 14:13:20:16 02:14:43:16 02:14:44:05 +*VFX 124_SYF_0090 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124E-2 +*LOC: 02:14:43:21 White VFX 124_SYF_0090 add Norway landscape +*ASC_SOP (0.9201 0.9118 0.9150)(-0.0137 0.0007 0.0036)(0.9530 0.9664 1.0033) +*ASC_SAT 1.0000 +000035 D007C0007_241008_Q3J912 V C 13:26:59:07 13:27:00:18 02:14:44:05 02:14:45:16 +*VFX 124_SYF_0110 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124D-2 +*LOC: 02:14:44:19 White VFX 124_SYF_0110 add Norway landscape +*ASC_SOP (0.9058 0.8914 0.8960)(-0.0006 0.0207 0.0219)(0.9087 0.9191 0.9783) +*ASC_SAT 1.0000 +000036 D007C0005_241008_Q3J912 V C 13:19:04:09 13:19:07:01 02:14:45:16 02:14:48:08 +*VFX 124_SYF_0120 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124C-4 +*LOC: 02:14:47:22 White VFX 124_SYF_0120 add Norway landscape +*ASC_SOP (0.8789 0.8685 0.8723)(0.0094 0.0316 0.0328)(0.9300 0.9406 1.0012) +*ASC_SAT 1.0000 +000037 D007C0007_241008_Q3J912 V C 13:27:03:08 13:27:04:10 02:14:48:08 02:14:49:10 +*VFX 124_SYF_0130 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124D-2 +*LOC: 02:14:48:19 White VFX 124_SYF_0130 add Norway landscape +*ASC_SOP (0.9058 0.8914 0.8960)(-0.0006 0.0207 0.0219)(0.9087 0.9191 0.9783) +*ASC_SAT 1.0000 +000038 D007C0003_241008_Q3J912 V C 13:15:29:20 13:15:30:23 02:14:49:10 02:14:50:13 +*VFX 124_SYF_0140 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 124C-2 +*LOC: 02:14:49:15 White VFX 124_SYF_0140 add Norway landscape +*ASC_SOP (0.8711 0.8610 0.8647)(0.0125 0.0345 0.0357)(0.9300 0.9406 1.0012) +*ASC_SAT 1.0000 +000039 A_0045C009_241015_135209_h1EHP V C 14:53:13:14 14:53:15:09 02:14:50:13 02:14:52:08 +*VFX 124_SYF_0150 ADD NORWAY LANDSCAPE +*FROM CLIP NAME: 125A-3* +*LOC: 02:14:50:13 Green Sc 126 +*LOC: 02:14:50:14 White VFX 124_SYF_0150 add Norway landscape +*ASC_SOP (0.9541 0.9282 0.9124)(-0.0197 0.0032 0.0111)(0.9317 0.9350 0.9640) +*ASC_SAT 1.0000 \ No newline at end of file diff --git a/tests/edls/cdl_example02.cdl b/tests/edls/cdl_example02.cdl new file mode 100644 index 0000000..8239d87 --- /dev/null +++ b/tests/edls/cdl_example02.cdl @@ -0,0 +1,17 @@ +TITLE: cdl_example02 +FCM: NON-DROP FRAME +000001 A205C016_220204_R24B V C 22:47:18:20 22:47:21:16 03:09:09:03 03:09:11:23 +*FROM CLIP NAME: 49D-3 +*ASC_SOP (0.98875 0.9878 0.98659)(-0.0008 0.00263 -0.00269)(0.9769 0.9767 0.97709) +*ASC_SAT 1.0 +*SOURCE FILE: A205C016_220204_R24B +000002 A238C007_220221_R24B V C 11:53:01:13 11:53:05:20 03:09:55:18 03:10:00:01 +*FROM CLIP NAME: 52B-7 +*ASC_SOP (1.05572 1.06914 1.05607)(-0.03004 -0.03044 -0.03044)(1.02112 1.01956 1.01707) +*ASC_SAT 1.0 +*SOURCE FILE: A238C007_220221_R24B +000004 A239C004_220221_R24B V C 15:19:53:22 15:19:55:02 03:10:00:01 03:10:01:05 +*FROM CLIP NAME: 52G-4* +*ASC_SOP (1.00515 0.99542 0.9934)(-0.02412 -0.01467 -0.01351)(0.97348 0.97074 0.96887) +*ASC_SAT 1.0 +*SOURCE FILE: A239C004_220221_R24B diff --git a/tests/edls/cdl_frmc_example01.edl b/tests/edls/cdl_frmc_example01.edl new file mode 100644 index 0000000..c9c8158 --- /dev/null +++ b/tests/edls/cdl_frmc_example01.edl @@ -0,0 +1,7 @@ +TITLE: cdl_frmc_example01 +FCM: NON-DROP FRAME +000001 C004C008_240813ZW V C 14:41:59:15 14:42:03:21 01:00:00:00 01:00:04:06 +*FROM CLIP NAME: QTLF_101_010_113_BG_01_V001 +*FRMC START: 1001 FRMC END: 1102 FRMC DURATION:102 +*ASC_SOP (1.04751 1.0378 1.02485)(-0.00909 0.00062 0.01468)(1.0 1.0 1.0) +*ASC_SAT 1.0 \ No newline at end of file diff --git a/tests/edls/cdl_frmc_example02.edl b/tests/edls/cdl_frmc_example02.edl new file mode 100644 index 0000000..3b9ef86 --- /dev/null +++ b/tests/edls/cdl_frmc_example02.edl @@ -0,0 +1,123 @@ +TITLE: cdl_frmc_example02 +FCM: NON-DROP FRAME +000001 A_0095C008_250116_182427_h1DQ9 V C 17:31:54:08 17:31:58:00 01:00:00:00 01:00:03:16 +*FROM CLIP NAME: 000_trl_0010_bg01_v01 +*FRMC start: 1001 FRMC end: 1088 FRMC duration:88 +*ASC_SOP (1.0035 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000002 V204_01051811_C010 V C 13:07:43:14 13:07:49:06 01:00:03:16 01:00:09:08 +*FROM CLIP NAME: 000_trl_0010_el01_v01 +*FRMC start: 1001 FRMC end: 1136 FRMC duration:136 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000003 A_0092C017_250115_182121_h1DQ9 V C 17:27:07:01 17:27:12:09 01:00:09:08 01:00:14:16 +*FROM CLIP NAME: 027_mtr_1770_bg01_v01 +*FRMC start: 1001 FRMC end: 1128 FRMC duration:128 +*ASC_SOP (1.0 1.0 1.0)(0.0 -0.004 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000004 A_0092C018_250115_182308_h1DQ9 V C 17:28:39:03 17:28:51:00 01:00:14:16 01:00:26:13 +*FROM CLIP NAME: 027_mtr_1770_rf01_v01 +*FRMC start: 1001 FRMC end: 1285 FRMC duration:285 +*ASC_SOP (1.0 1.0 1.0)(0.0 -0.004 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000005 C_0122C010_250219_123205_h1E5N V C 11:34:58:01 11:35:01:07 01:00:26:13 01:00:29:19 +*FROM CLIP NAME: 084_ebk_2120_bg01_v01 +*FRMC start: 1001 FRMC end: 1078 FRMC duration:78 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000006 C_0122C011_250219_123354_h1E5N V C 11:36:19:22 11:36:40:04 01:00:29:19 01:00:50:01 +*FROM CLIP NAME: 084_ebk_2120_rf01_v01 +*FRMC start: 1001 FRMC end: 1486 FRMC duration:486 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000007 B_0124C002_250219_045355_h1CUT V C 12:00:32:21 12:00:36:01 01:00:50:01 01:00:53:05 +*FROM CLIP NAME: 084_ebk_2140_bg01_v01 +*FRMC start: 1001 FRMC end: 1076 FRMC duration:76 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000008 C_0126C013_250221_121324_h1E5N V C 11:16:03:18 11:16:09:11 01:00:53:05 01:00:58:22 +*FROM CLIP NAME: 084_ebk_2280_bg01_v01 +*FRMC start: 1001 FRMC end: 1137 FRMC duration:137 +*ASC_SOP (1.0 1.0 0.999)(-0.0078 -0.0078 -0.0098)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000009 D_0079C004_250223_110040_h1DZT V C 11:04:05:08 11:04:08:08 01:00:58:22 01:01:01:22 +*FROM CLIP NAME: 086_ebk_4160_bg01_v01 +*FRMC start: 1001 FRMC end: 1072 FRMC duration:72 +*ASC_SOP (1.0031 1.003 1.0025)(-0.0116 -0.0191 -0.0266)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000010 D_0079C005_250223_110303_h1DZT V C 11:06:01:07 11:06:14:12 01:01:01:22 01:01:15:03 +*FROM CLIP NAME: 086_ebk_4160_rf01_v01 +*FRMC start: 1001 FRMC end: 1317 FRMC duration:317 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000011 W_0005C003_250223_105431_h1EPT V C 09:59:09:05 09:59:11:19 01:01:15:03 01:01:17:17 +*FROM CLIP NAME: 086_ebk_4180_bg01_v01 +*FRMC start: 1001 FRMC end: 1062 FRMC duration:62 +*ASC_SOP (1.0198 1.0198 1.0193)(-0.0019 -0.0082 -0.0174)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000012 W_0005C004_250223_110023_h1EPT V C 10:03:33:16 10:03:41:05 01:01:17:17 01:01:25:06 +*FROM CLIP NAME: 086_ebk_4180_rf01_v01 +*FRMC start: 1001 FRMC end: 1181 FRMC duration:181 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000013 D_0079C001_250223_095442_h1DZT V C 09:59:09:13 09:59:12:23 01:01:25:06 01:01:28:16 +*FROM CLIP NAME: 086_ebk_4200_bg01_v01 +*FRMC start: 1001 FRMC end: 1082 FRMC duration:82 +*ASC_SOP (1.0031 1.003 1.0025)(0.0067 -0.0008 -0.0083)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000014 D_0079C002_250223_100041_h1DZT V C 10:03:42:19 10:03:51:04 01:01:28:16 01:01:37:01 +*FROM CLIP NAME: 086_ebk_4200_rf01_v01 +*FRMC start: 1001 FRMC end: 1201 FRMC duration:201 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000015 A_0095C006_250116_181426_h1DQ9 V C 17:20:11:09 17:21:44:21 01:01:37:01 01:03:10:13 +*FROM CLIP NAME: 088_mcm_0200_bg01_v01 +*FRMC start: 1001 FRMC end: 3244 FRMC duration:2244 +*ASC_SOP (1.0035 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000016 V204_01051756_C008 V C 12:54:36:09 12:54:43:14 01:03:10:13 01:03:17:18 +*FROM CLIP NAME: 088_mcm_0200_el02_v01 +*FRMC start: 1829 FRMC end: 2001 FRMC duration:173 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000017 V204_01051808_C009 V C 13:03:57:17 13:04:08:00 01:03:17:18 01:03:28:01 +*FROM CLIP NAME: 088_mcm_0200_el03_v01 +*FRMC start: 2592 FRMC end: 2838 FRMC duration:247 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000018 V204_01051811_C010 V C 13:07:57:07 13:08:04:12 01:03:28:01 01:03:35:06 +*FROM CLIP NAME: 088_mcm_0200_el04_v01 +*FRMC start: 3072 FRMC end: 3244 FRMC duration:173 +*ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000019 A_0095C012_250116_184034_h1DQ9 V C 17:46:03:10 17:46:11:09 01:03:35:06 01:03:43:05 +*FROM CLIP NAME: 088_mcm_0200_rf01_v01 +*FRMC start: 1001 FRMC end: 1191 FRMC duration:191 +*ASC_SOP (1.0035 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000020 A_0095C013_250116_184129_h1DQ9 V C 17:47:00:10 17:47:21:07 01:03:43:05 01:04:04:02 +*FROM CLIP NAME: 088_mcm_0200_rf02_v01 +*FRMC start: 1001 FRMC end: 1501 FRMC duration:501 +*ASC_SOP (1.0035 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000021 A_0095C006_250116_181426_h1DQ9 V C 17:21:43:22 17:21:58:07 01:04:04:02 01:04:18:11 +*FROM CLIP NAME: 088_mcm_0240_bg01_V01 +*FRMC start: 1001 FRMC end: 1345 FRMC duration:345 +*ASC_SOP (1.0035 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000022 A_0002C019_241030_174120_h1DQ9 V C 16:43:24:02 16:43:27:09 01:04:18:11 01:04:21:18 +*FROM CLIP NAME: fv025_prw_0160_bg01_v01 +*FRMC start: 1001 FRMC end: 1079 FRMC duration:79 +000023 018_hdh_0040_lineup_v0003 V C 00:00:42:09 00:00:48:16 01:04:21:18 01:04:28:01 +*FROM CLIP NAME: fv025_prw_0160_tv01_v01 +*FRMC start: 1017 FRMC end: 1167 FRMC duration:151 +000024 Z_0003C015_241120_031008_h1CIM V C 14:09:11:18 14:09:14:12 01:04:28:01 01:04:30:19 +*FROM CLIP NAME: fv075_lgk_0500_bg01_v01 +*FRMC start: 1001 FRMC end: 1066 FRMC duration:66 +*ASC_SOP (1.005 0.9993 0.9917)(-0.005 0.0007 0.0083)(1.0 1.0 1.0) +*ASC_SAT 1.0 +000025 Z_0003C011_241120_022000_h1CIM V C 13:19:03:19 13:19:16:04 01:04:30:19 01:04:43:04 +*FROM CLIP NAME: fv075_lgk_0500_rf01_v01 +*FRMC start: 1001 FRMC end: 1297 FRMC duration:297 +*ASC_SOP (1.005 0.9993 0.9917)(-0.005 0.0007 0.0083)(1.0 1.0 1.0) +*ASC_SAT 1.0 \ No newline at end of file From 2ee94ca358eda9bd5dbcda6830ad9e6985e31a73 Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 09:44:36 -0800 Subject: [PATCH 02/12] Moved statement structs into a new file --- pycmx/parse_cmx_statements.py | 18 +----------------- pycmx/statements.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 pycmx/statements.py diff --git a/pycmx/parse_cmx_statements.py b/pycmx/parse_cmx_statements.py index ba19485..53ad172 100644 --- a/pycmx/parse_cmx_statements.py +++ b/pycmx/parse_cmx_statements.py @@ -5,25 +5,9 @@ import re from collections import namedtuple from typing import TextIO, List - +from .statements import * from .util import collimate -StmtTitle = namedtuple("Title", ["title", "line_number"]) -StmtFCM = namedtuple("FCM", ["drop", "line_number"]) -StmtEvent = namedtuple("Event", ["event", "source", "channels", "trans", - "trans_op", "source_in", "source_out", - "record_in", "record_out", "format", - "line_number"]) -StmtAudioExt = namedtuple("AudioExt", ["audio3", "audio4", "line_number"]) -StmtClipName = namedtuple("ClipName", ["name", "affect", "line_number"]) -StmtSourceFile = namedtuple("SourceFile", ["filename", "line_number"]) -StmtRemark = namedtuple("Remark", ["text", "line_number"]) -StmtEffectsName = namedtuple("EffectsName", ["name", "line_number"]) -StmtSourceUMID = namedtuple("Source", ["name", "umid", "line_number"]) -StmtSplitEdit = namedtuple("SplitEdit", ["video", "magnitude", "line_number"]) -StmtMotionMemory = namedtuple( - "MotionMemory", ["source", "fps"]) # FIXME needs more fields -StmtUnrecognized = namedtuple("Unrecognized", ["content", "line_number"]) def parse_cmx3600_statements(file: TextIO) -> List[object]: diff --git a/pycmx/statements.py b/pycmx/statements.py new file mode 100644 index 0000000..ef5df71 --- /dev/null +++ b/pycmx/statements.py @@ -0,0 +1,18 @@ +from collections import namedtuple + +StmtTitle = namedtuple("Title", ["title", "line_number"]) +StmtFCM = namedtuple("FCM", ["drop", "line_number"]) +StmtEvent = namedtuple("Event", ["event", "source", "channels", "trans", + "trans_op", "source_in", "source_out", + "record_in", "record_out", "format", + "line_number"]) +StmtAudioExt = namedtuple("AudioExt", ["audio3", "audio4", "line_number"]) +StmtClipName = namedtuple("ClipName", ["name", "affect", "line_number"]) +StmtSourceFile = namedtuple("SourceFile", ["filename", "line_number"]) +StmtRemark = namedtuple("Remark", ["text", "line_number"]) +StmtEffectsName = namedtuple("EffectsName", ["name", "line_number"]) +StmtSourceUMID = namedtuple("Source", ["name", "umid", "line_number"]) +StmtSplitEdit = namedtuple("SplitEdit", ["video", "magnitude", "line_number"]) +StmtMotionMemory = namedtuple( + "MotionMemory", ["source", "fps"]) # FIXME needs more fields +StmtUnrecognized = namedtuple("Unrecognized", ["content", "line_number"]) From 6c7f7d2de1edaa64e16118120cb90504f89207ac Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 10:35:40 -0800 Subject: [PATCH 03/12] Implemented SOP form parsing --- pycmx/parse_cmx_statements.py | 22 +++++++++++++++++++++- pycmx/statements.py | 5 +++++ tests/test_parse.py | 8 ++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/pycmx/parse_cmx_statements.py b/pycmx/parse_cmx_statements.py index 53ad172..048aabd 100644 --- a/pycmx/parse_cmx_statements.py +++ b/pycmx/parse_cmx_statements.py @@ -3,7 +3,7 @@ import re from collections import namedtuple -from typing import TextIO, List +from typing import Any, TextIO, List from .statements import * from .util import collimate @@ -104,6 +104,26 @@ def _parse_remark(line, line_number) -> object: elif line.startswith("SOURCE FILE:"): return StmtSourceFile(filename=line[12:].strip(), line_number=line_number) + elif line.startswith("ASC_SOP"): + group_patterns: list[str] = re.findall(r'\((.*?)\)', line) + + v: list[list[str]] = [re.findall(r'-?\d+(\.\d+)?', a) for + a in group_patterns] + + if len(v) != 3 or any([len(a) != 3 for a in v]): + return StmtRemark(line, line_number) + + else: + return StmtCdlSop(slope_r=v[0][0], slope_g=v[0][1], + slope_b=v[0][2], offset_r=v[1][0], + offset_g=v[1][1], offset_b=v[1][2], + power_r=v[2][0], power_g=v[2][1], + power_b=v[2][2], line_number=line_number) + + elif line.startswith("ASC_SAT"): + ... + elif line.startswith("FRMC"): + ... else: return StmtRemark(text=line, line_number=line_number) diff --git a/pycmx/statements.py b/pycmx/statements.py index ef5df71..e9b1ab0 100644 --- a/pycmx/statements.py +++ b/pycmx/statements.py @@ -9,6 +9,11 @@ StmtEvent = namedtuple("Event", ["event", "source", "channels", "trans", StmtAudioExt = namedtuple("AudioExt", ["audio3", "audio4", "line_number"]) StmtClipName = namedtuple("ClipName", ["name", "affect", "line_number"]) StmtSourceFile = namedtuple("SourceFile", ["filename", "line_number"]) +StmtCdlSop = namedtuple("CdlSop", ['slope_r','slope_g','slope_b', + 'offset_r', 'offset_g', 'offset_b', + 'power_r', 'power_g', 'power_b', + 'line_number']) +StmtCdlSat = namedtuple("SdlSat", ['value']) StmtRemark = namedtuple("Remark", ["text", "line_number"]) StmtEffectsName = namedtuple("EffectsName", ["name", "line_number"]) StmtSourceUMID = namedtuple("Source", ["name", "umid", "line_number"]) diff --git a/tests/test_parse.py b/tests/test_parse.py index c468d78..2bbd3b4 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -137,3 +137,11 @@ class TestParse(TestCase): pycmx.Transition.Cut) self.assertEqual(event.edits[0].source_in, "18:44:20:12") + + + def test_cdl(self): + with open("tests/edls/cdl_example01.edl", "r") as f: + edl = pycmx.parse_cmx3600(f) + for event in edl.events: + if event.number == 1: + ... From 2483e7fe43e6de7fa4f700d1da166afa34d7d54c Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 11:10:08 -0800 Subject: [PATCH 04/12] Implemented Cdl ASC_SAT --- pycmx/edit_list.py | 5 ++--- pycmx/event.py | 10 +++++++--- pycmx/parse_cmx_statements.py | 9 ++++++++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/pycmx/edit_list.py b/pycmx/edit_list.py index 08e6c39..490358c 100644 --- a/pycmx/edit_list.py +++ b/pycmx/edit_list.py @@ -1,6 +1,7 @@ # pycmx # (c) 2018 Jamie Hardt +from pycmx.statements import StmtTitle from .parse_cmx_statements import ( StmtUnrecognized, StmtEvent, StmtSourceUMID) from .event import Event @@ -16,7 +17,7 @@ class EditList: """ def __init__(self, statements): - self.title_statement = statements[0] + self.title_statement: StmtTitle = statements[0] self.event_statements = statements[1:] @property @@ -90,8 +91,6 @@ class EditList: else: event_statements.append(stmt) - elif type(stmt) is StmtSourceUMID: - break else: event_statements.append(stmt) diff --git a/pycmx/event.py b/pycmx/event.py index 0b94236..d671852 100644 --- a/pycmx/event.py +++ b/pycmx/event.py @@ -1,9 +1,10 @@ # pycmx # (c) 2023 Jamie Hardt -from .parse_cmx_statements import ( - StmtEvent, StmtClipName, StmtSourceFile, StmtAudioExt, StmtUnrecognized, - StmtEffectsName) +from pycmx.statements import * +# from .parse_cmx_statements import ( +# StmtEvent, StmtClipName, StmtSourceFile, StmtAudioExt, StmtUnrecognized, +# StmtEffectsName) from .edit import Edit from typing import List, Generator, Optional, Tuple, Any @@ -106,3 +107,6 @@ class Event: yield (s1, s2) elif type(s1) is StmtEvent: yield (s1, None) + + def _asc_sop_statements(self) -> list[StmtCdlSop]: + return [s for s in self.statements if type(s) == StmtCdlSop] diff --git a/pycmx/parse_cmx_statements.py b/pycmx/parse_cmx_statements.py index 048aabd..e3d0b4b 100644 --- a/pycmx/parse_cmx_statements.py +++ b/pycmx/parse_cmx_statements.py @@ -121,7 +121,14 @@ def _parse_remark(line, line_number) -> object: power_b=v[2][2], line_number=line_number) elif line.startswith("ASC_SAT"): - ... + value = re.findall(r'-?\d+(\.\d+)?', line) + + if len(value) != 1: + return StmtRemark(line, line_number) + + else: + return StmtCdlSat(value=value[0]) + elif line.startswith("FRMC"): ... else: From 73853d215edbcdbaf7576149b7d68bb95a9df0c0 Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 11:24:42 -0800 Subject: [PATCH 05/12] FRMC statement form implementation --- pycmx/parse_cmx_statements.py | 24 +++++++++++++++++------- pycmx/statements.py | 3 ++- tests/test_parse.py | 8 ++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/pycmx/parse_cmx_statements.py b/pycmx/parse_cmx_statements.py index e3d0b4b..14dd5f4 100644 --- a/pycmx/parse_cmx_statements.py +++ b/pycmx/parse_cmx_statements.py @@ -9,7 +9,6 @@ from .statements import * from .util import collimate - def parse_cmx3600_statements(file: TextIO) -> List[object]: """ Return a list of every statement in the file argument. @@ -106,9 +105,9 @@ def _parse_remark(line, line_number) -> object: line_number=line_number) elif line.startswith("ASC_SOP"): group_patterns: list[str] = re.findall(r'\((.*?)\)', line) - + v: list[list[str]] = [re.findall(r'-?\d+(\.\d+)?', a) for - a in group_patterns] + a in group_patterns] if len(v) != 3 or any([len(a) != 3 for a in v]): return StmtRemark(line, line_number) @@ -122,15 +121,26 @@ def _parse_remark(line, line_number) -> object: elif line.startswith("ASC_SAT"): value = re.findall(r'-?\d+(\.\d+)?', line) - + if len(value) != 1: return StmtRemark(line, line_number) - + else: - return StmtCdlSat(value=value[0]) + return StmtCdlSat(value=value[0], line_number=line_number) elif line.startswith("FRMC"): - ... + match = re.match( + r'^FRMC START:\s*(\d+)\s+FRMC END:\s*(\d+)' + r'\s+FRMC DURATION:\s*(\d+)', + line) + + if match is None: + return StmtRemark(line, line_number) + + else: + return StmtFrmc(start=match.group(1), end=match.group(2), + duration=match.group(3), line_number=line_number) + else: return StmtRemark(text=line, line_number=line_number) diff --git a/pycmx/statements.py b/pycmx/statements.py index e9b1ab0..687003f 100644 --- a/pycmx/statements.py +++ b/pycmx/statements.py @@ -13,7 +13,8 @@ StmtCdlSop = namedtuple("CdlSop", ['slope_r','slope_g','slope_b', 'offset_r', 'offset_g', 'offset_b', 'power_r', 'power_g', 'power_b', 'line_number']) -StmtCdlSat = namedtuple("SdlSat", ['value']) +StmtCdlSat = namedtuple("SdlSat", ['value', 'line_number']) +StmtFrmc = namedtuple("Frmc", ['start', 'end', 'duration', 'line_number']) StmtRemark = namedtuple("Remark", ["text", "line_number"]) StmtEffectsName = namedtuple("EffectsName", ["name", "line_number"]) StmtSourceUMID = namedtuple("Source", ["name", "umid", "line_number"]) diff --git a/tests/test_parse.py b/tests/test_parse.py index 2bbd3b4..f8e88d6 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -145,3 +145,11 @@ class TestParse(TestCase): for event in edl.events: if event.number == 1: ... + + def test_frmc(self): + with open("tests/edls/cdl_frmc_example01.edl", "r") as f: + edl = pycmx.parse_cmx3600(f) + for event in edl.events: + if event.number == 1: + ... + From 039bf8de6db603a684a906bcf698a8ff599b17bd Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 11:26:38 -0800 Subject: [PATCH 06/12] autopep --- pycmx/statements.py | 8 ++++---- tests/test_parse.py | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pycmx/statements.py b/pycmx/statements.py index 687003f..a296bb5 100644 --- a/pycmx/statements.py +++ b/pycmx/statements.py @@ -1,4 +1,4 @@ -from collections import namedtuple +from collections import namedtuple StmtTitle = namedtuple("Title", ["title", "line_number"]) StmtFCM = namedtuple("FCM", ["drop", "line_number"]) @@ -9,9 +9,9 @@ StmtEvent = namedtuple("Event", ["event", "source", "channels", "trans", StmtAudioExt = namedtuple("AudioExt", ["audio3", "audio4", "line_number"]) StmtClipName = namedtuple("ClipName", ["name", "affect", "line_number"]) StmtSourceFile = namedtuple("SourceFile", ["filename", "line_number"]) -StmtCdlSop = namedtuple("CdlSop", ['slope_r','slope_g','slope_b', - 'offset_r', 'offset_g', 'offset_b', - 'power_r', 'power_g', 'power_b', +StmtCdlSop = namedtuple("CdlSop", ['slope_r', 'slope_g', 'slope_b', + 'offset_r', 'offset_g', 'offset_b', + 'power_r', 'power_g', 'power_b', 'line_number']) StmtCdlSat = namedtuple("SdlSat", ['value', 'line_number']) StmtFrmc = namedtuple("Frmc", ['start', 'end', 'duration', 'line_number']) diff --git a/tests/test_parse.py b/tests/test_parse.py index f8e88d6..2fd8253 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -138,7 +138,6 @@ class TestParse(TestCase): self.assertEqual(event.edits[0].source_in, "18:44:20:12") - def test_cdl(self): with open("tests/edls/cdl_example01.edl", "r") as f: edl = pycmx.parse_cmx3600(f) @@ -149,7 +148,6 @@ class TestParse(TestCase): def test_frmc(self): with open("tests/edls/cdl_frmc_example01.edl", "r") as f: edl = pycmx.parse_cmx3600(f) - for event in edl.events: + for event in edl.events: if event.number == 1: ... - From 8a825c8164c13d13e23dd143251d24703520da24 Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 12:14:26 -0800 Subject: [PATCH 07/12] ASC SOP and SAT support in Edit type --- pycmx/edit.py | 22 +++++++++++++++++++++- pycmx/event.py | 13 ++++++++++--- pycmx/parse_cmx_statements.py | 10 ++++++---- tests/test_parse.py | 12 +++++++++++- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/pycmx/edit.py b/pycmx/edit.py index 7dafb64..bb67be7 100644 --- a/pycmx/edit.py +++ b/pycmx/edit.py @@ -1,6 +1,7 @@ # pycmx # (c) 2018 Jamie Hardt +from pycmx.statements import StmtCdlSat, StmtCdlSop from .transition import Transition from .channel_map import ChannelMap # from .parse_cmx_statements import StmtEffectsName @@ -16,12 +17,17 @@ class Edit: def __init__(self, edit_statement, audio_ext_statement, clip_name_statement, source_file_statement, - trans_name_statement=None): + trans_name_statement=None, asc_sop_statement=None, + asc_sat_statement=None, frmc_statement=None): + self.edit_statement = edit_statement self.audio_ext = audio_ext_statement self.clip_name_statement = clip_name_statement self.source_file_statement = source_file_statement self.trans_name_statement = trans_name_statement + self.asc_sop_statement: Optional[StmtCdlSop] = asc_sop_statement + self.asc_sat_statement: Optional[StmtCdlSat] = asc_sat_statement + self.frmc_statement = frmc_statement @property def line_number(self) -> int: @@ -131,3 +137,17 @@ class Edit: return None else: return self.clip_name_statement.name + + @property + def asc_sop(self) -> Optional[StmtCdlSop]: + """ + Get ASC CDL Slope-Offset-Power transfer function for clip, if present + """ + return self.asc_sop_statement + + @property + def asc_sat(self) -> Optional[StmtCdlSat]: + """ + Get ASC CDL saturation value for clip, if present + """ + return self.asc_sat_statement diff --git a/pycmx/event.py b/pycmx/event.py index d671852..6ae8911 100644 --- a/pycmx/event.py +++ b/pycmx/event.py @@ -75,7 +75,9 @@ class Event: audio_ext_statement=e1[1], clip_name_statement=n1, source_file_statement=s1, - trans_name_statement=u1) + trans_name_statement=u1, + asc_sop_statement=self._asc_sop_statement(), + asc_sat_statement=self._asc_sat_statement()) for (e1, n1, s1, u1) in zip(*the_zip)] @property @@ -108,5 +110,10 @@ class Event: elif type(s1) is StmtEvent: yield (s1, None) - def _asc_sop_statements(self) -> list[StmtCdlSop]: - return [s for s in self.statements if type(s) == StmtCdlSop] + def _asc_sop_statement(self) -> Optional[StmtCdlSop]: + return next((s for s in self.statements if type(s) == StmtCdlSop), + None) + + def _asc_sat_statement(self) -> Optional[StmtCdlSat]: + return next((s for s in self.statements if type(s) == StmtCdlSat), + None) diff --git a/pycmx/parse_cmx_statements.py b/pycmx/parse_cmx_statements.py index 14dd5f4..068eb72 100644 --- a/pycmx/parse_cmx_statements.py +++ b/pycmx/parse_cmx_statements.py @@ -106,8 +106,10 @@ def _parse_remark(line, line_number) -> object: elif line.startswith("ASC_SOP"): group_patterns: list[str] = re.findall(r'\((.*?)\)', line) - v: list[list[str]] = [re.findall(r'-?\d+(\.\d+)?', a) for - a in group_patterns] + v1: list[list[tuple[str, str]]] = [re.findall(r'(-?\d+(\.\d+)?)', a) for + a in group_patterns] + + v: list[list[str]] = [[a[0] for a in b] for b in v1] if len(v) != 3 or any([len(a) != 3 for a in v]): return StmtRemark(line, line_number) @@ -120,13 +122,13 @@ def _parse_remark(line, line_number) -> object: power_b=v[2][2], line_number=line_number) elif line.startswith("ASC_SAT"): - value = re.findall(r'-?\d+(\.\d+)?', line) + value = re.findall(r'(-?\d+(\.\d+)?)', line) if len(value) != 1: return StmtRemark(line, line_number) else: - return StmtCdlSat(value=value[0], line_number=line_number) + return StmtCdlSat(value=value[0][0], line_number=line_number) elif line.startswith("FRMC"): match = re.match( diff --git a/tests/test_parse.py b/tests/test_parse.py index 2fd8253..97db130 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -143,7 +143,16 @@ class TestParse(TestCase): edl = pycmx.parse_cmx3600(f) for event in edl.events: if event.number == 1: - ... + sop = event.edits[0].asc_sop_statement + self.assertIsNotNone(sop) + assert sop + self.assertEqual(sop.slope_r, "0.9405") + self.assertEqual(sop.offset_g, "-0.0276") + + sat = event.edits[0].asc_sat_statement + self.assertIsNotNone(sat) + assert sat + self.assertEqual(sat.value, '0.9640') def test_frmc(self): with open("tests/edls/cdl_frmc_example01.edl", "r") as f: @@ -151,3 +160,4 @@ class TestParse(TestCase): for event in edl.events: if event.number == 1: ... + From 878bdcc8c8056fc66eb11fd6c1283a4bc4f539d8 Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 12:18:50 -0800 Subject: [PATCH 08/12] Made statement imports explicit --- pycmx/edit.py | 4 ++-- pycmx/parse_cmx_statements.py | 11 +++++++---- tests/test_parse.py | 1 - 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pycmx/edit.py b/pycmx/edit.py index bb67be7..d9583b0 100644 --- a/pycmx/edit.py +++ b/pycmx/edit.py @@ -138,14 +138,14 @@ class Edit: else: return self.clip_name_statement.name - @property + @property def asc_sop(self) -> Optional[StmtCdlSop]: """ Get ASC CDL Slope-Offset-Power transfer function for clip, if present """ return self.asc_sop_statement - @property + @property def asc_sat(self) -> Optional[StmtCdlSat]: """ Get ASC CDL saturation value for clip, if present diff --git a/pycmx/parse_cmx_statements.py b/pycmx/parse_cmx_statements.py index 068eb72..5e09b19 100644 --- a/pycmx/parse_cmx_statements.py +++ b/pycmx/parse_cmx_statements.py @@ -2,10 +2,13 @@ # (c) 2018 Jamie Hardt import re -from collections import namedtuple -from typing import Any, TextIO, List +from typing import TextIO, List -from .statements import * +from .statements import (StmtCdlSat, StmtCdlSop, StmtFrmc, StmtRemark, + StmtTitle, StmtUnrecognized, StmtFCM, StmtAudioExt, + StmtClipName, StmtEffectsName, StmtEvent, + StmtSourceFile, StmtSplitEdit, StmtMotionMemory, + StmtSourceUMID) from .util import collimate @@ -107,7 +110,7 @@ def _parse_remark(line, line_number) -> object: group_patterns: list[str] = re.findall(r'\((.*?)\)', line) v1: list[list[tuple[str, str]]] = [re.findall(r'(-?\d+(\.\d+)?)', a) for - a in group_patterns] + a in group_patterns] v: list[list[str]] = [[a[0] for a in b] for b in v1] diff --git a/tests/test_parse.py b/tests/test_parse.py index 97db130..2ba4e9a 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -160,4 +160,3 @@ class TestParse(TestCase): for event in edl.events: if event.number == 1: ... - From 78f5c8ea08cfaf67480b58a98e6f465aeb0c979b Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 12:20:25 -0800 Subject: [PATCH 09/12] Made imports explicit --- pycmx/edit.py | 1 - pycmx/event.py | 11 +++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pycmx/edit.py b/pycmx/edit.py index d9583b0..992f952 100644 --- a/pycmx/edit.py +++ b/pycmx/edit.py @@ -4,7 +4,6 @@ from pycmx.statements import StmtCdlSat, StmtCdlSop from .transition import Transition from .channel_map import ChannelMap -# from .parse_cmx_statements import StmtEffectsName from typing import Optional diff --git a/pycmx/event.py b/pycmx/event.py index 6ae8911..d5ef542 100644 --- a/pycmx/event.py +++ b/pycmx/event.py @@ -1,10 +1,9 @@ # pycmx # (c) 2023 Jamie Hardt -from pycmx.statements import * -# from .parse_cmx_statements import ( -# StmtEvent, StmtClipName, StmtSourceFile, StmtAudioExt, StmtUnrecognized, -# StmtEffectsName) +from .parse_cmx_statements import ( + StmtEvent, StmtClipName, StmtSourceFile, StmtAudioExt, StmtUnrecognized, + StmtEffectsName, StmtCdlSop, StmtCdlSat) from .edit import Edit from typing import List, Generator, Optional, Tuple, Any @@ -75,8 +74,8 @@ class Event: audio_ext_statement=e1[1], clip_name_statement=n1, source_file_statement=s1, - trans_name_statement=u1, - asc_sop_statement=self._asc_sop_statement(), + trans_name_statement=u1, + asc_sop_statement=self._asc_sop_statement(), asc_sat_statement=self._asc_sat_statement()) for (e1, n1, s1, u1) in zip(*the_zip)] From 23499b140c55409ee920d4bd3a641248060c3f0b Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 12:21:51 -0800 Subject: [PATCH 10/12] flake8 --- pycmx/event.py | 4 ++-- pycmx/parse_cmx_statements.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pycmx/event.py b/pycmx/event.py index d5ef542..c9d0437 100644 --- a/pycmx/event.py +++ b/pycmx/event.py @@ -110,9 +110,9 @@ class Event: yield (s1, None) def _asc_sop_statement(self) -> Optional[StmtCdlSop]: - return next((s for s in self.statements if type(s) == StmtCdlSop), + return next((s for s in self.statements if type(s) is StmtCdlSop), None) def _asc_sat_statement(self) -> Optional[StmtCdlSat]: - return next((s for s in self.statements if type(s) == StmtCdlSat), + return next((s for s in self.statements if type(s) is StmtCdlSat), None) diff --git a/pycmx/parse_cmx_statements.py b/pycmx/parse_cmx_statements.py index 5e09b19..73bcf63 100644 --- a/pycmx/parse_cmx_statements.py +++ b/pycmx/parse_cmx_statements.py @@ -109,8 +109,8 @@ def _parse_remark(line, line_number) -> object: elif line.startswith("ASC_SOP"): group_patterns: list[str] = re.findall(r'\((.*?)\)', line) - v1: list[list[tuple[str, str]]] = [re.findall(r'(-?\d+(\.\d+)?)', a) for - a in group_patterns] + v1: list[list[tuple[str, str]]] = \ + [re.findall(r'(-?\d+(\.\d+)?)', a) for a in group_patterns] v: list[list[str]] = [[a[0] for a in b] for b in v1] From 229f6d646b0bbca099f42c16f47671f43d5fa4d6 Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 12:37:16 -0800 Subject: [PATCH 11/12] FRMT implementation --- pycmx/edit.py | 11 +++++++++-- pycmx/event.py | 7 ++++++- pycmx/parse_cmx_statements.py | 3 +-- tests/test_parse.py | 18 +++++++++++++++++- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/pycmx/edit.py b/pycmx/edit.py index 992f952..57bd7a5 100644 --- a/pycmx/edit.py +++ b/pycmx/edit.py @@ -1,7 +1,7 @@ # pycmx # (c) 2018 Jamie Hardt -from pycmx.statements import StmtCdlSat, StmtCdlSop +from pycmx.statements import StmtCdlSat, StmtCdlSop, StmtFrmc from .transition import Transition from .channel_map import ChannelMap @@ -26,7 +26,7 @@ class Edit: self.trans_name_statement = trans_name_statement self.asc_sop_statement: Optional[StmtCdlSop] = asc_sop_statement self.asc_sat_statement: Optional[StmtCdlSat] = asc_sat_statement - self.frmc_statement = frmc_statement + self.frmc_statement: Optional[StmtFrmc] = frmc_statement @property def line_number(self) -> int: @@ -150,3 +150,10 @@ class Edit: Get ASC CDL saturation value for clip, if present """ return self.asc_sat_statement + + @property + def frmc(self) -> Optional[StmtFrmc]: + """ + Get FRMC data + """ + return self.frmc_statement diff --git a/pycmx/event.py b/pycmx/event.py index c9d0437..57f97e2 100644 --- a/pycmx/event.py +++ b/pycmx/event.py @@ -1,6 +1,7 @@ # pycmx # (c) 2023 Jamie Hardt +from pycmx.statements import StmtFrmc from .parse_cmx_statements import ( StmtEvent, StmtClipName, StmtSourceFile, StmtAudioExt, StmtUnrecognized, StmtEffectsName, StmtCdlSop, StmtCdlSat) @@ -76,7 +77,8 @@ class Event: source_file_statement=s1, trans_name_statement=u1, asc_sop_statement=self._asc_sop_statement(), - asc_sat_statement=self._asc_sat_statement()) + asc_sat_statement=self._asc_sat_statement(), + frmc_statement=self._frmc_statement()) for (e1, n1, s1, u1) in zip(*the_zip)] @property @@ -116,3 +118,6 @@ class Event: def _asc_sat_statement(self) -> Optional[StmtCdlSat]: return next((s for s in self.statements if type(s) is StmtCdlSat), None) + + def _frmc_statement(self) -> Optional[StmtFrmc]: + return next((s for s in self.statements if type(s) is StmtFrmc), None) diff --git a/pycmx/parse_cmx_statements.py b/pycmx/parse_cmx_statements.py index 73bcf63..ee96ed9 100644 --- a/pycmx/parse_cmx_statements.py +++ b/pycmx/parse_cmx_statements.py @@ -136,8 +136,7 @@ def _parse_remark(line, line_number) -> object: elif line.startswith("FRMC"): match = re.match( r'^FRMC START:\s*(\d+)\s+FRMC END:\s*(\d+)' - r'\s+FRMC DURATION:\s*(\d+)', - line) + r'\s+FRMC DURATION:\s*(\d+)', line, re.IGNORECASE) if match is None: return StmtRemark(line, line_number) diff --git a/tests/test_parse.py b/tests/test_parse.py index 2ba4e9a..598e0d7 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -159,4 +159,20 @@ class TestParse(TestCase): edl = pycmx.parse_cmx3600(f) for event in edl.events: if event.number == 1: - ... + frmc = event.edits[0].frmc_statement + self.assertIsNotNone(frmc) + assert frmc + self.assertEqual(frmc.start, "1001") + self.assertEqual(frmc.end, "1102") + self.assertEqual(frmc.duration, "102") + + with open("tests/edls/cdl_frmc_example02.edl", "r") as f: + edl = pycmx.parse_cmx3600(f) + for event in edl.events: + if event.number == 6: + frmc = event.edits[0].frmc_statement + self.assertIsNotNone(frmc) + assert frmc + self.assertEqual(frmc.start, "1001") + self.assertEqual(frmc.end, "1486") + self.assertEqual(frmc.duration, "486") From 87dbbb1c68efcd9c4ce21e9a47a15fcd51b138fa Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Tue, 16 Dec 2025 12:39:04 -0800 Subject: [PATCH 12/12] autopep --- pycmx/edit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycmx/edit.py b/pycmx/edit.py index 57bd7a5..a68532f 100644 --- a/pycmx/edit.py +++ b/pycmx/edit.py @@ -151,7 +151,7 @@ class Edit: """ return self.asc_sat_statement - @property + @property def frmc(self) -> Optional[StmtFrmc]: """ Get FRMC data