The Capturing and Playing Module must communicate with the RTP module. Recording thread sends encoded frames to the transmitting RTP, and the playing thread receives frames from the receiving RTP module. The module that allows this communication is the Audio Queue module. This module is optimized to store blocks of audio data (samples or audio frames). The queue, when initiated, is located between receiving/transmitting RTP thread and recorder/player thread. There may be many queues created, depending on how many audio engine threads are active. Recording thread and transmitting RTP must get the same queue pointer to work properly, and the same to playing thread and receiving RTP.
The queue contains two sets of buffers: free and used. Free buffers are those that are empty and can be filled with digital audio data. Used buffers are those containing digital audio data.
The main data structure is the frame_queue structure. This is a structure describing all features of the queue. A pointer to this structure (typedefed as fqp) is commonly used by all functions working with this queue. This pointer is also passed to the playing/recording thread and the RTP thread. There is no need of know the internals of this structure to use it properly.
The buf_struct structure describes a buffer (a single node of the queue).
struct buf_struct{
char *payload; /* digital audio data (payload) */
timestp timestamp; /* timestamp */
bsp next; /* For internal use only */
};
The pointer to this structure is typedefed as
bsp and it is returned by
the get_buffer() and reserve_buffer() functions (described later).All queue-functions are multi-thread safe, the data is protected by critical sections. These mechanisms are run with no user's effort, they are placed inside the routines described below.
prepare_queue Creates a new queue object.
This function initiates a queue with buf_num buffers and payload_len payload length. All data is allocated it the function body, not while using it. All buffers in queue are designated as "free" buffers. No "used" buffers exist.reserve_buffer Reserves a single buffer.
This function reserves (locks) a single buffer from the set of "free" buffers. It returns a pointer to that buffer. If no buffers are available, this function blocks. A buffer, when reserved can be used only by someone who owes the returned pointer (i.e., the reserving thread). It is not accessible for others.reserve_buffer_nb A non-blocking version of the reserve_buffer function.
It returns NULL if no "free" buffers are available.put_buffer Puts the previously reserved buffer into queue.
buffer is the reserved buffer. This buffer is added to the set of "used" buffers (at the end of the FIFO inside).get_buffer Returns a buffer from the queue.
This function gets the oldest buffer from the "used" buffers set (the first in the FIFO). If no buffers are available the function blocks.get_buffer_nb A non-blocking version of the get_buffer function.
It returns NULL if no "used" buffers are available.get_buffer_when_notless Gets a buffer on condition.
The get_buffer_when_notless function gets a buffer if there are not less "used" buffers than num in the queue. This function a blocking one.giveback_buffer Returns a buffer to the queue.
This function gives back a buffer returned by get_ functions if no longer needed. Adds the buffer to the set of "free" buffers.get_buffer_len Returns the length of a buffer.
Every buffer in the queue queue is the same length (specified when preparing the a queue). This function allows to check the length.get_buffer_no Returns the number of all the buffers in the queue.
The returned value is a sum of "used", "free" and "reserved" buffers.turn_on_sorting and turn_off_sorting Turn sorting on or off, respectively.
The turn_on_sorting function turns on the sorting of frames (according to the timestamp field). The turn_off_sorting function turns the sorting off. turn_on_sorting should be called before the queue queue is used.