From b593c2c4170ba63f2ee21a7a8414081a45235cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sat, 28 Apr 2007 17:40:51 +0000 Subject: [PATCH] Bandwidth limit access filter --- configure.ac | 1 + modules/access_filter/Modules.am | 1 + modules/access_filter/bandwidth.c | 173 ++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 modules/access_filter/bandwidth.c diff --git a/configure.ac b/configure.ac index 73d5d38abb..8cc7a05df1 100644 --- a/configure.ac +++ b/configure.ac @@ -1175,6 +1175,7 @@ VLC_ADD_PLUGINS([i420_rgb rawvideo blend scale image logo magnify puzzle colorth VLC_ADD_PLUGINS([wav araw subtitle vobsub adpcm a52sys dtssys au ty voc xa nuv]) VLC_ADD_PLUGINS([access_directory access_file access_udp access_tcp]) VLC_ADD_PLUGINS([access_http access_mms access_ftp]) +VLC_ADD_PLUGINS([access_filter_bandwidth]) VLC_ADD_PLUGINS([packetizer_mpegvideo packetizer_h264]) VLC_ADD_PLUGINS([packetizer_mpeg4video packetizer_mpeg4audio]) VLC_ADD_PLUGINS([packetizer_vc1]) diff --git a/modules/access_filter/Modules.am b/modules/access_filter/Modules.am index 7bb91a2da6..5b2eaca07d 100644 --- a/modules/access_filter/Modules.am +++ b/modules/access_filter/Modules.am @@ -1,3 +1,4 @@ SOURCES_access_filter_timeshift = timeshift.c SOURCES_access_filter_record = record.c SOURCES_access_filter_dump = dump.c +SOURCES_access_filter_bandwidth = bandwidth.c diff --git a/modules/access_filter/bandwidth.c b/modules/access_filter/bandwidth.c new file mode 100644 index 0000000000..77f7e0cc31 --- /dev/null +++ b/modules/access_filter/bandwidth.c @@ -0,0 +1,173 @@ +/***************************************************************************** + * bandwidth.c + ***************************************************************************** + * Copyright © 2007 Rémi Denis-Courmont + * $Id: dump.c 19948 2007-04-26 19:53:53Z courmisch $ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#define BANDWIDTH_TEXT N_("Bandwidth limit (bytes/s)") +#define BANDWIDTH_LONGTEXT N_( \ + "The bandwidth module will drop any data in excess of that many bytes " \ + "per seconds." ) + +static int Open (vlc_object_t *); +static void Close (vlc_object_t *); + +/* TODO: burst support */ + +vlc_module_begin (); + set_shortname (_("Bandwidth")); + set_description (_("Bandwidth limiter")); + set_category (CAT_INPUT); + set_subcategory (SUBCAT_INPUT_ACCESS_FILTER); + set_capability ("access_filter", 0); + add_shortcut ("bandwidth"); + set_callbacks (Open, Close); + + add_integer ("access-bandwidth", 65536, NULL, BANDWIDTH_TEXT, + BANDWIDTH_LONGTEXT, VLC_FALSE); +vlc_module_end(); + +static int Read (access_t *access, uint8_t *buffer, int len); +static int Seek (access_t *access, int64_t offset); +static int Control (access_t *access, int cmd, va_list ap); + +struct access_sys_t +{ + mtime_t last_time; + size_t last_size; + size_t bandwidth; +}; + +/** + * Open() + */ +static int Open (vlc_object_t *obj) +{ + access_t *access = (access_t*)obj; + access_t *src = access->p_source; + + if (src->pf_read != NULL) + access->pf_read = Read; + else + { + msg_Err (obj, "block bandwidth limit not implemented"); + return VLC_EGENERIC; + } + + if (src->pf_seek != NULL) + access->pf_seek = Seek; + + access->pf_control = Control; + access->info = src->info; + + access_sys_t *p_sys = access->p_sys = malloc (sizeof (*p_sys)); + if (p_sys == NULL) + return VLC_ENOMEM; + + memset (p_sys, 0, sizeof (*p_sys)); + p_sys->bandwidth = var_CreateGetInteger (access, "access-bandwidth"); + p_sys->last_time = mdate (); + + msg_Dbg (obj, "bandwidth limit: %u bytes/s", p_sys->bandwidth); + return VLC_SUCCESS; +} + + +/** + * Close() + */ +static void Close (vlc_object_t *obj) +{ + access_t *access = (access_t *)obj; + access_sys_t *p_sys = access->p_sys; + free (p_sys); +} + + +static int Read (access_t *access, uint8_t *buffer, int len) +{ + access_t *src = access->p_source; + access_sys_t *p_sys = access->p_sys; + mtime_t now; + + if (len == 0) + return 0; + +retry: + now = mdate (); + if (now <= p_sys->last_time) + { + msg_Err (access, "*** ALERT *** System clock is going backward! ***"); + return 0; /* Uho, your clock is broken. */ + } + + mtime_t delta = now - p_sys->last_time; + p_sys->last_time = now; + + delta *= p_sys->bandwidth; + delta /= 1000000u; + + if (delta == 0) + { + now += 1000000u / p_sys->bandwidth; + mwait (now); + goto retry; + } + + if (len > delta) + { + msg_Dbg (access, "reading %u bytes instead of %u", (unsigned)delta, + len); + len = (int)delta; + } + + + src->info.i_update = access->info.i_update; + len = src->pf_read (src, buffer, len); + access->info = src->info; + + msg_Dbg (access, "read %u bytes", len); + return len; +} + + +static int Control (access_t *access, int cmd, va_list ap) +{ + access_t *src = access->p_source; + return src->pf_control (src, cmd, ap); +} + + +static int Seek (access_t *access, int64_t offset) +{ + access_t *src = access->p_source; + + src->info.i_update = access->info.i_update; + int ret = src->pf_seek (src, offset); + access->info = src->info; + return ret; +} -- GitLab