comparison spandsp-0.0.6pre17/src/spandsp/playout.h @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
comparison
equal deleted inserted replaced
3:c6c5a16ce2f2 4:26cd8f1ef0b1
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * playout.h
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2005 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 2.1,
14 * as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: playout.h,v 1.14 2009/02/10 13:06:47 steveu Exp $
26 */
27
28 #if !defined(_SPANDSP_PLAYOUT_H_)
29 #define _SPANDSP_PLAYOUT_H_
30
31 /*! \page playout_page Play-out (jitter buffering)
32 \section playout_page_sec_1 What does it do?
33 The play-out module provides a static or dynamic length buffer for received frames of
34 audio or video data. It's goal is to maximise the receiver's tolerance of jitter in the
35 timing of the received frames.
36
37 Dynamic buffers are generally good for speech, since they adapt to provide the smallest delay
38 consistent with a low rate of packets arriving too late to be used. For things like FoIP and
39 MoIP, a static length of buffer is normally necessary. Any attempt to elastically change the
40 buffer length would wreck a modem's data flow.
41 */
42
43 /* Return codes */
44 enum
45 {
46 PLAYOUT_OK = 0,
47 PLAYOUT_ERROR,
48 PLAYOUT_EMPTY,
49 PLAYOUT_NOFRAME,
50 PLAYOUT_FILLIN,
51 PLAYOUT_DROP
52 };
53
54 /* Frame types */
55 #define PLAYOUT_TYPE_CONTROL 0
56 #define PLAYOUT_TYPE_SILENCE 1
57 #define PLAYOUT_TYPE_SPEECH 2
58
59 typedef int timestamp_t;
60
61 typedef struct playout_frame_s
62 {
63 /*! The actual frame data */
64 void *data;
65 /*! The type of frame */
66 int type;
67 /*! The timestamp assigned by the sending end */
68 timestamp_t sender_stamp;
69 /*! The timespan covered by the data in this frame */
70 timestamp_t sender_len;
71 /*! The timestamp assigned by the receiving end */
72 timestamp_t receiver_stamp;
73 /*! Pointer to the next earlier frame */
74 struct playout_frame_s *earlier;
75 /*! Pointer to the next later frame */
76 struct playout_frame_s *later;
77 } playout_frame_t;
78
79 /*!
80 Playout (jitter buffer) descriptor. This defines the working state
81 for a single instance of playout buffering.
82 */
83 typedef struct
84 {
85 /*! TRUE if the buffer is dynamically sized */
86 int dynamic;
87 /*! The minimum length (dynamic) or fixed length (static) of the buffer */
88 int min_length;
89 /*! The maximum length (dynamic) or fixed length (static) of the buffer */
90 int max_length;
91 /*! The target filter threshold for adjusting dynamic buffering. */
92 int dropable_threshold;
93
94 int start;
95
96 /*! The queued frame list */
97 playout_frame_t *first_frame;
98 playout_frame_t *last_frame;
99 /*! The free frame pool */
100 playout_frame_t *free_frames;
101
102 /*! The total frames input to the buffer, to date. */
103 int frames_in;
104 /*! The total frames output from the buffer, to date. */
105 int frames_out;
106 /*! The number of frames received out of sequence. */
107 int frames_oos;
108 /*! The number of frames which were discarded, due to late arrival. */
109 int frames_late;
110 /*! The number of frames which were never received. */
111 int frames_missing;
112 /*! The number of frames trimmed from the stream, due to buffer shrinkage. */
113 int frames_trimmed;
114
115 timestamp_t latest_expected;
116 /*! The present jitter adjustment */
117 timestamp_t current;
118 /*! The sender_stamp of the last speech frame */
119 timestamp_t last_speech_sender_stamp;
120 /*! The duration of the last speech frame */
121 timestamp_t last_speech_sender_len;
122
123 int not_first;
124 /*! The time since the target buffer length was last changed. */
125 timestamp_t since_last_step;
126 /*! Filter state for tracking the packets arriving just in time */
127 int32_t state_just_in_time;
128 /*! Filter state for tracking the packets arriving late */
129 int32_t state_late;
130 /*! The current target length of the buffer */
131 int target_buffer_length;
132 /*! The current actual length of the buffer, which may lag behind the target value */
133 int actual_buffer_length;
134 } playout_state_t;
135
136 #if defined(__cplusplus)
137 extern "C"
138 {
139 #endif
140
141 /*! Queue a frame
142 \param s The play-out context.
143 \param data The frame data.
144 \param sender_len Length of frame (for voice) in timestamp units.
145 \param sender_stamp Sending end's time stamp.
146 \param receiver_stamp Local time at which packet was received, in timestamp units.
147 \return One of
148 PLAYOUT_OK: Frame queued OK.
149 PLAYOUT_ERROR: Some problem occured - e.g. out of memory. */
150 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);
151
152 /*! Get the next frame.
153 \param s The play-out context.
154 \param frame The frame.
155 \param sender_stamp The sender's timestamp.
156 \return One of
157 PLAYOUT_OK: Suitable frame found.
158 PLAYOUT_DROP: A frame which should be dropped was found (e.g. it arrived too late).
159 The caller should request the same time again when this occurs.
160 PLAYOUT_NOFRAME: There's no frame scheduled for this time.
161 PLAYOUT_FILLIN: Synthetic signal must be generated, as no real data is available for
162 this time (either we need to grow, or there was a lost frame).
163 PLAYOUT_EMPTY: The buffer is empty.
164 */
165 SPAN_DECLARE(int) playout_get(playout_state_t *s, playout_frame_t *frame, timestamp_t sender_stamp);
166
167 /*! Unconditionally get the first buffered frame. This may be used to clear out the queue, and free
168 all its contents, before the context is freed.
169 \param s The play-out context.
170 \return The frame, or NULL is the queue is empty. */
171 SPAN_DECLARE(playout_frame_t *) playout_get_unconditional(playout_state_t *s);
172
173 /*! Find the current length of the buffer.
174 \param s The play-out context.
175 \return The length of the buffer. */
176 SPAN_DECLARE(timestamp_t) playout_current_length(playout_state_t *s);
177
178 /*! Find the time at which the next queued frame is due to play.
179 Note: This value may change backwards as freshly received out of order frames are
180 added to the buffer.
181 \param s The play-out context.
182 \return The next timestamp. */
183 SPAN_DECLARE(timestamp_t) playout_next_due(playout_state_t *s);
184
185 /*! Reset an instance of play-out buffering.
186 NOTE: The buffer should be empty before you call this function, otherwise
187 you will leak queued frames, and some internal structures
188 \param s The play-out context.
189 \param min_length Minimum length of the buffer, in samples.
190 \param max_length Maximum length of the buffer, in samples. If this equals min_length, static
191 length buffering is used. */
192 SPAN_DECLARE(void) playout_restart(playout_state_t *s, int min_length, int max_length);
193
194 /*! Create a new instance of play-out buffering.
195 \param min_length Minimum length of the buffer, in samples.
196 \param max_length Maximum length of the buffer, in samples. If this equals min_length, static
197 length buffering is used.
198 \return The new context */
199 SPAN_DECLARE(playout_state_t *) playout_init(int min_length, int max_length);
200
201 /*! Release an instance of play-out buffering.
202 \param s The play-out context to be releaased
203 \return 0 if OK, else -1 */
204 SPAN_DECLARE(int) playout_release(playout_state_t *s);
205
206 /*! Free an instance of play-out buffering.
207 \param s The play-out context to be destroyed
208 \return 0 if OK, else -1 */
209 SPAN_DECLARE(int) playout_free(playout_state_t *s);
210
211 #if defined(__cplusplus)
212 }
213 #endif
214
215 #endif
216 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.