afh: Limit chunk numbers to 32 bit. The number of chunks and the chunk offsets are stored in the audio file table as 32 bit unsigned integers. Thus, chunk numbers and sizes cannot exceed 2^32 - 1. Make this fact obvious by changing the corresponding parameters of aac_afh_get_chunk() from size_t or unsigned long to uint32_t.
afh: Constify definition of audio format handlers. The audio_format_handler structure contains only pointers, and the ->init method of each instance initializes these pointers to constant values. The ->init() method is thus useless at best, and it prevents the structures from being declared constant. This patch removes ->init() of struct audio_format_handler and the public afh_init() which iterates over all audio formats to call each ->init() method. The audio format handlers are modified to define an instance of the structure rather than an init function which fills the fields of the given structure. The structure can be declared constant, but not static because afh_common.c needs a way to refer to it. We rely on weak symbols to deal with audio format handlers which are not compiled in. The codec-independent code in afh_common.c defines a weak instance of the audio_format_handler structure for each audio format. The command handlers which are compiled in override the weak symbol with their own definition. The afh receiver used to define afh_init() as its (receiver!) init function, which no longer exists. Since receiver init functions are optional, we don't need to supply a replacement. However, play.c calls ->init() of the afh_receiver unconditionally. This call needs to be removed to avoid a null pointer dereference.
afh: Introduce audio_format_names[]. This removes .name of struct audio_format in favor of an array of strings. This will allow us to make afl[] a constant array of pointers, some of which may be NULL to indicate that the audio format was not compiled in. This temporarily duplicates the list of audio formats. The second list will be removed in a subsequent commit.
afh: Get rid of dummy entry at the end of afl[]. The number of audio formats is a compile-time constant. It used to be the array size of afl[] minus one due to the dummy entry. Without it, it becomes simply the array size. This patch introduces NUM_AUDIO_FORMATS as a shortcut for ARRAY_SIZE(afl) and adjusts next_audio_format() to avoid the access of memory past the end of the array. With these preparations in place, the dummy entry can be removed.
afh: Minor simplification for afh_get_chunk(). The function already defines a shortcut for the pointer to the audio format handler, so use it.
afh: Move audio_format_name() up. So that all its callers are further down. Not really necessary because the function is non-static and declared in afh.h. But still..
Shorten copyright notice. The GPLv2 line does not add any additional information, so drop it. This leaves a single line of legalese text for most files, which is about the amount of screen real estate it deserves. This patch was created with the following script (plus some manual fixups): awk '{ if (NR <= 5) { gs = gensub(/.*Copyright.* ([0-9]+).*Andre Noll.*/, "\\1", "g") if (gs != $0) year = gs next } if (NR == 6 && year != "") printf("/* Copyright (C) %s Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */\n", year) print }'
Merge branch 'refs/heads/t/si_conversion' A single patch which moves the list of status items from configure.ac to para.h. Cooking for five weeks. * refs/heads/t/si_conversion: Define status items in para.h.
Merge branch 'refs/heads/t/doxygen' This series contains an update of Doxyfile to a newer doxygen version and an overhaul of the source code documentation. Several stale references have been fixed. Other parts of the documentation have been improved. Cooking for almost a month. * refs/heads/t/doxygen: aft.c: Trivial spelling/whitespace fixes. afh: Expand documentation of init function declarations. filter: Remove duplicate documentation of filter_get(). doxygen: Improve documentation of struct receiver. doxygen: Add \ref to references. Improve documentation of mm.c and mm.h. doxygen: Don't refer to Black Hats Manual. doxygen: Don't refer to libosl functions. doxygen: Trivial cleanups. doxygen: Remove some stale doxygen references. recv: Explain user data mechanism. Update to doxygen-1.8.11. The merge resulted in a few conflicts which were easy to resolve.
Define status items in para.h. The only reason the status item enum and string array are defined in configure.ac is that upper case identifiers and lower case strings are not easy to do in cpp as it lacks toupper(). However, configure.ac is not the right place for defining C language constructs as the configure script should only check for installed packages. This commit moves the definition of the status item enum and array to para.h and modifies all users to use lower case for the item names. This was automated with a script which essentially did upper=${i^^} sed -i "s/\<SI_$upper/SI_$i/g" $files for each status item $i. Care has been taken to leave the order of the status items unchanged. This is important because the item numbers must be considered part of the API between server and client.
afh: Unify name of init functions. The init functions of the mp3 and ogg audio format handlers lacked the _afh part in the name which all other audio format handlers have.
afh: Fix typo in comment.
afh: Expand documentation of init function declarations. It's not obvious why all of these are declared here, so explain this in a bit more detail.
Convert the aac audio format handler to libmp4ff. This changes the aac audio format handler to call the primitives provided by the mp4ff library. This allows to remove the atom parsing code from aac_afh.c. After this change para_server, para_afh, and para_recv no longer depend on aac_common.c and on the mp4v2 library. The autoconf tests for libmp4v2 are removed from configure.ac. A subsequent commit will deal with aac_common.c.
aac_afh: Don't create chunk tables any more. A previous commit activated dynamic chunks for the aac audio format handler, so the virtual streaming system no longer consults the chunk table stored in the audio file table of the osl database. However, the code to open or add an audio file still assumes that there is a chunk table and bails out if it can't find it. This patch changes aft.c to do without a chunk table if the audio format handler supports dynamic chunks. The afh_supports_dynamic_chunks() helper needs to be made public because of this. With chunk tables being optional, the ->get_file_info method of the audio format handler can safely set ->chunk_table to NULL. It still needs to compute the maximum chunk size though.
afh: Dynamic chunks. paraslash chunk tables were designed long ago with the idea that the full audio file, with the exception of a potential header, is going to be sent to the client. This allows to store a sequence of offsets as the chunk table. Each chunk is defined as the contiguous region of the file given by two consecutive offsets. For most audio formats, however, not every part of the file corresponds to encoded audio. We work around this on the client side by letting the filters detect and skip those parts which can not be fed to the decoder. This works generally well, but for the aac decoder we have a rather ugly hack that skips over any non aac decoded data of its input. This hack was never very reliable, and the concept of dynamic chunks finally allows to get rid of it. Dynamic chunks work as follows. Each audio format handler signifies support by defining the new ->get_chunk method. In this case afh_get_chunk() no longer consults the chunk table at all but calls the new method instead in order to obtain a reference to the chunk. This comes with a certain overhead at runtime because we need to call into the functions of the mp4ff library (ships together with faad) rather looking up the offset in the chunk table. Only the aac audio format handler supports dynamic chunks per this commit. To keep the patch size relatively small, this commit does not touch ->get_file_info() of the aac audio format handler. Therefore, when a new m4a file is added to the database, the aac audio format handler still creates the chunk table. A subsequent commit will turn off this unnecessary operation. The documentation is updated to mention that mp4ff is now required for the aac audio format handler. The configure script now checks for the mp4ff header and the library and deactivates aac support if it was not found.
server: Store max chunk size in database. This number is needed up-front for the initialization of the fec data structures. Currently we recompute it from the chunk table each time the file is opened for streaming. We can only get rid of the chunk table concept if we tell the VSS by other means how to obtain this information. Fortunately there is an unused 4-byte field in the on-disk afhi structure, which is always zero at the moment. This patch starts to use this field to store the maximal chunk size. For backwards compatibility, when the afhi structure is loaded from disk at stream time, we check if the field is zero and recompute the max chunk size as before in this case. Although the maximal chunk size is generally only needed on the server side, for consistence we expose it though a new status item along with chunk_tv and friends.
afh: Make sure we never return a negative chunk number. With the old code this could happen if chunk zero is empty.
afh: Improve error diagnostics. If compute_afhi() can not figure out the type of an audio file, it prints a rather incomprehensive error message for each audiod format which was tried to no avail. This commit improves the readability of these error messages by including the path and the name of the audio format that caused the error. Before: $ para_afh /etc/resolv.conf mp3_read_info: could not read mp3 info compute_afhi: could not read mp3 info compute_afhi: ogg sync page-out error (no ogg file?) compute_afhi: mp4v2 library error compute_afhi: asf/wma format not recognized compute_afhi: ogg sync page-out error (no ogg file?) compute_afhi: could not read meta chain compute_afhi: ogg sync page-out error (no ogg file?) main: audio format not recognized After: $ para_afh /etc/resolv.conf get_file_info: /etc/resolv.conf: mp3 format not detected: could not read mp3 info get_file_info: /etc/resolv.conf: ogg format not detected: ogg sync page-out error (no ogg file?) get_file_info: /etc/resolv.conf: aac format not detected: did not find esds atom get_file_info: /etc/resolv.conf: wma format not detected: asf/wma format not recognized get_file_info: /etc/resolv.conf: spx format not detected: ogg sync page-out error (no ogg file?) get_file_info: /etc/resolv.conf: flac format not detected: could not read meta chain get_file_info: /etc/resolv.conf: opus format not detected: ogg sync page-out error (no ogg file?) main: audio format not recognized The patch also removes a call to PARA_ERROR_LOG() in the mp3 audio format handler which is unnecessary because we return the error code and print the message in the caller anyway. A new helper, get_file_info(), is introduced to print the diagnostic messages. Since audio_format_name() is called from this helper, that function needed to be moved up to avoid a forward declaration.
afh: Make ->chunks_total and ->seconds_total fixed-size. These members of struct afh_info are stored as 4-byte quantities in the serialized afhi blob created by save_afhi(), so the structure should declare them as uint32_t rather than unsigned long. Fortunately, this bug is benign since save_afhi() uses the write_u32() helper from portable_io.h which does the right thing, regardless of the type of the variable passed.