As I see it, we have basically three choices. 1. Encode as a string, establishing a convention for how it should be formatted (and maybe how it must be named to be recognized specifically as an SMPTE timecode).
2. Encode as some other type we already support (a uint64, or array of ints, say, if there is already an accepted convention for how SMPTE timecodes should be represented using ints or bitfields). Again, some convention in the metadata name might disambiguate which metadata are to be interpreted this way, versus truly being an int[2], for example. 3. Make an entirely new type, which is obviously better suited for that type, but which would necessitate a break in API and link compatibility, because it would involve changing the definitions of TypeDesc and ParamList and every place in the code (and application code!) that deals with those data structures and think that they currently cover all the possibilities. Note that #1 and #2 would be API forward and back compatible and only impact the couple of format readers/writers that deal with SMPTE timecodes, would not alter OIIO internals or other plugins. There is precedent for this approach for other formats/data items, and it generalizes to other similar issues that might come up in the future. Once we open the door on #3, will we have a proliferation of new types (each one requiring a change to multiple classes, internals, and apps, and representing a compatibility break) as additional purposes dribble in from time to time? I'm not saying no... I just want to get all the pros and cons on the table. But that's why #3 is, in my mind, a choice of last resort. I prefer standard types and conventions to growing a large "type zoo." The fact that TypeDesc and ParamList have been almost completely unchanged for 5 years is a strength and speaks to it being a pretty good fit for its intended purpose. Wait, there's one other possibility to throw out there, a bit of a compromise between #2 and #3: 4. We could transform the 'reserved' field in TypeDesc to some kind of "special meaning" code -- or just make another tag for the existing 'vecsemantics' byte -- and let "this is an SMPTE timecode" be one of those values. So it could store the data as a uint32[2], but have the semantic code set to indicate that it should be interpreted as an SMPTE timecode. This (versus truly making a new core 'basetype') changes very little of the internals, is not a break in link compatibility, and any apps or plugins that don't care specifically about timecodes can ignore it (or, at least, just continue to treat it as the int[2] that it's stored as). On Oct 10, 2013, at 9:13 AM, Mark Boorer wrote: > I guess I also disagree that timecode should survive a transfer into a > format that doesn't support it. To me, OIIO is not a metadata > pipeline, but just a way to get the maximum amount of information from > as many image formats in a standardised way. If metadata goes > EXR:TimeCode -> JPEG:string -> EXR I would expect the attribute to > arrive as a string. > > If we are making the call that certain metadata types will be > serialised in a certain way, and reconstructed at the other end, that > opens another whole kettle of fish. What if I want my string unmangled > for instance? Not converting metadata types is the least surprising > behaviour. > > On Thu, Oct 10, 2013 at 4:55 PM, Mark Boorer <[email protected]> wrote: >> But it isn't just SMPTE timecodes. there are many different rich types >> exposed in EXR metadata, some of which overlap with each other in >> terms of POD types, but you would want their types to be maintained. >> >> I agree that TypeDesc probably shouldn't describe these rich types, so >> perhaps the ParamValue shouldn't take a TypeDesc and maybe needs a >> more general AttributeDesc? >> >> I have some exr's with metadata like this: >> >> End (type string): "21:38:14:09" >> Start (type string): "21:37:36:03" >> timeCode (type timecode): >> time 21:37:36:03 >> drop frame 0, color frame 0, field/phase 0 >> bgf0 0, bgf1 0, bgf2 0 >> user data 0x0 >> >> When writing this data back out, I would expect that the "End" and >> "Start" attributes remain as strings, whereas the "timeCode" attribute >> is written as a TimeCode instance. >> >> The readers and writers can convert from these richer types to strings >> or ints or whatever we decide on a case by case basis, as long as they >> are consistent for their filetype, but I don't feel as though richer >> formats should lose out on this functionality. >> >> >> >> On Thu, Oct 10, 2013 at 4:45 PM, Larry Gritz <[email protected]> wrote: >>> I'm leaning toward representing it (as it travels through the OIIO >>> interface) as a string, where we can pick the representation/convention for >>> encoding it to preserve all the original information. There's an example >>> (which may or may not be correct and/or complete) in how we handle DPX, but >>> I'm not at all averse to changing it if we now have a better understanding >>> of what we want. >>> >>> But I'm not an expert on SMPTE timecodes and how they're used, so if >>> there's a good argument for keeping it as a 64 bit int or two 32 bit ints >>> -- for example, if there is an established convention for storing them this >>> way that SMPTE experts expect -- we can probably deal with that, too. >>> Maybe the metadata name is required to have some kind of hint (e.g., needs >>> the substring 'SMPTETime' in it somewhere). Maybe we need to provide >>> utility functions to split the bit fields into a more self-documenting >>> struct, and back. But I do know that I would prefer not to extend TypeDesc >>> (and our metadata passing in the ParamList) to take on the complexity of >>> being able to describe arbitrary structs, or even adding tags for one-off >>> special purpose structs. It's so nicely simple and general now. >>> >>> One of the best arguments I can think of for preferring strings is as >>> follows. If you were somehow making a round trip like this >>> >>> format A -> format B -> format A >>> >>> Now, suppose A supports SMPTE timecodes, but B does not (but does support >>> string metadata). Merely by adopting the string<->timecode convention >>> within A's format reader/writer, the timecode would make it through the >>> above pipeline intact. B will blindly pass the string along, and then the >>> A writer will recognize it as a timecode and deal with that appropriately. >>> The alternative is that *every* format reader would need to recognize SMPTE >>> timecodes (even if that is not a concept native to that file format) and >>> have to deal with it in some way. Also, the string approach lets a program >>> like 'iinfo' just print the string and be on its merry way, without needing >>> to be cluttered with timecode-specific logic. >>> >>> -- lg >>> >>> >>> On Oct 9, 2013, at 11:31 AM, Pete Black wrote: >>> >>>> Hi All, >>>> >>>> First, the below is my understanding of SMPTE timecode, it may not be 100% >>>> complete, or totally correct - >>>> >>>> SMPTE timecode includes both clock data - this is binary-coded decimal and >>>> takes 32 bits, and user data which is another 32 bits with unspecified >>>> content (often a 'tape name' or similar, but also containing flag bits to >>>> indicate drop frame or otr details). >>>> >>>> In LTC (Longitudinal timecode, as it is encoded and written to tape or >>>> sent on the wire), the 4-bit nibbles which make up each binary-coded digit >>>> in both blocks of data are interleaved, which is why a SMPTE timecode is >>>> often represented by 64 bits of packed data. >>>> >>>> If you wanted to read timecode off the wire, write it into a file, then >>>> read the data from the file and write it back on the wire, without parsing >>>> it at all then you might want to ensure you had a 'flat' 64-bit type for >>>> this. >>>> >>>> Personally I think it makes more sense to separate clock and user data >>>> into 2 32 bit fields, if you want 'raw' storage of this data - using a >>>> string representation to get and set the clock data seems ideal, but might >>>> be tricky for user data, as bitwise interpretation/manipulation of this >>>> data ( e.g. drop frame indicator bit ) may be desirable - though this >>>> usage tends to be less important now we are leaving the world of analog >>>> tape, I know we abuse it for our purposes in 48fps workflow. >>>> >>>> There would also be some merit in dumping the 'raw' format entirely and >>>> just reading/writing an arbitrary string for timecode, as this would work >>>> for most practical purposes ( image file metadata is reference only, and >>>> timecode is always reconstructed and sent by some application) just fine. >>>> >>>> Not sure if this helps too much, I guess following what the DPX format >>>> does would be good for consistency. >>>> >>>> -Pete >>>> >>>> >>>> Mark Boorer <[email protected]> wrote: >>>> >>>>> Hi, >>>>> >>>>> Looking further into this, are we sure that timecode doesn't warrant a >>>>> new type? EXR's can contain many metadata fields in Timecode format >>>>> (not just one) and I don't think we can just give users 2 unsigned >>>>> ints and be done with it. Users will probably want their timecode in >>>>> string format (as is presently done in the DPX header) or at least >>>>> have an easy way for converting to/from strings. >>>>> >>>>> Further more, I don't think it's particularly intuitive to assume that >>>>> any TypeDesc of 2 UINT32 should be written as timecode, especially >>>>> where I would expect a TypeDesc of 2 INT32s to be written as an >>>>> ImfVecAttribute "v2i". >>>>> >>>>> Thoughts? >>>>> >>>>> Cheers, >>>>> Mark >>>>> >>>>> On Sun, Oct 6, 2013 at 9:27 PM, Pete Black <[email protected]> wrote: >>>>>> Hi All, >>>>>> >>>>>> DPX definitely supports timecode - and inside the DPX file, this is >>>>>> stored as a uint32 for the timecode data and a uint32 for the user data, >>>>>> by the looks >>>>>> >>>>>> Retrieving timecode from the DPX files we have using OIIO involves >>>>>> reading the metadata attribute 'dpx:Timecode' which returns the 'TV >>>>>> Industry specific' timecode formatted as a string e.g. '00:00:00:05'. >>>>>> >>>>>> -Pete >>>>>> >>>>>> >>>>>> >>>>>> I believe this maps to the >>>>>> >>>>>> On 7/10/2013, at 6:58 AM, Andrew Hunter <[email protected]> wrote: >>>>>> >>>>>>> I believe that DPX also supports SMPTE time code as well as CinemaDNG. >>>>>>> >>>>>>> -- >>>>>>> +1 416 567 9514 >>>>>>> [email protected] >>>>>>> http://aehunter.net >>>>>>> >>>>>>> On 3 Oct 2013 13:14, "Larry Gritz" <[email protected]> wrote: >>>>>>> I would welcome a pull request with this fully fleshed out and tested. >>>>>>> >>>>>>> Two more things... >>>>>>> >>>>>>> 1. Just to future-proof it, I might add this in there: >>>>>>> >>>>>>> ASSERT(sizeof(Imf::TimeCode) == 2*sizeof(unsigned int)); >>>>>>> >>>>>>> 2. If there are other formats that have full SMPTE timecodes, we might >>>>>>> want to instead change the attribute to "SMPTE:TimeCode" (making it not >>>>>>> be exr-specific) and dictate that any other formats follow the same >>>>>>> encoding if they have an SMPTE timecode. >>>>>>> >>>>>>> >>>>>>> On Oct 3, 2013, at 10:07 AM, Larry Gritz wrote: >>>>>>> >>>>>>>> I don't think this merits a new core type. >>>>>>>> >>>>>>>> I would add it to the metadata as an array of two unsigned ints, which >>>>>>>> is how it's encoded in Imf::TimeCode. You'd want something like this >>>>>>>> in exrinput.cpp: >>>>>>>> >>>>>>>> static TypeDesc TwoUints (TypeDesc::UINT, 2); >>>>>>>> Imf::TimeCode tc = ...; // get the timecode from the EXR file >>>>>>>> spec.attribute ("openexr:TimeCode", TwoUints, &tc); >>>>>>>> >>>>>>>> And then to extract it (including in exroutput.cpp): >>>>>>>> >>>>>>>> ImageIOParameter *f = spec.find_attribute ("openexr:TimeCode", >>>>>>>> TwoUints); >>>>>>>> if (f) { >>>>>>>> Imf::TimeCode tc = *(const ImfTimeCode *) f->data(); >>>>>>>> ... do your thing with tc ... >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Oct 3, 2013, at 8:56 AM, Mark Boorer wrote: >>>>>>>> >>>>>>>>> Hi, >>>>>>>>> >>>>>>>>> Was just looking to access timecode metadata from some EXR files, and >>>>>>>>> noticed that timecode keys aren't extracted by the reader. >>>>>>>>> >>>>>>>>> I then found this rather old issue >>>>>>>>> https://github.com/OpenImageIO/oiio/issues/337. Is it possible for me >>>>>>>>> to add this in? A simple class based on ImfTimeCode.h (or even just >>>>>>>>> this class directly) and a new enum added to TypeDesc? >>>>>>>>> >>>>>>>>> Cheers, >>>>>>>>> Mark >>>>>>>> >>>>>>>> -- >>>>>>>> Larry Gritz >>>>>>>> [email protected] >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Larry Gritz >>>>>>> [email protected] >>>>>>> >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> Oiio-dev mailing list >>>>>>> [email protected] >>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>>>>> >>>>>>> _______________________________________________ >>>>>>> Oiio-dev mailing list >>>>>>> [email protected] >>>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>>>> >>>>>> _______________________________________________ >>>>>> Oiio-dev mailing list >>>>>> [email protected] >>>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>>> _______________________________________________ >>>>> Oiio-dev mailing list >>>>> [email protected] >>>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>>> _______________________________________________ >>>> Oiio-dev mailing list >>>> [email protected] >>>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org >>> >>> -- >>> Larry Gritz >>> [email protected] >>> >>> >>> _______________________________________________ >>> Oiio-dev mailing list >>> [email protected] >>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org > _______________________________________________ > Oiio-dev mailing list > [email protected] > http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org -- Larry Gritz [email protected] _______________________________________________ Oiio-dev mailing list [email protected] http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
