[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Openexr-devel] Re: New framesPerSecond Attribute?
From: |
Florian Kainz |
Subject: |
[Openexr-devel] Re: New framesPerSecond Attribute? |
Date: |
Mon, 16 Oct 2006 19:30:26 -0700 |
User-agent: |
Mozilla Thunderbird 1.0 (X11/20041207) |
I got a some of votes for "quotient" and some for "double".
A compromise might be to represent the frame rate as a Rational
object, were class Rational is defined as shown below. The
Rational object would support conversion to and from double.
This would allow you to store NTSC frame rates exactly and
to extract them as doubles when needed. Unfortunately the
conversion from double to Rational does not always preserve
the double's value exactly; Rational(double(30000.0/1001.0))
to Rational introduces a relative error of 1.7e-10.
Rational(30000,1001), Rational(24.0) and Rational(30.0) do
represent the corresponding frame rates exactly.
Florian
---------------------
//
// Rational number class, value is
//
// n/d for d > 0
// positive infinity for n > 0, d == 0
// negative infinity for n < 0, d == 0
// not a number (NaN) for n == 0, d == 0
//
class Rational
{
public:
int n; // numerator
unsigned int d; // denominator
//----------------------------------------
// Default constructor, sets value to zero
//----------------------------------------
Rational (): n (0), d (1) {}
//-------------------------------------
// Constructor, explicitly sets n and d
//-------------------------------------
Rational (int n, int d): n (n), d (d) {}
//----------------------------
// Constructor, approximates x
//----------------------------
Rational (double x);
//---------------------
// Conversion to double
//---------------------
operator double () const;
};
Rational::Rational (double x)
{
int sign;
if (x >= 0)
{
sign = 1; // positive
}
else if (x < 0)
{
sign = -1; // negative
x = -x;
}
else
{
n = 0; // NaN
d = 0;
return;
}
if (x >= (1U << 31) - 0.5)
{
n = sign; // infinity
d = 0;
return;
}
d = 1;
n = int (x * d + 0.5);
while (n < (1 << 30) && d < (1U << 31))
{
d <<= 1;
n = int (x * d + 0.5);
}
if (n == 0)
{
d = 1; // zero
return;
}
while (!(n & 1) && d > 1)
{
n >>= 1;
d >>= 1;
}
n *= sign;
}
Rational::operator double () const
{
return double (n) / double (d);
}
Florian Kainz wrote:
I would like propose a new "framesPerSecond" standard attribute
for OpenEXR:
The attribute defines the frame rate at which an OpenEXR image
sequence should be played back. All frames in a sequence should
have this attribute, and the attribute's value should be the same
for all frames. If no frame rate is specified for a sequence,
then playback software should assume 24 frames per second.
The attribute's value could be represented either as a floating-
point number or as the quotient of two integers. A floating-point
number would be easier to use, but it cannot represent NTSC frame
and field rates exactly. A quotient would be slightly less
convenient, but all commonly used frame rates, including NTSC,
can be represented exactly.
frame rate float quotient
--------------------------------------------------------
35-mm film 24.0 24 / 1
PAL video, 25.0 25 / 1
50 Hz HDTV frames
NTSC frames 29.97003 30000 / 1001
60 Hz HDTV frames 30.0 30 / 1
50 Hz HDTV fields 50.0 50 / 1
NTSC fields 59.94006 60000 / 1001
60 Hz HDTV fields, 60.0 60 / 1
Showscan
If you have comments or opinions, I'd like to hear them.
Thank you,
Florian