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

Generated on Fri Nov 10 09:40:24 2006 for libspandsp by  doxygen 1.5.1