![]() |
OpenNI 1.5.4
|
Source file: Click the following link to view the source code file:
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.
@subsection cnvx2o_mainprg_dcl_blk 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 <code>seekNodeType</code> 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 <code>seekNodeType</code> initialization makes the program play back all nodes. @code XnUInt32 nStartFrame = 1; XnUInt32 nEndFrame = XN_MAX_UINT32; XnProductionNodeType seekNodeType = XN_NODE_TYPE_INVALID; @endcode @subsection cnvx2o_get_prod_node 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 @ref xn::xnProductionNodeTypeFromString "xnProductionNodeTypeFromString()". @code if (argc >= 4) { strNodeType = argv[3]; nRetVal = xnProductionNodeTypeFromString(strNodeType, &seekNodeType); if (nRetVal != XN_STATUS_OK) { ... } ... } @endcode The following initializes the @ref xn::Context object. This is where the application builds an OpenNI production graph. The <i>production graph</i> is a network of <i>production nodes</i> and is the principal OpenNI object structure. @code Context context; nRetVal = context.Init(); @endcode The following code uses the @ref xn::Player node to replay a recorded file of a session of OpenNI data generation exactly as it was recorded. <code>strInputFile</code> contains the input file name, as above. The @ref xn::Context::OpenFileRecording() "OpenFileRecording()" method replays a recorded file of a session of OpenNI data generation exactly as it was recorded. This includes recreating the whole @ref prod_graph "production graph", with all its nodes, that was built to run the original data generation session. @code Player player; nRetVal = context.OpenFileRecording(strInputFile, player); @endcode In the following statement, the @ref xn::Player::SetPlaybackSpeed() "SetPlaybackSpeed()" method sets the player's playback speed, as a ratio of the rate that the recording was made at. The value @ref xn::XN_PLAYBACK_SPEED_FASTEST (0.0) means that there will be no delay, and that frames will be returned immediately on demand. @code nRetVal = player.SetPlaybackSpeed(XN_PLAYBACK_SPEED_FASTEST); @endcode In the following statement, the @ref xn::Player::EnumerateNodes() "EnumerateNodes()" method places in <code>nodes</code> the list of all nodes created by the earlier call to @ref xn::Context::OpenFileRecording() "OpenFileRecording()". @code NodeInfoList nodes; nRetVal = player.EnumerateNodes(nodes); @endcode In the following, the call to @ref xn::Recorder::Create() "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. @code Recorder recorder; nRetVal = recorder.Create(context); @endcode In the following statement, the call to @ref xn::Recorder::SetDestination() "SetDestination()" specifies to where the recorder must send its recording. This is a disk file of ONI type. @code nRetVal = recorder.SetDestination(XN_RECORD_MEDIUM_FILE, strOutputFile); @endcode @subsection cnvx2o_for_add_all_nodes_to_the_recorder for() - Add all Nodes to the Recorder The following 'for' loop adds to the recorder all the nodes in the @ref xn::NodeInfoList "NodeInfoList" that were obtained from the earlier call to the @ref xn::Player::EnumerateNodes() "EnumerateNodes()" method. A NodeInfoList object contains a list of @ref xn::NodeInfo "NodeInfo" objects. The NodeInfo class contains information about a @ref node_alternative "node", whether it is an existing node, or not-yet instantiated. In this case it is instantiated. @code for (NodeInfoList::Iterator it = nodes.Begin(); it != nodes.End(); ++it) { ... } @endcode The body of the above for-loop is described in the following paragraphs. NodeInfo nodeInfo = *it; Ignore AudioGenerator nodes. @code if (nodeInfo.GetDescription().Type == XN_NODE_TYPE_AUDIO) { continue; } @endcode The following statements use the @ref xn::NodeInfo object to get a reference to the actual @ref xn::ProductionNode "ProductionNode" object. The ProductionNode class is a base class for all production nodes, including all @ref xn::Generator "Generator" nodes. Thus, the OpenNI Production Graph is comprised entirely of production nodes of one type or another. @code ProductionNode node; nRetVal = nodeInfo.GetInstance(node); @endcode The following '<code>if</code>' determines whether the user wants to play back all nodes or just one specific node. The XN_NODE_TYPE_INVALID value for <code>seekNodeType</code> indicates that the user wants to play back all nodes. This value was set in earlier code above. @code if (seekNodeType == XN_NODE_TYPE_INVALID) @endcode If the user wants all nodes to be played back and recorded then each and every node iterated by <code>nodeInfo</code> is added to the recorder. @ref xn::Recorder::AddNodeToRecording() "AddNodeToRecording()" adds a node to the recording, and starts recording data that the node generates. @code if (seekNodeType == XN_NODE_TYPE_INVALID) { nRetVal = recorder.AddNodeToRecording(node); } @endcode If the user specifies a certain node type, the program selects and records only nodes of that type, <code>seekNodeType</code>, in the run parameter (explained earlier). The @ref xn::Player::SeekToFrame() "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. <code>XN_PLAYER_SEEK_SET</code> specifies that the player must start from the frame number, <code>nStartFrame</code>. @code else if (seekNodeType == nodeInfo.GetDescription().Type) { nRetVal = player.SeekToFrame(node.GetName(), nStartFrame, XN_PLAYER_SEEK_SET); nRetVal = recorder.AddNodeToRecording(node); } @endcode In the following, @ref xn::Player::SetRepeat() "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). @code nRetVal = player.SetRepeat(FALSE); @endcode @subsection cnvx2o_main_prog_loop - 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 @ref xn::Context::WaitAnyUpdateAll() "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 @ref xn::Context::WaitAnyUpdateAll() "WaitAnyUpdateAll()" method has to be called for each and every loop to refresh the node's data. @code while ((nRetVal = depth.WaitAnyUpdateAll ()) != XN_STATUS_EOF) { ... } @endcode Inside the body of the main program loop <code>nFrame</code> 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. @code printf("Recording: %u\r", nFrame++); if ((seekNodeType != XN_NODE_TYPE_INVALID) && (nFrame == nEndFrame)) { break; } @endcode