File: pktbuf.c

package info (click to toggle)
rat 4.2.22-2.2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,896 kB
  • ctags: 3,717
  • sloc: ansic: 36,542; tcl: 2,740; sh: 2,675; makefile: 295
file content (136 lines) | stat: -rw-r--r-- 2,766 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * FILE:      pktbuf.c
 * AUTHOR(S): Orion Hodson 
 *
 * Copyright (c) 1999-2001 University College London
 * All rights reserved.
 */
 
#ifndef HIDE_SOURCE_STRINGS
static const char cvsid[] = 
	"$Id: pktbuf.c,v 1.13 2001/03/28 23:31:48 ucacoxh Exp $";
#endif /* HIDE_SOURCE_STRINGS */

#include "config_unix.h"
#include "config_win32.h"
#include "debug.h"
#include "memory.h"
#include "rtp.h"

#include "playout.h"
#include "ts.h"

#include "pktbuf.h"

static void pktbuf_free_rtp(u_char **mem, uint32_t memsz);

struct s_pktbuf {
	struct s_pb		*rtp_buffer;
	struct s_pb_iterator	*rtp_iterator;
	ts_sequencer		rtp_sequencer;
        uint16_t		max_packets;
	
};

int
pktbuf_create(struct s_pktbuf **ppb, uint16_t size)
{
        struct s_pktbuf *pb;
        
        pb = (struct s_pktbuf*)xmalloc(sizeof(struct s_pktbuf));
        if (pb == NULL) {
                return FALSE;
        }

	if (pb_create(&pb->rtp_buffer, pktbuf_free_rtp) == FALSE) {
		xfree(pb);
		return FALSE;
	}

	if (pb_iterator_create(pb->rtp_buffer, &pb->rtp_iterator) == FALSE) {
		pb_destroy(&pb->rtp_buffer);
		xfree(pb);
		return FALSE;
	}

	pb->max_packets = size;
        *ppb = pb;
        return TRUE;
}

void
pktbuf_destroy(struct s_pktbuf **ppb)
{
        struct s_pktbuf *pb = *ppb;
	pb_iterator_destroy(pb->rtp_buffer, &pb->rtp_iterator);
	pb_destroy(&pb->rtp_buffer);
        xfree(pb);
        *ppb = NULL;
}

static void 
pktbuf_free_rtp(u_char **data, uint32_t data_bytes) {
	assert(data_bytes == sizeof(rtp_packet));
	xfree(*data);
	*data = NULL;
}

int 
pktbuf_enqueue(struct s_pktbuf *pb, rtp_packet *p)
{
	timestamp_t	playout;
	uint32_t	psize;

        assert(p != NULL);
	playout = ts_seq32_in(&pb->rtp_sequencer, 8000 /* Arbitrary */, p->ts);
	psize   = sizeof(rtp_packet);
	pb_add(pb->rtp_buffer, (u_char*)p, psize, playout);

	if (pb_node_count(pb->rtp_buffer) > pb->max_packets) {
		debug_msg("RTP packet queue overflow\n");
		if (pktbuf_dequeue(pb, &p)) {
			pktbuf_free_rtp((u_char**)&p, psize);
			return TRUE;
		}
		/* NOTREACHED */
		debug_msg("Failed to detach overflow packet\n");
		abort();
	}

        return TRUE;
}

int 
pktbuf_dequeue(struct s_pktbuf *pb, rtp_packet **pp)
{
	timestamp_t	playout;
	uint32_t	psize;

	if (pb_iterator_rwd(pb->rtp_iterator) == FALSE) {
		return FALSE;
	}

	pb_iterator_detach_at(pb->rtp_iterator, (u_char**)pp, &psize, &playout);
	return TRUE;
}

int
pktbuf_peak_last(pktbuf_t   *pb,
                 rtp_packet **pp)
{
	timestamp_t	playout;
	uint32_t	psize;

	if (pb_iterator_ffwd(pb->rtp_iterator) == FALSE) {
		return FALSE;
	}
	pb_iterator_get_at(pb->rtp_iterator, (u_char**)pp, &psize, &playout);
	return TRUE;
}

uint16_t 
pktbuf_get_count(pktbuf_t *pb)
{
        return (uint16_t)pb_node_count(pb->rtp_buffer);
}