EGL Stream (nvm_eglstream)
EGL is an interface between Khronos rendering APIs such as OpenGL and the underlying native platform window system. It handles:
• Graphics context management
• Surface/buffer binding
• Rendering synchronization
It also enables high-performance, accelerated, mixed-mode 2D and 3D rendering using other Khronos APIs.
Architecture
EGLStream is an EGL object that exposes a set of APIs that transfer a sequence of EGL image frames between software components (e.g., video frames from NvMedia to OpenGL ES). Each EGLStream is associated with a producer that generates EGL image frames and inserts them into the EGLStream. The producer is responsible for inserting each EGL image frame into the EGLStream at the correct time so that the consumer can process the frame for the appropriate duration; for example, to display the EGL image frame.
Each EGLStream is associated with a consumer that retrieves EGL image frames from the EGLStream. The consumer is responsible for determining when an image frame is available and displaying it; or otherwise consuming it in some way. The consumer is also responsible for indicating the latency when that is possible. The latency is the time that elapses between when an image frame is retrieved from the EGLStream until the time it is delivered to the user.
EGL Image Frame
An EGL image frame is the entity posted by the producer to the EGLStream and acquired later by the consumer. The sequence can be:
• Frames of video data decoded from a video file
• Images output by a camera sensor
• Surfaces rendered using OpenGL commands
• Generated in some other manner
The color format for the image frame can be:
• RGBA and YUV420 planar
• YUV420 semi-planar
Different types of image frames must be posted to the EGLStream using different types of producers.
EGLStream Producer
The EGLStream producer is the entity that inserts or posts EGL image frames into the EGLStream. In the NvMedia domain, there are two types of producers:
• Video producer: posts NvMedia video surfaces as EGL image frames. Video surfaces can be generated by NvMedia video decoder, or NvMedia video capture, etc. The supported video surface formats include:
• NvMediaSurfaceType_R8G8B8A8
• NvMediaSurfaceType_Video_420
• Image producer: posts NvMedia image surfaces as EGL image frames. Image surfaces can be generated by NvMedia image capture, or NvMedia image JPEG decoder, etc. The supported image surface formats include:
• NvMediaSurfaceType_Image_RGBA
• NvMediaSurfaceType_Image_YUV_420
• Other types of producers
• CUDA producer: posts CUDA array or CUDA pointer as EGL image frames to the EGLStream.
• GL producer: posts graphic surfaces as EGL image frames to the EGLStream.
EGLStream Consumer
The EGLStream consumer is the entity that retrieves or acquires EGL image frames from the EGLStream. In the NvMedia domain, there are two types of consumers:
• Video consumer: acquires EGL image frames and fills the frame information in NvMedia video surfaces. Video surfaces acquired can then be consumed by NvMedia video encoder, or NvMedia video display, etc.
• Image consumer: acquires EGL image frames and fills the frame information in Nvmedia image surfaces (NvMediaImage). Image surfaces acquired can then be consumed by NvMedia image encoder, or NvMedia image display, etc.
• Other types of consumers
• CUDA consumer: retrieves EGL image frames and fills the frame information as CUDA array or CUDA pointer. The CUDA frames can then be processed in CUDA domain.
• GL consumer: retrieves EGL image frames that can then be used in graphic rendering.
• EGL output consumer: retrieves EGL image frames, and directly renders to EGL output. This consumer is valid when EGL output is used on the Linux platform.
EGLStream Operation Modes
There are two types of EGLStream operation modes: mailbox mode and FIFO mode. Both modes are supported by NvMedia producers and consumers.
Mailbox Mode
In mailbox mode, EGLStream conceptually operates as a mailbox. When a new frame is generated, the producer waits for a certain time for the consumer to process the frame. If the consumer does not consume the frame, the frame is discarded when the next frame is posted into the stream by the producer. This means that if the consumer consumes frames slower than the producer posts frames, some frames may be lost and never seen by the consumer. The producer is never stalled. Therefore, the timing of EGLStream in mailbox mode is controlled by the producer.
FIFO Mode
In FIFO mode, EGLStream operates as a FIFO rather than a mailbox. If the previous frame is not used by the consumer yet, the newly generated frame is added into an available slot in the queue. The FIFO size is set when it is created by the EGLStream. If the FIFO is full, the producer is stalled until there is room in the FIFO. This implies that the consumer has consumed some previous frames. In this mode, frames are not discarded.
The timing of an EGLStream in FIFO mode is the responsibility of the consumer. Each frame in the FIFO must be associated with a timestamp set by the producer. The consumer uses this timestamp to determine when the frame is intended to be processed.
EGLStream Pipeline
EGL provides functions to create and destroy EGLStreams, for querying and setting attributes of EGLStreams, and for connecting EGLStreams to producers and consumers. To use the EGLStream, it must be connected to a consumer before being connected to a producer.
Each EGLStream must be connected to only one producer and one consumer. Once an EGLStream is connected to a consumer, it is connected to that consumer until the EGLStream is destroyed. Likewise, once an EGLStream is connected to a producer it is connected to that producer until the EGLStream is destroyed.
Building a Simple EGLStream Pipeline
Before building simple EGLStream pipeline, you must initialize the EGL interface on the platform, and create the EGLDisplay.
1. Create the EGLDisplay object for the EGLStream to bind to it.
The following window interfaces are supported in the application:
• X11
• EGL device
• Wayland
There are separate implementations for each window system. For code details, see the following dictionary:
home/nvidia/samples/nvmedia/eglstream/winintf/
2. Initialize the EGL by calling eglInitialize() to initialize EGL on the created display or on the default display.
If GL consumer or EGL output consumer is used, you must initialize the rendering window before creating the EGL pipeline.
If NvMedia/CUDA producer-consumer is used, window system initialization is not required. In the absence of available display devices, EGL can be initialized using default display and instead of rendering, output can be an encoded (H.264) file for NvMedia consumer.
There are separate implementations of GrUtilWindowInit() for different window system. For more information, see the EGLDisplay implementations in the winintf dictionary.
3. Create an EGLStream.
The following example is from eglstrm_setup.c.
// Standalone consumer or no standalone mode
eglStream = eglCreateStreamKHR(display,
args->fifoMode ? streamAttrFIFOMode : streamAttrMailboxMode);
if (eglStream == EGL_NO_STREAM_KHR) {
LOG_ERR("EGLStreamInit: Couldn't create eglStream.\n");
return 0;
}
Depending on the mailbox mode or FIFO mode used, the EGLStream sample sets the attrib_list to one of the arrays shown in the following example.
static const EGLint streamAttrMailboxMode[] = {
EGL_METADATA0_SIZE_NV, 16*1024,
EGL_METADATA1_SIZE_NV, 16*1024,
EGL_METADATA2_SIZE_NV, 16*1024,
EGL_METADATA3_SIZE_NV, 16*1024, EGL_NONE };
static const EGLint streamAttrFIFOMode[] = {
EGL_STREAM_FIFO_LENGTH_KHR, 4,
EGL_METADATA0_SIZE_NV, 16*1024,
EGL_METADATA1_SIZE_NV, 16*1024,
EGL_METADATA2_SIZE_NV, 16*1024,
EGL_METADATA3_SIZE_NV, 16*1024, EGL_NONE };
4. Create a consumer and connect it to the EGLStream.
Once an EGLStream is connected to a consumer, it must remain connected to the same consumer until the EGLStream is destroyed.
The EGLStream sample application defines the following consumer creation functions:
video_display_init(); //Initializes an NvMedia video consumer.
image_display_init(); //Initializes an NvMedia image consumer.
cuda_consumer_init(); //Initializes a CUDA consumer.
glConsumer_init(); //Initializes a GL consumer.
screenConsumer_init(); //Initializes a screen consumer.
Each consumer creation function starts a process thread for procThreadFunc(). procThreadFunc(), which is specific to the consumer, acquires and processes EGL frames. The following example is from cuda_consumer.c.
pthread_create(&cudaConsumer->procThread, NULL, procThreadFunc, (void *)cudaConsumer);
if (!cudaConsumer->procThread) {
LOG_ERR("Cuda consumer init: Unable to create process thread\n");
cudaConsumer->procThreadExited = NV_TRUE;
return NV_FALSE;
}
5. Create a producer and connect it to the EGLStream.
The EGLStream must be connected to consumer before connecting to a producer. Once an EGLStream is connected to a producer, it must remain connected to the same producer until the EGLStream is destroyed.
The EGLStream sample application defines the following producer creation functions:
VideoDecoderInit (); //NvMedia video producer init
Image2DInit (); //NvMedia image producer init
CudaProducerInit (); //cuda producer init
GearProducerInit (); //GL producer init
A process thread is also started for EGL frame generating and posting.
Acquiring a Single Frame
A consumer acquires one frame, processes it, and releases it before acquiring the next frame. Consequently a consumer holds, at most, one frame at any time in both mailbox and FIFO mode.
Single Frame communication between producer and consumer in the EGLStream pipeline are as follows:
• Producer posts EGL image frame (video surface or image surface) to the EGLStream using NvMediaEglStreamProducerPostSurface() or NvMediaEglStreamProducerPostImage().
The following example is from nvmvid_producer.c.
status = NvMediaEglStreamProducerPostSurface(parser->producer,
renderSurface, timestamp);
if(status != NVMEDIA_STATUS_OK) {
EGLint streamState = 0;
if(!eglQueryStreamKHR(
parser->eglDisplay,
parser->eglStream,
EGL_STREAM_STATE_KHR,
&streamState)) {
LOG_ERR("main: eglQueryStreamKHR EGL_STREAM_STATE_KHR
failed\n");
}
if(streamState != EGL_STREAM_STATE_DISCONNECTED_KHR &&
!parser->stopDecoding)
LOG_ERR("SendRenderSurface: NvMediaPostSurface
failed\n");
return 0;
• Consumer acquires/retrieves EGL image frame (video surface or image surface) from the EGLStream. The consumer acquires/retrieves the frame with NvMediaEglStreamConsumerAcquireSurface() or NvMediaEglStreamConsumerAcquireImage(). If there is no new frame available for the surface, those functions return NULL.
The following example is from nvmvid_consumer.c.
if(NVMEDIA_STATUS_ERROR ==
NvMediaEglStreamConsumerAcquireSurface(display->consumer,
&surface, 16, &timeStamp)) {
LOG_DBG("Nvmedia video Consumer: - surface acquire
failed\n");
display->quit = NV_TRUE;
goto done;
}
• Consumer releases the EGL image frame (surface) after consuming it, using NvMediaEglStreamConsumerReleaseSurface() or NvMediaEglStreamConsumerReleaseImage().
• Producer gets the EGL image frame (surface) back after consumer releases it. The producer can then update the surface and post later. If there is no frame released from consumer, it must return NULL for the surface using NvMediaEglStreamProducerGetSurface() or NvMediaEglStreamProducerGetImage().
The following example is from nvmvid_producer.c.
NvMediaVideoSurface *videoSurface = NULL;
NvMediaStatus status;
status = NvMediaEglStreamProducerGetSurface(ctx->producer,
&videoSurface, 100);
if(status == NVMEDIA_STATUS_TIMED_OUT) {
LOG_DBG("cbAllocPictureBuffer: NvMediaGetSurface
waiting\n");
} else if(status == NVMEDIA_STATUS_OK) {
ReleaseFrame(ctx, videoSurface);
} else
goto failed;
In the NvMedia EGLStream sample application, two threads are created:
• One for producer
• One for consumer
In each of the thread process function, ProducerProc() and ConsumerProc(), the following diagram shows which functions are called in each thread for EGLStream frame communication.
Acquiring Multiple Frames
Before releasing for the first time, the consumer acquires multiple frames. This means the consumer can hold more than one frame during the active processing time. Use FIFO mode for acquiring multiple frames. For NvMedia consumer type, the maximum frame number a consumer can hold is 6. The frame communication is the same as for acquiring a single case; except in ConsumerProc(), the ConsumerAcquireSurface is called more than once before ConsumerReleaseSurface gets called. Consumer must verify that the surface is released in the same order as they are acquired, i.e., first in first out manner.
Managing the EGLStream Pipeline Buffer
To prevent the producer from overwriting the frame buffer when the consumer still processes the frame, it is recommended that you create a buffer pool at the producer side. The buffer pool size can be 2 or more, depending on the application. If buffer pool size equals 2, the producer can generate and post one frame to the EGLStream, then the producer can generate the second frame using the second buffer in the pool without waiting for the consumer to consume the first frame. When the consumer finishes and releases the first frame back to the producer, the producer can then reuse the first frame buffer for the third frame.
When acquiring multiple frames, the buffer pool size must be at least n+1.
• Where: <n> is the number of frames the consumer holds at any time.
Destroying the EGLStream Pipeline
To destroy the EGLStream pipeline, you must:
1. Destroy the producer
2. Destroy the consumer
3. Destroy the EGLStream
4. Destroy the resources for the window system
EGLStream sample functions that destroy producers are:
VideoDecoderDeinit() //Video producer destroy
Image2DDeinit() //Image producer destroy
CudaProducerDeinit() //CUDA producer destroy
EGLStream sample functions that destroy consumers are:
video_display_Deinit() //Video consumer destroy
image_display_Deinit() //Image consumer destroy
cuda_consumer_Deinit() //CUDA consumer destroy
For example:
if(args.nvmediaVideoProducer)
VideoDecoderFlush();
else if(args.nvmediaImageProducer)
Image2DproducerFlush();
LOG_DBG("main - flush produer and consumer eglstream: Done\n");
LOG_DBG("main - program end, clean up start\n");
if(args.nvmediaVideoProducer)
VideoDecoderDeinit();
else if (args.nvmediaImageProducer)
Image2DDeinit();
else if (args.cudaProducer) {
#ifdef CUDA_SUPPORT
CudaProducerDeinit();
#endif
}
else if(args.glProducer) {
GearProducerDeinit();
}
The EGLStream sample function that destroys the EGLStream is:
EGLStreamFini()
The EGLStream sample code for that shuts down the window interface is:
GrUtilShutdown()
GrUtilShutdown() is in the folder:
eglstream/winintf
It calls GrUtilWindowTerm() and GrUtilDisplayTerm(), each has different implementation for different window interface.
Transitioning the EGLStream State
After an EGLStream is created, at any given time, the EGLStream is in one of the following defined states:
• EGL_STREAM_STATE_CREATED_KHR The EGLStream has been created but not yet connected to a producer or a consumer.
• EGL_STREAM_STATE_CONNECTING_KHR The EGLStream has been connected to a consumer but not yet connected to a producer.
• EGL_STREAM_STATE_EMPTY_KHR The EGLStream has been connected to a consumer and a producer, but the producer has not yet posted any image frames.
• EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR The producer has posted at least one image frame that the consumer has not yet acquired.
• EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR The producer has posted at least one image frame, and the consumer has already acquired the most recently posted image frame.
• EGL_STREAM_STATE_DISCONNECTED_KHR The producer, or the consumer, or both, are no longer connected to the EGLStream (e.g. they have been destroyed). Once the EGLStream is in this state it remains in this state until the EGLStream is destroyed. In this state only eglQueryStreamKHR and eglDestroyStreamKHR are valid operations.
The EGLStream state is queried as follows:
EGLBoolean eglQueryStreamuKHR(
EGLDisplay dpy,
EGLStreamKHR stream,
EGLenum attribute,
EGLuint64KHR *value);
The following state transitions may occur:
1. EGL_STREAM_STATE_CREATED_KHR A new EGLStream is created in this state.
2. EGL_STREAM_STATE_CREATED_KHR -> EGL_STREAM_STATE_CONNECTING_KHR Occurs when a consumer is connected to the EGLStream.
3. EGL_STREAM_STATE_CONNECTING_KHR -> EGL_STREAM_STATE_EMPTY_KHR Occurs when a producer is connected to the EGLStream.
4. EGL_STREAM_STATE_EMPTY_KHR -> EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR Occurs the first time the producer inserts an EGL image frame.
5. EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR -> EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR Occurs when the consumer begins acquiring a newly posted EGL image frame.
6. EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR -> EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR Occurs when the producer posts a new EGL image frame.
7. ANY STATE -> EGL_STREAM_STATE_DISCONNECTED_KHR Occurs when the producer or consumer is destroyed.
Building a Cross Process EGLStream Pipeline
To build a cross process EGLStream pipeline, the EGLStream is created by the consumer process. Then, the consumer gets the file descriptor for the EGLStream and send the file descriptor through socket.
In the producer process, the producer receives the file descriptor through socket, then creates the EGLStream from the file descriptor. After the EGLStream is created in both consumer and producer processes, the consumer and the producer is created and connected to the EGLStream.
Building a Cross Partition EGLStream Pipeline
The EGLStream can also be used across multiple partitions in a multi-OS environment. For more details about setting up and configuring multiple OSes, refer to the Foundation documentation.
To build a cross partition EGLStream pipeline, the EGLStream is created by the consumer process on consumer partition. The consumer creates a socket and waits for the producer to connect to that socket.
The producer uses the IP of the partition on which the consumer is running and the specific port on which EGLStream was created by the consumer to connect to it. After a successful connection, the producer creates an EGLStream using the same handle. After the EGLStream is created in both consumer and producer processes, the consumer and the producer are created and connected to the same EGLStream.
EGLStream Application
The NvMedia EGLStream sample application demonstrates how to:
• Create and initialize EGLStream, NvMedia EGLStream producers, NvMedia EGLStream consumers.
• Get the EGLStreams to work together to post and acquire video or image surfaces.
• Make the code modularized so that the producers and consumers are running in their own threads in the same or different partitions.
Two types of NvMedia producers and two types of NvMedia consumers are supported:
• For the NvMedia video producer, video decoder is used to generate video frames. Then, the video producer posts the video surface, in the form of NvMediaVideoSurface, to the EGLStream.
• On the NvMedia video consumer side, after the video consumer acquires video surface, it uses either video mixer to display the video frames, or video encoder to encode the video frames.
• For the NvMedia image producer, the image data is read from the YUV file to generate image surfaces, in the form of NvMediaImage, then the image producer posts the image surfaces to the EGLStream.
• On the NvMedia image consumer side, after the image consumer acquires the image surface, it uses the image display to display the image frames.
To demonstrate the NvMedia/GL/CUDA/Screen EGLStream interoperability, the application includes sample code for creating and using GL producer, GL consumer, CUDA producer, and CUDA consumer.
• For GL producer, the Gear application is used to generate graphic frames.
• For GL consumer, graphic display is used.
• For CUDA producer, the image is read from the YUV or RGB file. Then it is copied to CUDA array or CUDA device pointer. The producer posts it to the EGLStream.
• For CUDA consumer, after the consumer acquires the frame, the data is saved to the file.
• For Screen window consumer, the received frames are directly rendered to the display.
Command Line Options
The following shows the command syntax:
./nvm_eglstream -f <input filename> -producer <producer_type> -consumer <consumer_type> [-optional_options]
To run the EGLStream in an X11 target
1. Start X11.
X -ac
2. Set the display.
export DISPLAY=:0
The above steps are not required for EGL device interface.
Required Options
The following table describes the required command line options.
Option | Parameter | Description |
-f | [input_file] | Input filename for producer • H.264 file for Video producer • YUV file for Image producer • RGBA/YUV file for CUDA producer |
-producer | [type] | Set producer type • 0: Video producer • 1: Image producer • 2: GL producer • 3: CUDA producer The producer type must be specified in the consumer process for cross-process and cross-partition. |
-consumer | [type] | Set consumer type • 0: Video consumer • 1: Image consumer • 2: GL consumer • 3: CUDA consumer • 4: Screen window consumer (QNX screen] EGL output consumer (using EGL output on Linux) The consumer type must be specified in the producer process for cross-process and cross-partition use. |
-d | [id] | Display ID |
-ot | [type] | Surface type used: YUV420/YUV420p/RGBA. Default is RGBA. YUV420 posts semiplanar; use YUV420p for planar surfaces (valid for CUDA/image producers) |
-fr | [WxH] | Input file resolution. Mandatory for Image/CUDA producer. |
-enc | [output_file] | Encode mode. Enabled for consumer type 0 and 1. |
Other Options
The following table describes the optional command line options.
Option | Parameter | Description |
-h | N/A | Displays guidance on using this application. |
-v | [level] | Logging level= • 0 (Errors) • 1 (Warnings) • 2 (Information) • 3 (Debug) |
-fifo | N/A | set FIFO mode for EGL stream; otherwise mailbox mode is used |
-metadata | N/A | Enables metadata for the EGL stream. |
-standalone | [mode] | Set standalone mode (cross process/cross partition mode for producer and consumer) • 0: Single process mode (default) • 1: Cross process producer • 2: Cross process consumer • 3: Cross partition producer • 4: Cross partition consumer |
-pl | N/A | Image/CUDA producer uses pitch linear surface, if present. Otherwise, uses block linear surface. |
-consumervm | [partition_id] | Sets VM ID of partition in which cross-partition consumer is running for cross-partition producer. |
-ip | [ip_address] | Sets IP address of partition in which cross-partition consumer is running for cross-partition producer. |
-socketport | [port_num] | Sets port number used by cross-partition consumer during EGLStream creation for cross-partition producer. Default: 8888 |
-defaultdisplay | N/A | To avoid initializing the window system, use the default EGL display for NvMedia/CUDA producer/consumer during eglInitialize. |
-w | [window_id] | Displays window ID [0-1], default=1, for Video/Image consumer. |
-l | [loop_num] | Number of loops for Video/Image producer. Default=1. |
-shader | [type] | Shader type: YUV/RGB (default). Shader type is used when GL consumer is enabled. |
Single Process Examples
This topic explains how to perform single process tasks.
To run an NvMedia video producer and consumer to encode H.264
../egldevice/nvm_eglstream -f disney.264 -producer 0 -consumer 0 -ot rgba -defaultdisplay -enc encode.264
To run an NvMedia video for a producer and consumer
./nvm_eglstream -f test.264 -producer 0 -consumer 0 -d 0 [-ot yuv420]
To run an NvMedia image for a producer and consumer
./nvm_eglstream -f test.yuv -fr 720x480 -producer 1 -consumer 1 -d 0 [-ot yuv420]
To run an NvMedia video producer and a GL consumer
./nvm_eglstream -f test.264 -producer 0 -consumer 2 [-ot yuv420]
To run an NvMedia image producer and a GL consumer
./nvm_eglstream -f test.yuv -fr 720x480 -producer 1 -consumer 2 [-ot yuv420]
To run an NvMedia video producer and a CUDA consumer
./nvm_eglstream -f test.264 -producer 0 -consumer 3 [-ot yuv420 -pl]
Once properly setup, you can view the save output using yuvviewer. The output is saved to cuda.yuv.
To run an NvMedia image producer and a CUDA consumer
./nvm_eglstream -f test.yuv -fr 720x480 -producer 1 -consumer 3 [-ot yuv420 -pl]
Once properly setup, you can view the save output using yuvviewer. The output is saved to cuda.yuv.
To run a CUDA producer and consumer
./nvm_eglstream -f test.yuv -fr 720x480 -producer 3 -consumer 3 [-ot yuv420 -pl]
Once properly setup, you can view the save output using yuvviewer. The output is saved to cuda.yuv.
To run an NvMedia video producer and an EGLOutput consumer
This example is valid for Linux and EGLOutput.
./nvm_eglstream -f test.264 -producer 0 -consumer 4 [-ot yuv420]
To run an NvMedia image producer and an EGL Output consumer
This example is valid for Linux with EGLOutput.
./nvm_eglstream -f test.yuv -fr 720x480 -producer 1 -consumer 4 [-ot yuv420]
Cross Process Examples
The following cross process examples can be executed in two shells or run in the background in one shell.
The examples provided are similar to those described for single process samples except for an additional argument -consumer.
To run cross process samples, add standalone 1 for producer, and standalone 2 for consumer. Mention the consumer type in the producer thread using the -consumer argument.
To run an NvMedia image producer and an NvMedia video consumer
./nvm_eglstream -standalone 2 -producer 1 -consumer 0 -ot rgba -enc encode.264
./nvm_eglstream -standalone 1 -producer 1 -consumer 0 -f -ot rgba
To run an NvMedia video producer and consumer
./nvm_eglstream -f test.h264 -producer 0 -standalone 1 -consumer 0 [-ot yuv420]
./nvm_eglstream -consumer 0 -standalone 2 -producer 0 -d 0 [-ot yuv420]
To run an NvMedia video producer and an NvMedia image consumer
./nvm_eglstream -f test.h264 -producer 0 -standalone 1 -consumer 1 [-ot yuv420]
./nvm_eglstream -consumer 1 -standalone 2 -producer 0 -d 0 [-ot yuv420]
Cross Partition Examples
The following cross partition examples can be executed in two shells, one for each partition.
The examples provided are similar to those described for cross process samples except for a few additional arguments: -consumervm, -ip, and -socketport.
To run cross partition samples, hv0 of both the consumer and producer partition must be configured to use two different IP address. For example, on VM1 (producer), set it to 12.0.0.2 using:
ifconfig hv0 12.0.0.2
Similarly, on consumer partition, hv0 can be set to 12.0.0.1.
Add standalone 3 for producer, and standalone 4 for consumer.
In the producer process, mention the VM ID of the consumer partition using the -consumervm argument. Set -ip as the IP of consumer partition, i.e., 12.0.0.1, as in the above example. Set -socketport to the same port number used while creating EGLStream in the consumer process.
If the producer is running on a partition that does not own the display, specify the -defaultdisplay option in the command line while executing producer to use the default EGL display for EGL initialization.
Set the DISPLAY_VM environment variable on the consumer partition. If EGLOutput consumer is being used, set the DISPLAY_VM environment variable on the producer partition as well before executing the producer thread.
To run an NvMedia video producer and consumer
On VM1, where producer will be running:
./nvm_eglstream -f test.h264 -producer 0 -standalone 1 -consumer 0 [-ot yuv420]
On VM0, where consumer will be running:
./nvm_eglstream -consumer 0 -standalone 2 -producer 0 -d 0 [-ot yuv420]
To run an NvMedia video producer and an NvMedia image consumer
On VM1, where producer will be running:
./nvm_eglstream -f test.h264 -producer 0 -standalone 1 -consumer 1 [-ot yuv420]
On VM0, where consumer will be running:
./nvm_eglstream -consumer 1 -standalone 2 -producer 0 -d 0 [-ot yuv420]