[libdvbpsi-devel] examples/dvbinfo: limit fifo size
Jean-Paul Saman
git at videolan.org
Wed Jun 27 14:29:04 CEST 2012
libdvbpsi | branch: master | Jean-Paul Saman <jean-paul.saman at m2x.nl> | Wed Jun 20 16:37:36 2012 +0200| [41e5a3bd5e326ab1c147aa2f5db1fcaeeb6b3224] | committer: Jean-Paul Saman
examples/dvbinfo: limit fifo size
Implemented a function fifo_size() that returns the current size of the fifo.
The dvbinfo example program uses fifo_size() to detect if the total size of
buffers inside the fifo exceeds a certain threshold. The threshold is currently
defined at compile time.
> http://git.videolan.org/gitweb.cgi/libdvbpsi.git/?a=commit;h=41e5a3bd5e326ab1c147aa2f5db1fcaeeb6b3224
---
examples/dvbinfo/buffer.c | 12 ++++++++++++
examples/dvbinfo/buffer.h | 2 ++
examples/dvbinfo/dvbinfo.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
examples/dvbinfo/dvbinfo.h | 1 +
4 files changed, 60 insertions(+)
diff --git a/examples/dvbinfo/buffer.c b/examples/dvbinfo/buffer.c
index 6633938..f03a3bb 100644
--- a/examples/dvbinfo/buffer.c
+++ b/examples/dvbinfo/buffer.c
@@ -44,6 +44,7 @@ struct fifo_s
pthread_cond_t wait;
bool b_force_wake;
ssize_t i_count;
+ size_t i_size; /* fifo size in bytes */
buffer_t *p_first;
buffer_t **pp_last;
};
@@ -73,6 +74,7 @@ fifo_t *fifo_new(void)
if (fifo == NULL) return NULL;
fifo->i_count = 0;
+ fifo->i_size = 0;
fifo->b_force_wake = false;
fifo->p_first = NULL;
fifo->pp_last = &fifo->p_first;
@@ -129,6 +131,14 @@ ssize_t fifo_count(fifo_t *fifo)
return count;
}
+size_t fifo_size(fifo_t *fifo)
+{
+ pthread_mutex_lock(&fifo->lock);
+ size_t size = fifo->i_size;
+ pthread_mutex_unlock(&fifo->lock);
+ return size;
+}
+
void fifo_push(fifo_t *fifo, buffer_t *buffer)
{
buffer_t *p_last;
@@ -148,6 +158,7 @@ void fifo_push(fifo_t *fifo, buffer_t *buffer)
*fifo->pp_last = buffer;
fifo->pp_last = &p_last->p_next;
fifo->i_count += i_depth;
+ fifo->i_size += buffer->i_size;
assert(fifo->p_first != NULL);
assert(fifo->pp_last != NULL);
@@ -175,6 +186,7 @@ buffer_t *fifo_pop(fifo_t *fifo)
fifo->p_first = buffer->p_next;
fifo->i_count--;
+ fifo->i_size -= buffer->i_size;
if (fifo->p_first == NULL)
{
diff --git a/examples/dvbinfo/buffer.h b/examples/dvbinfo/buffer.h
index 0196510..151f93a 100644
--- a/examples/dvbinfo/buffer.h
+++ b/examples/dvbinfo/buffer.h
@@ -46,6 +46,7 @@ void buffer_free(buffer_t *buffer);
* fifo_new() - create a new fifo holding buffer_t pointers
* fifo_free() - release fifo and all buffers contained therein
* fifo_count()- number of buffers in fifo_t
+ * fifo_size() - total size of buffers in fifo_t
* fifo_push() - push buffer at end of fifo
* fifo_pop() - pop buffer from start of fifo
* fifo_wake() - wake up fifo listeners
@@ -53,6 +54,7 @@ void buffer_free(buffer_t *buffer);
fifo_t *fifo_new(void);
void fifo_free(fifo_t *fifo);
ssize_t fifo_count(fifo_t *fifo);
+size_t fifo_size(fifo_t *fifo);
void fifo_push(fifo_t *fifo, buffer_t *buffer);
buffer_t *fifo_pop(fifo_t *fifo);
void fifo_wake(fifo_t *fifo);
diff --git a/examples/dvbinfo/dvbinfo.c b/examples/dvbinfo/dvbinfo.c
index 774041a..a333d0b 100644
--- a/examples/dvbinfo/dvbinfo.c
+++ b/examples/dvbinfo/dvbinfo.c
@@ -64,6 +64,7 @@
# include "tcp.h"
#endif
+#define FIFO_THRESHOLD_SIZE (400 * 1024 * 1024) /* threshold in bytes */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
static const int i_summary_mode[] = { SUM_BANDWIDTH, SUM_TABLE, SUM_PACKET, SUM_WIRE };
@@ -77,6 +78,10 @@ typedef struct dvbinfo_capture_s
fifo_t *fifo;
fifo_t *empty;
+ pthread_mutex_t lock;
+ pthread_cond_t fifo_full;
+ bool b_fifo_full;
+
size_t size; /* prefered capture size */
params_t *params;
@@ -277,6 +282,30 @@ static void *dvbinfo_capture(void *data)
buffer->i_date = mdate();
+ /* check fifo size */
+ if (fifo_size(capture->fifo) >= FIFO_THRESHOLD_SIZE)
+ {
+ pthread_mutex_lock(&capture->lock);
+ capture->b_fifo_full = true;
+ pthread_mutex_unlock(&capture->lock);
+
+ if (param->b_file)
+ {
+ /* wait till buffer becomes smaller again */
+ pthread_mutex_lock(&capture->lock);
+ while(capture->b_fifo_full)
+ pthread_cond_wait(&capture->fifo_full, &capture->lock);
+ pthread_mutex_unlock(&capture->lock);
+ }
+ else
+ {
+ libdvbpsi_log(capture->params, DVBINFO_LOG_ERROR,
+ "error fifo full discarding buffer");
+ fifo_push(capture->empty, buffer);
+ continue;
+ }
+ }
+
/* store buffer */
fifo_push(capture->fifo, buffer);
buffer = NULL;
@@ -374,6 +403,15 @@ static int dvbinfo_process(dvbinfo_capture_t *capture)
/* reuse buffer */
fifo_push(capture->empty, buffer);
buffer = NULL;
+
+ /* check fifo size */
+ if (fifo_size(capture->fifo) < FIFO_THRESHOLD_SIZE)
+ {
+ pthread_mutex_lock(&capture->lock);
+ capture->b_fifo_full = false;
+ pthread_cond_signal(&capture->fifo_full);
+ pthread_mutex_unlock(&capture->lock);
+ }
}
libdvbpsi_exit(stream);
@@ -407,6 +445,9 @@ int main(int argc, char **pp_argv)
capture.params = param;
capture.fifo = fifo_new();
capture.empty = fifo_new();
+ capture.b_fifo_full = false;
+ pthread_mutex_init(&capture.lock, NULL);
+ pthread_cond_init(&capture.fifo_full, NULL);
static const struct option long_options[] =
{
@@ -461,6 +502,7 @@ int main(int argc, char **pp_argv)
}
/* */
param->pf_read = read;
+ param->b_file = true;
}
break;
@@ -647,6 +689,9 @@ int main(int argc, char **pp_argv)
fifo_free((&capture)->fifo);
fifo_free((&capture)->empty);
+ pthread_mutex_destroy(&capture.lock);
+ pthread_cond_destroy(&capture.fifo_full);
+
#ifdef HAVE_SYS_SOCKET_H
if (param->b_monitor)
closelog();
diff --git a/examples/dvbinfo/dvbinfo.h b/examples/dvbinfo/dvbinfo.h
index 9ce2815..9c7e472 100644
--- a/examples/dvbinfo/dvbinfo.h
+++ b/examples/dvbinfo/dvbinfo.h
@@ -40,6 +40,7 @@ typedef struct params_s
int port;
bool b_udp;
bool b_tcp;
+ bool b_file;
/* */
int fd_in;
More information about the libdvbpsi-devel
mailing list