examples/dvbinfo: limit fifo size
[email protected] (Jean-Paul Saman)
| Newsgroups | gmane.comp.video.videolan.libdvbpsi.devel |
|---|---|
| Message-ID | <[email protected]> |
libdvbpsi | branch: master | Jean-Paul Saman <[email protected]> | 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; _______________________________________________ libdvbpsi-devel mailing list [email protected] http://mailman.videolan.org/listinfo/libdvbpsi-devel