playout.h

00001 /*
00002  * SpanDSP - a series of DSP components for telephony
00003  *
00004  * playout.h
00005  *
00006  * Written by Steve Underwood <steveu@coppice.org>
00007  *
00008  * Copyright (C) 2005 Steve Underwood
00009  *
00010  * All rights reserved.
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU Lesser General Public License version 2.1,
00014  * as published by the Free Software Foundation.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00024  */
00025 
00026 #if !defined(_SPANDSP_PLAYOUT_H_)
00027 #define _SPANDSP_PLAYOUT_H_
00028 
00029 /*! \page playout_page Play-out (jitter buffering)
00030 \section playout_page_sec_1 What does it do?
00031 The play-out module provides a static or dynamic length buffer for received frames of
00032 audio or video data. It's goal is to maximise the receiver's tolerance of jitter in the
00033 timing of the received frames.
00034 
00035 Dynamic buffers are generally good for speech, since they adapt to provide the smallest delay
00036 consistent with a low rate of packets arriving too late to be used. For things like FoIP and
00037 MoIP, a static length of buffer is normally necessary. Any attempt to elastically change the
00038 buffer length would wreck a modem's data flow.
00039 */
00040 
00041 /* Return codes */
00042 enum
00043 {
00044     PLAYOUT_OK = 0,
00045     PLAYOUT_ERROR,
00046     PLAYOUT_EMPTY,
00047     PLAYOUT_NOFRAME,
00048     PLAYOUT_FILLIN,
00049     PLAYOUT_DROP
00050 };
00051 
00052 /* Frame types */
00053 #define PLAYOUT_TYPE_CONTROL    0
00054 #define PLAYOUT_TYPE_SILENCE    1
00055 #define PLAYOUT_TYPE_SPEECH     2
00056 
00057 typedef int timestamp_t;
00058 
00059 typedef struct playout_frame_s
00060 {
00061     /*! The actual frame data */
00062     void *data;
00063     /*! The type of frame */
00064     int type;
00065     /*! The timestamp assigned by the sending end */
00066     timestamp_t sender_stamp;
00067     /*! The timespan covered by the data in this frame */
00068     timestamp_t sender_len;
00069     /*! The timestamp assigned by the receiving end */
00070     timestamp_t receiver_stamp;
00071     /*! Pointer to the next earlier frame */
00072     struct playout_frame_s *earlier;
00073     /*! Pointer to the next later frame */
00074     struct playout_frame_s *later;
00075 } playout_frame_t;
00076 
00077 /*!
00078     Playout (jitter buffer) descriptor. This defines the working state
00079     for a single instance of playout buffering.
00080 */
00081 typedef struct
00082 {
00083     /*! TRUE if the buffer is dynamically sized */
00084     int dynamic;
00085     /*! The minimum length (dynamic) or fixed length (static) of the buffer */
00086     int min_length;
00087     /*! The maximum length (dynamic) or fixed length (static) of the buffer */
00088     int max_length;
00089     /*! The target filter threshold for adjusting dynamic buffering. */
00090     int dropable_threshold;
00091 
00092     int start;
00093 
00094     /*! The queued frame list */
00095     playout_frame_t *first_frame;
00096     playout_frame_t *last_frame;
00097     /*! The free frame pool */
00098     playout_frame_t *free_frames;
00099 
00100     /*! The total frames input to the buffer, to date. */
00101     int frames_in;
00102     /*! The total frames output from the buffer, to date. */
00103     int frames_out;
00104     /*! The number of frames received out of sequence. */
00105     int frames_oos;
00106     /*! The number of frames which were discarded, due to late arrival. */
00107     int frames_late;
00108     /*! The number of frames which were never received. */
00109     int frames_missing;
00110     /*! The number of frames trimmed from the stream, due to buffer shrinkage. */
00111     int frames_trimmed;
00112 
00113     timestamp_t latest_expected;
00114     /*! The present jitter adjustment */
00115     timestamp_t current;
00116     /*! The sender_stamp of the last speech frame */
00117     timestamp_t last_speech_sender_stamp;
00118     /*! The duration of the last speech frame */
00119     timestamp_t last_speech_sender_len;
00120 
00121     int not_first;
00122     /*! The time since the target buffer length was last changed. */
00123     timestamp_t since_last_step;
00124     /*! Filter state for tracking the packets arriving just in time */
00125     int32_t state_just_in_time;
00126     /*! Filter state for tracking the packets arriving late */
00127     int32_t state_late;
00128     /*! The current target length of the buffer */
00129     int target_buffer_length;
00130     /*! The current actual length of the buffer, which may lag behind the target value */
00131     int actual_buffer_length;
00132 } playout_state_t;
00133 
00134 #if defined(__cplusplus)
00135 extern "C"
00136 {
00137 #endif
00138 
00139 /*! Queue a frame
00140     \param s The play-out context.
00141     \param data The frame data.
00142     \param sender_len Length of frame (for voice) in timestamp units.
00143     \param sender_stamp Sending end's time stamp.
00144     \param receiver_stamp Local time at which packet was received, in timestamp units.
00145     \return One of
00146         PLAYOUT_OK:  Frame queued OK.
00147         PLAYOUT_ERROR: Some problem occured - e.g. out of memory. */
00148 SPAN_DECLARE(int) playout_put(playout_state_t *s, void *data, int type, timestamp_t sender_len, timestamp_t sender_stamp, timestamp_t receiver_stamp);
00149 
00150 /*! Get the next frame.
00151     \param s The play-out context.
00152     \param frame The frame.
00153     \param sender_stamp The sender's timestamp.
00154     \return One of
00155         PLAYOUT_OK:  Suitable frame found.
00156         PLAYOUT_DROP: A frame which should be dropped was found (e.g. it arrived too late).
00157                       The caller should request the same time again when this occurs.
00158         PLAYOUT_NOFRAME: There's no frame scheduled for this time.
00159         PLAYOUT_FILLIN: Synthetic signal must be generated, as no real data is available for
00160                         this time (either we need to grow, or there was a lost frame).
00161         PLAYOUT_EMPTY: The buffer is empty.
00162  */
00163 SPAN_DECLARE(int) playout_get(playout_state_t *s, playout_frame_t *frame, timestamp_t sender_stamp);
00164 
00165 /*! Unconditionally get the first buffered frame. This may be used to clear out the queue, and free
00166     all its contents, before the context is freed.
00167     \param s The play-out context.
00168     \return The frame, or NULL is the queue is empty. */
00169 SPAN_DECLARE(playout_frame_t *) playout_get_unconditional(playout_state_t *s);
00170 
00171 /*! Find the current length of the buffer.
00172     \param s The play-out context.
00173     \return The length of the buffer. */
00174 SPAN_DECLARE(timestamp_t) playout_current_length(playout_state_t *s);
00175 
00176 /*! Find the time at which the next queued frame is due to play.
00177     Note: This value may change backwards as freshly received out of order frames are
00178           added to the buffer.
00179     \param s The play-out context.
00180     \return The next timestamp. */
00181 SPAN_DECLARE(timestamp_t) playout_next_due(playout_state_t *s);
00182 
00183 /*! Reset an instance of play-out buffering.
00184     NOTE:  The buffer should be empty before you call this function, otherwise
00185            you will leak queued frames, and some internal structures
00186     \param s The play-out context.
00187     \param min_length Minimum length of the buffer, in samples.
00188     \param max_length Maximum length of the buffer, in samples. If this equals min_length, static
00189            length buffering is used. */
00190 SPAN_DECLARE(void) playout_restart(playout_state_t *s, int min_length, int max_length);
00191 
00192 /*! Create a new instance of play-out buffering.
00193     \param min_length Minimum length of the buffer, in samples.
00194     \param max_length Maximum length of the buffer, in samples. If this equals min_length, static
00195            length buffering is used.
00196     \return The new context */
00197 SPAN_DECLARE(playout_state_t *) playout_init(int min_length, int max_length);
00198 
00199 /*! Release an instance of play-out buffering.
00200     \param s The play-out context to be releaased
00201     \return 0 if OK, else -1 */
00202 SPAN_DECLARE(int) playout_release(playout_state_t *s);
00203 
00204 /*! Free an instance of play-out buffering.
00205     \param s The play-out context to be destroyed
00206     \return 0 if OK, else -1 */
00207 SPAN_DECLARE(int) playout_free(playout_state_t *s);
00208 
00209 #if defined(__cplusplus)
00210 }
00211 #endif
00212 
00213 #endif
00214 /*- End of file ------------------------------------------------------------*/

Generated on 29 Jul 2015 for spandsp by  doxygen 1.6.1