Andre Noll [Wed, 18 Nov 2009 18:23:45 +0000 (19:23 +0100)]
fecdec: Defer decoding until the next group after the first _usable_ fec group starts.
Commit faeabd31b4bea5c097acff4738a0626e3c84f1d9 (fecdec: Defer decoding until
the first slice of the second group arrives.) changed the fec decoder such that it does
not start to write the decoded output ASAP but waits until the next group starts.
This is generally a good idea, but the patch missed the fact that the first complete group
might be unusable in case of streams that carry an audio file header (currently only ogg
vorbis).
Fix this flaw by setting the completion status to GCS_FIRST_GROUP_COMPLETE only
if we received a complete group that is also usable.
Andre Noll [Thu, 12 Nov 2009 23:39:22 +0000 (00:39 +0100)]
http/dccp: Do not send the audio file header twice.
If the http/dccp client connects before stream start and the stream
starts at the beginning of the audio file (the common case), we do not
need to send the audio file header as it is contained in chunk zero.
However, the current code fails to set sender_client->sent_header to
a non-zero value in this case. This causes the header to be sent twice.
The ogg vorbis decoder is quite forgiving in that respect, which is
probably why this bug went unnoticed for so long. This patch gets
it right.
Andre Noll [Fri, 6 Nov 2009 14:07:18 +0000 (15:07 +0100)]
Replace assertion for invalid audio formats by a runtime check.
In case one switches back and forth between different versions of
para_server that support different audio formats, it may happen
that the aft table contains entries for audio formats that are not
supported by the version currently running.
ATM, this causes para_server to die immediately because of the
assertion in audio_format_name. Replace the assertion by a less
draconian run time check that returns the string "???" if the number
for an unknown audio file format is being looked up.
Andre Noll [Thu, 5 Nov 2009 23:21:16 +0000 (00:21 +0100)]
server: Fix assignment of afs_pid.
glibc-2.11 revealed the following bug in init_afs(): The assignment
mmd->afs_pid = fork();
results in undefined behaviour because fork() returns twice and mmd->afs_pid lives
in a shared memory area. Depending on whether the child runs first, this results in
mmd->afs_pid being either zero or the pid of the afs child process.
mmd->afs_pid being zero seems to happen always with glibc-2.11 and has rather
strange consequences:
First, it causes para_server attempt to kill process 0 instead of the afs process on
exit. This fails because para_server never runs as root. However, it may result in dirty
osl tables as the afs process might access mmd after the shared memory area containing
mmd has already been destroyed.
Second, para_server fails to notice the death of the afs process, which is really bad and
may cause tons of error messages being written to the log.
Fix this bug by temporarily storing the afs pid in a local variable and setting mmd->afs_pid
only in the server (parent) process.
Andre Noll [Thu, 5 Nov 2009 21:42:52 +0000 (22:42 +0100)]
wng: Avoid buffer underruns due to filter chain output buffer constraints.
Using ogg vorbis streams together with the oss writer hits the following nasty bug:
In case the filter chain can provide more data than what fits into its output buffer,
it converts the maximal amount possible to completely fill its output buffer. However, the
time to play this data might be less than than the time until the next data packet arrives
from the upper layers, especially when using ogg vorbis streams and FEC.
Since the filter chain task has no pre_select function, the convert function(s) of its filter
nodes only get the chance to convert more data until the next select call returns, which
might already be too late.
This patch fixes the bug by teaching the pre_select function of the writer node group
to remember whether something was written during the previous call to wng_post_select().
In this case we force a minimal timeout for select, i.e. the next call to select() will return
immediately and the convert functions of the filter node are called again, hopefully converting
more data for the writer node group.
Andre Noll [Sat, 24 Oct 2009 19:03:06 +0000 (21:03 +0200)]
vss: Fix computation of extra slices.
On stream start we check in setup_next_fec_group() whether the FEC
parameters requested by the client are sufficient for the current audio
file. We want each FEC group contain at least one non-header slice.
Since header slices can not contain any non-header data, the number
of required slices is given by the number of slices needed for the
header plus the number of slices needed for the largest chunk of the
audio file.
The current code gets this wrong because it computes the number of
slices needed for the header plus the largest chunk, which may be
strictly less than what is actually needed. IOW, the inequality
This bug could trigger the assertion assert(g->num_chunks) further
down in setup_next_fec_group().
This patch fixes this bug and also changes a log message in
udp_init_session() which always printed the requested FEC parameters,
not considering extra slices.
Andre Noll [Thu, 22 Oct 2009 20:47:19 +0000 (22:47 +0200)]
daemon: Avoid using MAXLINE.
MAXLINE is kind of depricated. Just use a 100 byte buffer and make the scope of the
buffer more local. Also, kill the pointless initialization to an empty string.
Andre Noll [Thu, 22 Oct 2009 20:42:36 +0000 (22:42 +0200)]
drop_privileges_or_die(): Check return value of setuid().
The call to setuid() may fail, e.g. because it brings the process over its RLIMIT_NPROC
resource limit. So print an error message and exit in this case.
Andre Noll [Thu, 22 Oct 2009 17:21:10 +0000 (19:21 +0200)]
fecdec: Fix decoding of the audio file header.
The handling of the audio file header in the fecdec code is currently
broken: We output all decoded header slices although the last slice
might only be partially used.
This patch introduces the new fec_group_usability value
"FEC_GROUP_USABLE_WITH_HEADER" which gets used when streaming starts in
the middle of the file. In this case, after the group has been decoded,
we make sure that only h.audio_header_size many bytes are being written
to the output buffer. We then proceed to write the output corresponding
to the data slices as in the FEC_GROUP_USABLE_SKIP_HEADER case.
In paraslash-0.3. only ogg vorbis uses audio file headers, and the
ogg code is quite forgiving and successfully resyncs the stream,
which is why this bug was never noticed. However, the wma decoder of
paraslash-0.4 fails badly due to the garbage that is written after
the header.
Andre Noll [Sun, 4 Oct 2009 13:57:33 +0000 (15:57 +0200)]
Put the git version into all executables.
This patch changes the -V output of all executables to print also
the git version which was used to make the executable. The idea and
the GIT-VERSION_GEN script was taken from git.git.
It also adds a VERSION file to the generated tarball. If this file
exists, its content is used as the version info rather than calling
git to obtain this info. This way, even if paraslash is built from
a tarball, the executables still contain the git version the tarball
was generated from.
Andre Noll [Thu, 1 Oct 2009 00:07:16 +0000 (02:07 +0200)]
Introduce clean2 target.
This makes the clean target remove objects and binaries only. The new
clean2 target removes in addition the man dir and the object dir
(hence all .d files) completely.
Andre Noll [Sat, 19 Sep 2009 08:38:25 +0000 (10:38 +0200)]
oggdec filter improvements.
Try to open the ogg vorbis callbacks as soon as possible rather
than waiting until the input buffer reaches the given initial buffer
size. If that fails, try again later when more data is available but
fail if the input buffer size is larger than the initial buffer size
and we can still not open the ov callbacks.
Also, if a hole was detected, likely because we started streaming
in the middle of the file, add an additional delay to avoid buffer
underruns.
Andre Noll [Sat, 19 Sep 2009 08:26:04 +0000 (10:26 +0200)]
Complete re-write of the ogg vorbis audio format handler.
The new code is quite a bit smaller, performes much better and chooses
a chunk time dependent on the average ogg page size rather than using
a hardcoded chunk time of 250ms.
Andre Noll [Sat, 19 Sep 2009 08:21:48 +0000 (10:21 +0200)]
fecdec: Defer decoding until the first slice of the second group arrives.
Otherwise, this could lead to buffer underruns in the decoding application
in case slices are missed. So introdce group_completion_status which tracks
whether we already have received the first group sucessfully and are waiting
for the first slice of the next group.
Andre Noll [Sat, 12 Sep 2009 16:16:56 +0000 (18:16 +0200)]
FEC timing improvements.
Currently we compute the time of a FEC group as the number of
containing chunks times the chunk time. The time between sending
two slices therefore depends only on the number of chunks the group
contains. Groups containing many slices are sent with larger delays
than groups containing few slices.
This approach is not optimal for the following reason: Consider a group
containing only few slices which is followed by a group containing
many slices. This happens frequently at the end of VBR MP3 files which
contain some seconds of silence or applause at the end because this
last part is often encoded at a lower bitrate than the preceding part.
In this scenario buffer underruns in the receiving application can
easily occur if the previous FEC group has been decoded and completely
fed to the writer before enough slices of the next group have arrived
to decode the second group.
This patch changes the timing of FEC groups such that all but the
first group use the duration of the _previous_ group as the basis
for the timing.
Andre Noll [Sat, 12 Sep 2009 16:13:36 +0000 (18:13 +0200)]
vss_send(): Fix EOF-check for FEC clients.
If the last chunk has been sent to all http/dccp clients we have
to wait until the last FEC group has been sent before setting the
NEXT flag that causes all senders to shut down its clients. The old
code tested if a slice was sent to any FEC client during vss_send()
and set the NEXT flag if nothing was sent.
However, this is not sufficient as there may be still slices available
which have to be sent at some future time. This patch teaches
vss_send() to detect this condition. It also renames the boolean
variable sent_something to fec_active, which is more to the point.