翻譯:AVPlayerItemOutput

@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 );
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章