VisionWorks Toolkit Reference

December 18, 2015 | 1.2 Release

 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Consuming Produced Frames

This section demonstrates how to query the EGL stream state to acquire produced frames.

Precondition
A producer (like NvMedia) has been connected to the EGL stream.
To consume produced frames
  1. Query the EGL stream state to determine whether a new frame is available:

    bool cudaConsumeEGLFrame(vx_context vxContext, CUeglStreamConnection cudaConsumer,
    EGLDisplay eglDisplay, EGLStreamKHR eglStream)
    {
    EGLint streamState = 0;
    if (!eglQueryStreamKHR(eglDisplay, eglStream, EGL_STREAM_STATE_KHR, &streamState))
    {
    printf("Cuda consumer, eglQueryStreamKHR EGL_STREAM_STATE_KHR failed\n");
    return false;
    }
    if (streamState == EGL_STREAM_STATE_DISCONNECTED_KHR)
    {
    printf("CUDA Consumer: - EGL_STREAM_STATE_DISCONNECTED_KHR received\n");
    return false;
    }
    else if (streamState != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR)
    {
    return true;
    }

    The cudaConsumer function returns false if a failure occurs or true otherwise.

  2. Acquire the newly produced frame:

    CUgraphicsResource cudaResource;
    CUresult cuStatus = cuEGLStreamConsumerAcquireFrame(&cudaConsumer, &cudaResource, NULL, 16000);
    if (cuStatus != CUDA_SUCCESS)
    {
    const char * error = NULL;
    cuGetErrorString(cuStatus, &error);
    printf("Cuda Acquire failed with the error: \"%s\"\n", error);
    return false;
    }
  3. Map the acquired CUDA graphics resource to an EGL frame instance:

    CUeglFrame eglFrame;
    cuStatus = cuGraphicsResourceGetMappedEglFrame(&eglFrame, cudaResource, 0, 0);
    if (cuStatus != CUDA_SUCCESS)
    {
    const char * error = NULL;
    cuGetErrorString(cuStatus, &error);
    printf("Cuda get resource failed with the error: \"%s\"\n", error);
    // release frame
    cuEGLStreamConsumerReleaseFrame(&cudaConsumer, cudaResource, NULL);
    return false;
    }

    CUeglFrame represents a simple CUDA buffer with additional properties like width, height, pitch, etc, so it can be wrapped by vx_image using the vxCreateImageFromHandle function for any processing:

    vxImageAddr.dim_x = eglFrame.width;
    vxImageAddr.dim_y = eglFrame.height;
    vxImageAddr.stride_x = 4;
    vxImageAddr.stride_y = eglFrame.pitch;
    vxImageAddr.scale_x = vxImageAddr.scale_y = VX_SCALE_UNITY;
    vxImageAddr.step_x = vxImageAddr.step_y = 1;
    void * ptrs[] = { eglFrame.frame.pPitch[0] };
    vx_image vxImage = vxCreateImageFromHandle(vxContext, VX_DF_IMAGE_RGBX, &vxImageAddr,
    // process frame
    // ...
    vxReleaseImage(&vxImage);
  4. After processing the EGL frame the CUDA consumer must release it:

    cuStatus = cuEGLStreamConsumerReleaseFrame(&cudaConsumer, cudaResource, NULL);
    return true;
    }

    You can see the full CUDA consumer procedure in the code below:

bool cudaConsumeEGLFrame(vx_context vxContext, CUeglStreamConnection cudaConsumer,
EGLDisplay eglDisplay, EGLStreamKHR eglStream)
{
EGLint streamState = 0;
if (!eglQueryStreamKHR(eglDisplay, eglStream, EGL_STREAM_STATE_KHR, &streamState))
{
printf("Cuda consumer, eglQueryStreamKHR EGL_STREAM_STATE_KHR failed\n");
return false;
}
if (streamState == EGL_STREAM_STATE_DISCONNECTED_KHR)
{
printf("CUDA Consumer: - EGL_STREAM_STATE_DISCONNECTED_KHR received\n");
return false;
}
else if (streamState != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR)
{
return true;
}
CUgraphicsResource cudaResource;
CUresult cuStatus = cuEGLStreamConsumerAcquireFrame(&cudaConsumer, &cudaResource, NULL, 16000);
if (cuStatus != CUDA_SUCCESS)
{
const char * error = NULL;
cuGetErrorString(cuStatus, &error);
printf("Cuda Acquire failed with the error: \"%s\"\n", error);
return false;
}
CUeglFrame eglFrame;
cuStatus = cuGraphicsResourceGetMappedEglFrame(&eglFrame, cudaResource, 0, 0);
if (cuStatus != CUDA_SUCCESS)
{
const char * error = NULL;
cuGetErrorString(cuStatus, &error);
printf("Cuda get resource failed with the error: \"%s\"\n", error);
// release frame
cuEGLStreamConsumerReleaseFrame(&cudaConsumer, cudaResource, NULL);
return false;
}
vxImageAddr.dim_x = eglFrame.width;
vxImageAddr.dim_y = eglFrame.height;
vxImageAddr.stride_x = 4;
vxImageAddr.stride_y = eglFrame.pitch;
vxImageAddr.scale_x = vxImageAddr.scale_y = VX_SCALE_UNITY;
vxImageAddr.step_x = vxImageAddr.step_y = 1;
void * ptrs[] = { eglFrame.frame.pPitch[0] };
vx_image vxImage = vxCreateImageFromHandle(vxContext, VX_DF_IMAGE_RGBX, &vxImageAddr,
// process frame
// ...
vxReleaseImage(&vxImage);
cuStatus = cuEGLStreamConsumerReleaseFrame(&cudaConsumer, cudaResource, NULL);
return true;
}