Archive for the ‘QuickTime’ Category

QTMovieView IB PlugIn on Snow Leopard problem

Recently I found a weird problem with QTMovieView IB Plug-In on Snow Leopard.

If you create an XIB or NIB file on a Snow Leopard and add a QTMovieView to a Window, its movie controller is not displayed even though you check “Show controller” check box.

Created on Snow Leopard

Created on Snow Leopard

Created on pre-Snow Leopard

Created on pre-Snow Leopard

As you can see, they are exactly same as far as their nature is concerned. Also, whether it is XIB or NIB doesn’t matter.

ADDED : It doesn’t display the movie controller either with IB 3.1.4, the latest IB for Leopard.

timeValue, timeScale and SMPTE – III

Joe van Tunen’s explanation

3) Glenn said “a QuickTime movie doesn’t need to have a consistent frame
rate”. This means that the timeValue does not need to increment by the same
amount all the time (timeValue increment / timeScale is the duration of the
frame). Even for movies that are supposed to have a consistent frame rate,
there could be times when the timeValue increment is not consistent (dropped
frames or rounding error or latency during movie capture). For example, an
NTSC movie with a timescale of 30000 should have frames at exact timeValues
0, 1001, 2002, 3003, etc. A dropped frame would be represented as an
increment of 2002. If the timeScale were less than 30000 then the timeValue
could not be incremented exactly. For example, if the timeScale were 2997
then the timeValue increment should be 99.9999 but will appear in the
QuickTime movie as 99 or 100. Latency could increase variability.

timeValue, timeScale and SMPTE – II

Glenn Anderson at the QuickTime-API mailing list answered to my question as follows :

On 10.5 there is also QTStringFromSMPTETime. You could use
QTMakeTimeScaled to get a time in the frame rate you want, fill out an
SMPTETime record, and pass it to QTStringFromSMPTETime. I’m not seeing
a convenient API for turning a frame number in to a SMPTETime.

A more general case that handles different frame rates isn’t simple,
as a QuickTime movie can handle arbitrary frame rates, and doesn’t
need to have a consistent frame rate, where SMPTE time code only
supports certain fixed frame rates. To try and do this as a general
case, you would need to look at the timescale of the movie, and the
durations of the frames, and try and work out if that is consistent
and what the best SMTPE frame rate is that would represent that. This
is further complicated by NTSC frame rates often being incorrectly set
as exactly 29.97fps, when it should be exactly 30/1.001, or rounded
values close to those.

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;
}
%d bloggers like this: