Streaming

Once initialized, the streaming loop looks like this:

/* Initialize empty fences for each direction*/
NvSciSyncFence nvmediaToCudaFence = NV_SCI_SYNC_FENCE_INITIALIZER;
NvSciSyncFence cudaToNvmediaFence = NV_SCI_SYNC_FENCE_INITIALIZER;

/* Main rendering loop */
while (!done) {
    NvMedia2DComposeresult result;
    NvMedia2DComposeParameters params;
    NvMedia2DGetComposeParameters(nvmedia2D, &params);

    /* Generate a fence when rendering finishes */
    NvMedia2DSetNvSciSyncObjforEOF(nvmedia2D, params,    nvmediaToCudaSync);

 
    /* Instruct NvMedia pipeline to wait for the fence from CUDA */
    NvMedia2DInsertPreNvSciSyncFence(nvmedia2D, params, cudaToNvmediaFence)
     /* Generate NvMedia image */
    NvMedia2DSomeRenderingOperation( ...);
    NvMedia2DCompose(nvmedia2D, params, &result);
 
    NvMedia2DGetEOFNvSciSyncFence(nvmedia2D, result, &nvmediaToCudaFence);
 
    /* Instruct CUDA pipeline to wait for fence from NvMedia */
    CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS cudaWaitParams;
    cudaWaitParams.params.nvSciSync.fence = (void*)&nvmediaToCudaFence;
    cudaWaitParams.flags = 0;
    cudaWaitExternalSemaphoresAsync(&nvmediaToCudaSem, &cudaWaitParams, 1, cudaStream);
 
    /* Process the frame in CUDA */
    cudaSomeProcessingOperation(..., cudaBuffer, ...);
 
    /* Generate a fence when processing finishes */
    CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS cudaSignalParams;
    cudaSignalParams.params.nvSciSync.fence = (void*)&cudaToNvmediaFence;
    cudaSignalParams.flags = 0;
    cudaSignalExternalSemaphoresAsync(&cudaToNvmediaSem, &cudaSignalParams, 1, cudaStream);
}

For each frame of data, the application instructs NvMedia to write the image to the buffer, and then issues a fence that indicates when writing finishes. CUDA is instructed to wait for that fence before it proceeds with any subsequent operations, then the commands to process the frame are issued to CUDA. Lastly, CUDA is told to generate a fence of its own, which indicates when all its operations finish. This fence is fed back to NvMedia, which waits for it before starting to write the next image to the buffer. "Ownership" of the buffer cycles back and forth between producer and consumer.

  • media/image3.png