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);
}
|