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.
Andre Noll [Sun, 6 Sep 2009 20:19:31 +0000 (22:19 +0200)]
filter: Register the filter chain as the last task.
Without this patch, the command
para_filter -f mp3dec < foo.mp3 > /dev/null
would take several minutes because the stdin buffer is usually full and the stdout buffer empty
which causes select() to be called with empty fd sets, resulting in a one second timeout.
Andre Noll [Mon, 31 Aug 2009 19:17:21 +0000 (21:17 +0200)]
mp3dec: Improve bad main_data_begin pointer error handling.
These errors from mad_frame_decode() are non-fatal and happen if the
stream is started at the middle of the file, e.g. when para_audiod
is started while para_server is already streaming.
If libmad encounters such an error it throws away the first (and
probably the second) frame which messes up the timing in udp/fec mode,
causing an audible buffer underrun after the remaining frames of the
first fec group have been decoded and fed to the writer.
This patch makes the mp3dec filter keep track of bad main_data_begin
pointer errors that happen at the start of the stream. In this case
decoding is deferred until more data has arrived or 60ms have passed.
Andre Noll [Sat, 29 Aug 2009 20:17:55 +0000 (22:17 +0200)]
Alsa timing improvements.
This moves the computation of the select timeout from
alsa_write_post_select() to alsa_write_pre_select(). The code now
computes when the next buffer underrun would occur and uses that
value to set the timeout for the next select call. This decreases
the number of writes to the alsa handle and therefore also the CPU
usage of para_write/para_audiod.
Andre Noll [Tue, 21 Jul 2009 15:56:02 +0000 (17:56 +0200)]
Rename LIST_HEAD to INITIALIZED_LIST_HEAD.
This fixes the following warning on NetBSD:
In file included from udp_send.c:25:
list.h:37:1: warning: "LIST_HEAD" redefined
In file included from /usr/include/net/if.h:84,
from udp_send.c:14:
/usr/include/sys/queue.h:88:1: warning: this is the location of the previous definition
Andre Noll [Sun, 19 Jul 2009 15:56:22 +0000 (17:56 +0200)]
Micro optimizations for the amp filter.
Use memcpy in the special case amp==0 (no amplification) and optimize the code in
the performance-critical loop. Intrestingly, using the likely()/unlikely() macros made the
code slower.
Results (three runs on identical input data on a 32bit x86 machine under Linux, gcc-4.4.0):
old with --amp 3:
0m0.776s 0m0.790s 0m0.812s, avg: 792
new with --amp 3:
0m0.456s 0m0.492s 0m0.477s, avg: 475
speedup: 1.67
old with --amp 0:
0m0.791s 0m0.808s 0m0.810s, avg: 803
new with --amp 0:
0m0.100s 0m0.103s 0m0.094s, avg: 99
speedup: 8.1
Andre Noll [Sun, 19 Jul 2009 13:07:28 +0000 (15:07 +0200)]
Move functions only needed by audiod from stat.c to audiod_command.c.
This was 4 out of 5 and thus should decrease the size of executables for non-Linux
systems a bit as we don't use -fdata-sections -ffunction-sections and -Wl,--gc-sections
there.
Is also allows to remove some entries from para.h.
Andre Noll [Sun, 19 Jul 2009 01:10:34 +0000 (03:10 +0200)]
client_post_select(): Defer decrypting of server challenge.
The old code worked only by pure luck: We allocated the crypt buffer on the stack as
an ordinary automatic variable. This buffer was filled right after we received the challenge
from the server, but it was used in a _subsequent_ call to client_post_select(). There's
no guarantee that the content of the crypt buffer stays the same between these two calls.
So defer the decryption until the client status is CL_RECEIVED_CHALLENGE, i.e. until
the socket file descriptor is known to be ready for sending back the SHA1 of the decrypted
challenge.
Andre Noll [Sat, 11 Jul 2009 19:01:27 +0000 (21:01 +0200)]
Fix com_init() in case arguments are given.
As the ->name field of struct afs_table was only initialized in the afs process,
com_init(), which gets forked from the server process, did not see the table
names and would segfault due to a NULL pointer dereference if table names
were given as arguments.
Fix it by initializing the ->name fields in the definition of the afs_tables array.
This bug was introduced in commit 53d503ce back in 2007...
Andre Noll [Sat, 11 Jul 2009 15:13:04 +0000 (17:13 +0200)]
Scoring performance enhancements.
The old scoring code computed the afsi, afhi, and the path of the audio file for each
item of the mood, which is unnecessary. This patch moves these computations from
get_item_score() into compute_mood_score() so that afsi, afhi and path are only
computed once per audio file.
As a result, get_item_score() can no longer fail, so we may skip the checks for negative
return values.
Andre Noll [Sat, 11 Jul 2009 13:55:04 +0000 (15:55 +0200)]
Move mood methods to a separate file.
As more mood methods will be added in subsequent patches, it's good to separate
moods from mood methods.
This also removes the played_rarely mood method, since it never really worked: Whether
or not a file was played rarely depends on the afs statistics which have not been
computed at the time the mood scrore function is executed.
Andre Noll [Thu, 9 Jul 2009 18:11:55 +0000 (20:11 +0200)]
Add the new "year" mood method.
This includes a Y2K heuristic for year tags that contain only two digits. If that two-digit
number N is less or equal than the current year minus 2000, assume that it means 2000 + N.
Otherwise, assume 1900 + N.
Andre Noll [Wed, 8 Jul 2009 21:10:49 +0000 (23:10 +0200)]
Introduce para_regcomp.
A wrapper for regcomp() that logs an error message if the regcomp() failed
and uses a return value according to the paraslash rules. Currently there is
only one user of regular expressions, is_v4_dot_quad(), which is converted
to para_regex(), but new callers will be added soon.
Unfortunately, this change made it necessary to include regex.h in all .c files
that use string.h. Clean up the order in which headers are included a bit while
we're at it.
Maybe I should rethink the rule "Only .c files shall include header files"...