OpenNI 1.5.4: NiConvertXToONI.cpp - sample program

OpenNI

NiConvertXToONI.cpp - sample program

Source file: Click the following link to view the source code file:

  • NiConvertXToONI.cpp

The program opens any recording, takes every node in this recording, and records it to a new ONI recording. It receives both input file and output file from the command line.

The documentation describes the sample program's code from the top of the program file(s) to bottom.

Every OpenNI feature is described the first time it appears in this sample program. Further appearances of the same feature are not decribed again.

main() – Main Program

Main Program Declaration Block

The following code block sets the limits for the main program loop later in the program.

Setting seekNodeType to xn::XN_NODE_TYPE_INVALID "XN_NODE_TYPE_INVALID" is an initialization for seekNodeType gets from the users run arguments an indication whether the user wants to play back all nodes or just one specified node. The XN_NODE_TYPE_INVALID value for seekNodeType initialization makes the program play back all nodes.

                XnUInt32 nStartFrame = 1;
                XnUInt32 nEndFrame = XN_MAX_UINT32;
                XnProductionNodeType seekNodeType = XN_NODE_TYPE_INVALID;

Get a Production Node From a String

If the node type parameter (the third command line parameter) is specified, we translate the node type from a string to an XnProductionNodeType value using xnProductionNodeTypeFromString().

                if (argc >= 4)
                {
                    strNodeType = argv[3];
                    nRetVal = xnProductionNodeTypeFromString(strNodeType, &seekNodeType);
                    if (nRetVal != XN_STATUS_OK)
                    {
                        ...
                    }
                    ...
                }       

The following initializes the xn::Context object. This is where the application builds an OpenNI production graph. The production graph is a network of production nodes and is the principal OpenNI object structure.

                Context context;
                nRetVal = context.Init();

The following code uses the xn::Player node to replay a recorded file of a session of OpenNI data generation exactly as it was recorded. strInputFile contains the input file name, as above.

The OpenFileRecording() method replays a recorded file of a session of OpenNI data generation exactly as it was recorded. This includes recreating the whole production graph, with all its nodes, that was built to run the original data generation session.

                Player player;
                nRetVal = context.OpenFileRecording(strInputFile, player);

In the following statement, the SetPlaybackSpeed() method sets the player's playback speed, as a ratio of the rate that the recording was made at. The value xn::XN_PLAYBACK_SPEED_FASTEST (0.0) means that there will be no delay, and that frames will be returned immediately on demand.

                nRetVal = player.SetPlaybackSpeed(XN_PLAYBACK_SPEED_FASTEST);

In the following statement, the EnumerateNodes() method places in nodes the list of all nodes created by the earlier call to OpenFileRecording().

                NodeInfoList nodes;
                nRetVal = player.EnumerateNodes(nodes);

In the following, the call to Create() initializes a Recorder object. This object records to a specified destination medium the frames of data from each node that was added to the Recorder node.

                Recorder recorder;
                nRetVal = recorder.Create(context);

In the following statement, the call to SetDestination() specifies to where the recorder must send its recording. This is a disk file of ONI type.

                nRetVal = recorder.SetDestination(XN_RECORD_MEDIUM_FILE, strOutputFile);

for() - Add all Nodes to the Recorder

The following 'for' loop adds to the recorder all the nodes in the NodeInfoList that were obtained from the earlier call to the EnumerateNodes() method. A NodeInfoList object contains a list of NodeInfo objects. The NodeInfo class contains information about a node, whether it is an existing node, or not-yet instantiated. In this case it is instantiated.

                for (NodeInfoList::Iterator it = nodes.Begin(); it != nodes.End(); ++it)
                {
                 ...
                }

The body of the above for-loop is described in the following paragraphs.

NodeInfo nodeInfo = *it;

Ignore AudioGenerator nodes.

                    if (nodeInfo.GetDescription().Type == XN_NODE_TYPE_AUDIO)
                    {
                        continue;
                    }

The following statements use the xn::NodeInfo object to get a reference to the actual ProductionNode object. The ProductionNode class is a base class for all production nodes, including all Generator nodes. Thus, the OpenNI Production Graph is comprised entirely of production nodes of one type or another.

                    ProductionNode node;
                    nRetVal = nodeInfo.GetInstance(node);

The following 'if' determines whether the user wants to play back all nodes or just one specific node. The XN_NODE_TYPE_INVALID value for seekNodeType indicates that the user wants to play back all nodes. This value was set in earlier code above.

                    if (seekNodeType == XN_NODE_TYPE_INVALID)

If the user wants all nodes to be played back and recorded then each and every node iterated by nodeInfo is added to the recorder. AddNodeToRecording() adds a node to the recording, and starts recording data that the node generates.

                    if (seekNodeType == XN_NODE_TYPE_INVALID)
                    {
                        nRetVal = recorder.AddNodeToRecording(node);
                    }

If the user specifies a certain node type, the program selects and records only nodes of that type, seekNodeType, in the run parameter (explained earlier).

The SeekToFrame() moves the player to a specific frame of a specific node, e.g., a DepthGenerator node, so it sets up the player so that it will play that node and from that frame onwards. XN_PLAYER_SEEK_SET specifies that the player must start from the frame number, nStartFrame.

                    else if (seekNodeType == nodeInfo.GetDescription().Type)
                    {
                        nRetVal = player.SeekToFrame(node.GetName(), nStartFrame, XN_PLAYER_SEEK_SET);
                        nRetVal = recorder.AddNodeToRecording(node);
                    }               

In the following, SetRepeat() specifies that the player will not automatically rewind to the beginning of the recording after reaching the end of the recording (the default behavior is to rewind).

                    nRetVal = player.SetRepeat(FALSE);

- Main Program Loop

Following is the main program loop. It waits for available data from any generator node and records it. The call to the context.WaitAnyUpdateAll() method updates all generator nodes in the context to the latest available data, first waiting for any of the nodes to have new data available. Since this method is being fed from a recording, the end of the recording is indicated by returning the XN_STATUS_EOF value.

Note that the WaitAnyUpdateAll() method has to be called for each and every loop to refresh the node's data.

                while ((nRetVal = depth.WaitAnyUpdateAll ()) != XN_STATUS_EOF)
                {
                    ...
                }

Inside the body of the main program loop nFrame is incremented. An 'if' statement tests whether the user has specified a single node type and if so, and if the requested number of frames has been played back, then the execution of the main program loop is terminated.

                printf("Recording: %u\r", nFrame++);
                if ((seekNodeType != XN_NODE_TYPE_INVALID) && (nFrame == nEndFrame))
                {
                    break;          
                }
Generated on Wed May 16 2012 10:16:06 for OpenNI 1.5.4 by   doxygen 1.7.5.1