@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 );
}