QTKit, QTStringTime() and SMPTE

QTKit is quite convenient, but strangely only after Mac OS X 10.5, SMPTE style timecode getter was added as SMPTETimeValue() as a function in NSValue_QTKitAdditions.

So, if you want to write codes for Mac OS X 10.4 or 10.3 as minimum requirement, you should write your own. ( People tend to use classes and messages available only on Mac OS X 10.5 nowadays, but why? 10.4 is still popular! )

However, we have one problem. Let’s read explanation about the QTStringTime().

QTKIT_EXTERN NSString * QTStringFromTime (QTTime time);
Discussion
This function returns a description of a QTTime structure. The string is in the form “sign:days:hours:minutes:seconds:timevalue:timescale

What is the timescale? Is it second, minute, or hour? What is timevalue? Is it remainder smaller than second? There is no clear explanation. Example of the QuickTime time format is :

  1. 0:00:00:01:20:11/3000
  2. 0:00:00:01:20:1120/2997

I could confirm it using the QTKitPlayer sample code. The QuickTime player is worse than the QTKitPlayer in displaying the time code. The QuickTime player doesn’t display the timevalue:timescale part. And the Final Cut Pro displays SMPTE instead of the QuickTime time format.

So, I could easily determine that the number after / represents fps * 100. For example, 2997 is 29.97. At first I though that 11/3000 is, for example, is 11 divided by 3000. But it turned out that it is ….11 and the timescale used is 3000. It is also weird that fps is called, “timescale”.
Why doesn’t Apple use more understandable term?

Anyway.. from definition of QTTime :

typedef struct {
	long long		timeValue;
	long			timeScale;
	long			flags;
} QTTime;

timeValue % timeScale is “frames”.
timeValue / timeScale is second
. And if you divide the second with 60, the remainder is second, and its quotient is minute, and so on.

So, I could find out that timeValue is number of frames. So, the term “timeValue” is misleading.

Comment in QTTime.h is more accurate than the documentation.

// dd:hh:mm:ss.ff/ts
QTKIT_EXTERN NSString *QTStringFromTime (QTTime time)

Now, how about the “frame” that is remainder of the above calculation, timeValue % timeScale? It is like 1120 in the example 2 above. Is it really 1120 frames? No.
Just like that 2997 is 29.97 *100, 1120 is also 11.20 * 100. So, rouding 1120 gives correct “frame” value for the SMPTE style.

So, the QTTime format can be easily converted to SMPTE style.
What is the SMPTE style? It is : hh:mm:ss:ff

So, my ugly completed code is :

NSString *SMPTEStringFromTime( QTTime time )
{
	NSString *SMPTE_string;
	int days, hour, minute, second, frame;
	long long result;

	// timeScale is fps * 100
	result = time.timeValue / time.timeScale; // second
	frame = (time.timeValue % time.timeScale) / 100;

	second = result % 60;

	result = result / 60; // minute
	minute = result % 60;

	result = result / 60; // hour
	hour = result % 24;

	days = result;

	SMPTE_string = [NSString stringWithFormat:@"%02d:%02d:%02d:%02d", hour, minute, second, frame]; // hh:mm:ss:ff

	return SMPTE_string;
}
About these ads

8 responses to this post.

  1. Posted by Onotoley on October 13, 2011 at 5:01 PM

    You might find this one insightful: http://videogorillas.com/?p=14

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 41 other followers

%d bloggers like this: