@class AVPlayerItemOutput
@abstract
AVPlayerItemOutput是一个封装了它的子类的通用API的抽象类。
@discussion
1.AVPlayerItemOutput实例允许你获得一个在AVPlayer播放过程中的AVAsset的一个独立的采样值。为了在当多个AVPlayerItemOutput应用在单一source时能优雅降档(graceful degradation),所有AVPlayerItemOutput子类只提供当前sample或者容易取得的future samples。所有在current sample之前的samples将被AVPlayerItemOutput自动丢弃。
2.你可以通过AVPlayerItem的下面两个方法来管理让一个AVPlayerItem作为source input与AVPlayerItemOutput之间的联系:(太长了好难捋顺语句…)
• addOutput:
• removeOutput:
3.当一个AVPlayerItemOutput与一个AVPlayerItem产生关联,在多个使能了的tracks中,samples会根据AVPlayer遵守的混合,合并或丢弃的规则来提供当做他们自己的渲染目的。(不会译直接上原文吧,samples are provided for a media type in accordance with the rules for mixing, composition, or exclusion that the AVPlayer honors among multiple enabled tracks of that media type for its own rendering purposes)。例如,video media会根据AVPlayerItem.videoComposition提供的指令来合并。
@class AVPlayerItemVideoOutput
@abstract
一个AVPlayerItemOutput的子类,把video images用CVPixelBuffers来“出售”?(vends)。
@discussion
最好是用一个AVPlayerItemVideoOutput连接一个CVDisplayLink or CADisplayLink的services,来确保与屏幕硬件刷新的同步。为了优化效率,这里可以有机会让services“静默”下来。例如当playback暂停或者在playback of empty edits的过程中。下面这个采样代码展示了在你使用AVPlayerItemVideoOutput时如何“静默”CVDisplayLink。
(void)CVDisplayLinkCreateWithActiveCGDisplays( &myDisplayLink );
CVDisplayLinkSetOutputCallback( myDisplayLink, myDisplayCallback, self );
[myPlayerItem addOutput:myVideoOutput];
[myVideoOutput setDelegate:self queue:myDispatchQueue];
...
static CVReturn myDisplayCallback ( CVDisplayLinkRef displayLink,
const CVTimeStamp *inNow,
const CVTimeStamp *inOutputTime,
CVOptionFlags flagsIn,
CVOptionFlags *flagsOut,
void *displayLinkContext )
{
MYObject *self = displayLinkContext;
CMTime outputItemTime = [[self myVideoOutput] itemTimeForCVTimeStamp:*inOutputTime];
if ( [[self myVideoOutput] hasNewPixelBufferForItemTime:outputItemTime] ) {
CVPixelBufferRef pixBuff = NULL;
CMTime presentationItemTime = kCMTimeZero;
self->myLastHostTime = inOutputTime->hostTime;
pixBuff = [[self myVideoOutput] copyPixelBufferForItemTime:outputItemTime itemTimeForDisplay:&presentationItemTime];
// Use pixBuff here
// presentationItemTime is the item time appropriate for
// the next screen refresh
CVBufferRelease( pixBuff );
}
else {
CMTime elapsedTime = CMClockMakeHostTimeFromSystemUnits( inNow->hostTime - self->myLastHostTime );
if ( CMTimeGetSeconds( elapsedTime ) > NON_QUIESCENT_PERIOD_IN_SECONDS ) {
[[self myVideoOutput] requestNotificationOfMediaDataChangeWithAdvanceInterval:MY_STARTUP_TIME_IN_SECONDS];
CVDisplayLinkStop( displayLink );
}
}
return kCVReturnSuccess;
}
- (void)outputMediaDataWillChange:(AVPlayerItemOutput *)output
{
// Start running again
myLastHostTime = CVGetCurrentHostTime();
CVDisplayLinkStart( myDisplayLink );
}