Skip to content
Permalink
Browse files

Unifies ALE to the EDL adapter by storing the cdl data in the metadata (

#621)

* Unifies ale to the EDL adapter by storing the cdl data in the same data
structure. Add one more test file and test case.

* Add sample ale file with cdl data and unittest
  • Loading branch information
vvzen authored and reinecke committed Jan 13, 2020
1 parent 3ae4499 commit 6d9a10f023063a04c2d0e3cfe517c9258b11ba03
@@ -27,6 +27,7 @@
import opentimelineio as otio

DEFAULT_VIDEO_FORMAT = '1080'
ASC_SOP_REGEX = re.compile(r'(-*\d+\.\d+)')


def AVID_VIDEO_FORMAT_FROM_WIDTH_HEIGHT(width, height):
@@ -116,6 +117,32 @@ def _parse_data_line(line, columns, fps):
target_url=source
)

# If available, collect cdl values in the same way we do for CMX EDL
cdl = {}

if metadata.get('CDL'):
cdl = _cdl_values_from_metadata(metadata['CDL'])
if cdl:
del metadata['CDL']

# If we have more specific metadata, let's use them
if metadata.get('ASC_SOP'):
cdl = _cdl_values_from_metadata(metadata['ASC_SOP'])

if cdl:
del metadata['ASC_SOP']

if metadata.get('ASC_SAT'):
try:
asc_sat_value = float(metadata['ASC_SAT'])
cdl.update(asc_sat=asc_sat_value)
del metadata['ASC_SAT']
except ValueError:
pass

if cdl:
clip.metadata['cdl'] = cdl

# We've pulled out the key/value pairs that we treat specially.
# Put the remaining key/values into clip.metadata["ALE"]
clip.metadata["ALE"] = metadata
@@ -127,6 +154,30 @@ def _parse_data_line(line, columns, fps):
))


def _cdl_values_from_metadata(asc_sop_string):

if not isinstance(asc_sop_string, (type(''), type(u''))):
return {}

asc_sop_values = ASC_SOP_REGEX.findall(asc_sop_string)

cdl_data = {}

if len(asc_sop_values) >= 9:

cdl_data.update(
asc_sop={
'slope': [float(v) for v in asc_sop_values[:3]],
'offset': [float(v) for v in asc_sop_values[3:6]],
'power': [float(v) for v in asc_sop_values[6:9]]
})

if len(asc_sop_values) == 10:
cdl_data.update(asc_sat=float(asc_sop_values[9]))

return cdl_data


def _video_format_from_metadata(clips):
# Look for clips with Image Size metadata set
max_height = 0
@@ -0,0 +1,14 @@
Heading
FIELD_DELIM TABS
VIDEO_FORMAT PAL
FPS 23.976
FILM_FORMAT 35mm,4perf

Column
Name Tape Tracks Start End Duration ASC_SOP ASC_SAT Shoot Date Camera UNC UNC First Frame UNC Last Frame Length CDL R3D.ToneMap R3D.HighlightRollOff

Data
A005_C010_0501J0 A005_C010_0501J0 V 17:49:33:01 17:49:35:10 00:00:02:09 (0.8714 0.9334 0.9947)(-0.087 -0.0922 -0.0808)(0.9988 1.0218 1.0101) 0.9 20190501 A some/path/A005_C010_0501J0_001.R3D 1111 1168 57 (0.8714 0.9334 0.9947) (-0.0870 -0.0922 -0.0808) (0.9988 1.0218 1.0101) (0.9000) Low None
A005_C010_0501J0 A005_C010_0501J0 V 17:49:55:19 17:50:02:04 00:00:06:09 (0.8714 0.9334 0.9947)(-0.087 -0.0922 -0.0808)(0.9988 1.0218 1.0101) 0.9 20190501 A some/path/A005_C010_0501J0_001.R3D 1657 1810 153 (0.8714 0.9334 0.9947) (-0.0870 -0.0922 -0.0808) (0.9988 1.0218 1.0101) (0.9000) Low None
A005_C009_0501A0 A005_C009_0501A0 V 17:40:25:06 17:40:28:02 00:00:02:20 (0.8604 0.9252 0.9755)(-0.0735 -0.0813 -0.0737)(0.9988 1.0218 1.0101) 0.9 20190501 A some/path/A005_C009_0501A0_001.R3D 1296 1364 68 (0.8604 0.9252 0.9755) (-0.0735 -0.0813 -0.0737) (0.9988 1.0218 1.0101) (0.9000) Low None
A005_C010_0501J0 A005_C010_0501J0 V 17:50:21:23 17:50:25:13 00:00:03:14 (0.8714 0.9334 0.9947)(-0.087 -0.0922 -0.0808)(0.9988 1.0218 1.0101) 0.9 20190501 A some/path/A005_C010_0501J0_001.R3D 2285 2371 86 (0.8714 0.9334 0.9947) (-0.0870 -0.0922 -0.0808) (0.9988 1.0218 1.0101) (0.9000) Low None
@@ -33,6 +33,7 @@
SAMPLE_DATA_DIR = os.path.join(os.path.dirname(__file__), "sample_data")
EXAMPLE_PATH = os.path.join(SAMPLE_DATA_DIR, "sample.ale")
EXAMPLE2_PATH = os.path.join(SAMPLE_DATA_DIR, "sample2.ale")
EXAMPLE_CDL_PATH = os.path.join(SAMPLE_DATA_DIR, "sample_cdl.ale")
EXAMPLEUHD_PATH = os.path.join(SAMPLE_DATA_DIR, "sampleUHD.ale")


@@ -98,6 +99,89 @@ def test_ale_read2(self):
]
)

def test_ale_read_cdl(self):
ale_path = EXAMPLE_CDL_PATH
collection = otio.adapters.read_from_file(ale_path)
self.assertTrue(collection is not None)
self.assertEqual(type(collection), otio.schema.SerializableCollection)
self.assertEqual(len(collection), 4)
fps = float(collection.metadata.get("ALE").get("header").get("FPS"))
self.assertEqual(fps, 23.976)
self.assertEqual([c.name for c in collection], [
"A005_C010_0501J0", "A005_C010_0501J0", "A005_C009_0501A0",
"A005_C010_0501J0"
])
self.assertEqual([c.source_range for c in collection], [

otio.opentime.TimeRange(
otio.opentime.from_timecode("17:49:33:01", fps),
otio.opentime.from_timecode("00:00:02:09", fps)),

otio.opentime.TimeRange(
otio.opentime.from_timecode("17:49:55:19", fps),
otio.opentime.from_timecode("00:00:06:09", fps)),

otio.opentime.TimeRange(
otio.opentime.from_timecode("17:40:25:06", fps),
otio.opentime.from_timecode("00:00:02:20", fps)),

otio.opentime.TimeRange(
otio.opentime.from_timecode("17:50:21:23", fps),
otio.opentime.from_timecode("00:00:03:14", fps))
])

# Slope, offset, and power values are of type _otio.AnyVector
# So we have to convert them to lists otherwise
# the comparison between those two types would fail

# FIRST CLIP
self.assertEqual(
list(collection[0].metadata['cdl']['asc_sop']['slope']),
[0.8714, 0.9334, 0.9947])
self.assertEqual(
list(collection[0].metadata['cdl']['asc_sop']['offset']),
[-0.087, -0.0922, -0.0808])
self.assertEqual(
list(collection[0].metadata['cdl']['asc_sop']['power']),
[0.9988, 1.0218, 1.0101])
self.assertEqual(collection[0].metadata['cdl']['asc_sat'], 0.9)

# SECOND CLIP
self.assertEqual(
list(collection[1].metadata['cdl']['asc_sop']['slope']),
[0.8714, 0.9334, 0.9947])
self.assertEqual(
list(collection[1].metadata['cdl']['asc_sop']['offset']),
[-0.087, -0.0922, -0.0808])
self.assertEqual(
list(collection[1].metadata['cdl']['asc_sop']['power']),
[0.9988, 1.0218, 1.0101])
self.assertEqual(collection[1].metadata['cdl']['asc_sat'], 0.9)

# THIRD CLIP
self.assertEqual(
list(collection[2].metadata['cdl']['asc_sop']['slope']),
[0.8604, 0.9252, 0.9755])
self.assertEqual(
list(collection[2].metadata['cdl']['asc_sop']['offset']),
[-0.0735, -0.0813, -0.0737])
self.assertEqual(
list(collection[2].metadata['cdl']['asc_sop']['power']),
[0.9988, 1.0218, 1.0101])
self.assertEqual(collection[2].metadata['cdl']['asc_sat'], 0.9)

# FOURTH CLIP
self.assertEqual(
list(collection[3].metadata['cdl']['asc_sop']['slope']),
[0.8714, 0.9334, 0.9947])
self.assertEqual(
list(collection[3].metadata['cdl']['asc_sop']['offset']),
[-0.087, -0.0922, -0.0808])
self.assertEqual(
list(collection[3].metadata['cdl']['asc_sop']['power']),
[0.9988, 1.0218, 1.0101])
self.assertEqual(collection[3].metadata['cdl']['asc_sat'], 0.9)

def test_ale_uhd(self):
ale_path = EXAMPLEUHD_PATH
collection = otio.adapters.read_from_file(ale_path)

0 comments on commit 6d9a10f

Please sign in to comment.
You can’t perform that action at this time.