summaryrefslogtreecommitdiff
path: root/mp4.h (follow)
Commit message (Collapse)AuthorAge
* Compile with -Wsuggest-attribute=malloc.Andre Noll2023-12-24
| | | | | | | | | | | | We already employ this attribute extensively to help the compiler improve optimization. However, a few malloc-like functions were not yet marked with __malloc. Fix that and enable the warning to make sure that new malloc-like functions get marked. Since not all supported compilers know about this warning option, we need to check at compile time whether the option is supported. Thanks to the existing cc-option make(1) function, this is a simple one-liner for Makefile.real.
* mp4: Doxify the public API.Andre Noll2022-06-27
| | | | | This adds doxygen comments to all public functions of the mp4 API and to the macros and enumerations of mp4.c.
* mp4: Rename mp4_open_read() to mp4_open().Andre Noll2022-06-27
| | | | | | | The function may be called with the intention to update the meta tags later by calling mp4_update_meta(), albeit mp4_open_meta() is cheaper if the caller only wants to modify the metadata. The old name is thus slightly misleading, and it's longer.
* mp4: Rename mp4_meta_update() to mp4_update_meta().Andre Noll2022-06-27
| | | | Just to be consistent with mp4_open_meta() and friends.
* mp4: Assorted trivial cleanups.Andre Noll2022-06-27
| | | | | | Avoid C++ comments, use int rather than int32_t as the standard return type, kill a pointless cast and use plain unsigned rather than uint32_t for the number of tag items.
* mp4: Remove ->len member of struct mp4_tag.Andre Noll2022-06-27
| | | | It is set but never read.
* mp4: Return proper types for sample rate and count.Andre Noll2022-06-27
| | | | | | The sample rate and the number of samples are stored as 16-bit/32-bit unsigned integers in the mp4 file, so let mp4_get_sample_rate() and mp4_num_samples() return these types.
* mp4: Remove E_MP4_BAD_CHANNEL_COUNT.Andre Noll2022-06-06
| | | | | | | | | | | If the mp4 file does not contain an m4a atom, the channel count stays at zero and open_file() returns -E_MP4_TRACK in this case. So the check in aac_afh.c for a non-positive return value from mp4_get_channel_count() can never trigger. Replace the check by an assertion and remove the error code. Also, let mp4_get_channel_count() return uint16_t as the number of channels is stored as an unsigned 16 bit number in the mp4 file.
* mp4: Improve mp4_get_sample_size().Andre Noll2022-06-06
| | | | | | Use an unsigned type for the sample number and check that the passed number is within range. Since the function can fail now, let it return int and return the sample size via an additional pointer argument.
* mp4: Make sample number be an unsigned parameter.Andre Noll2022-06-06
| | | | | | There is no reason to convert the 32-bit unsigned paraslash chunk number into a signed quantity here, as sample numbers are also stored as 32 bit unsigned in the mp4 file.
* mp4: Check the return value of ->truncate().Andre Noll2022-06-06
| | | | | | | This callback is implemented as a simple wrapper for the ftruncate() system call, which can fail for a number of reasons. Currently the callback returns unsigned and the return value is ignored. Fortunately, this is easy to fix.
* mp4: Replace the five tag value functions by a single one.Andre Noll2022-06-06
| | | | | | | | | | It's easier to let the caller pass the tag item string than to have one caller for each of the five tags of interest. This commit renames meta_find_by_name() to mp4_get_tag_value(), makes it public and removes its five callers from mp4.c. The only user is _aac_afh_get_taginfo() of aac_afh.c, which needs to be adjusted accordingly. Kill the pointless underscore while at it.
* mp4: Provide whence parameter for the seek callback.Andre Noll2022-05-30
| | | | | | | | | | | | | | | | | | This adds a parameter to make ->seek() work like the lseek(2) system call. This is easy to implement in both the memory-mapped callback case used to retrieve the file information and the metadata update case where ->seek() is a trivial wrapper for lseek(2). With the additional functionality in place we don't need to track the file size and the current file offset any more in mp4.c as these values can now be obtained by calling ->seek() with a zero offset and whence set to SEEK_END and SEEK_CUR, respectively. This also makes the code more robust against corrupt mp4 files because we no longer rely on the values from the atom headers to compute the file size. The way mp4.c calls ->seek() should never cause the underlying lseek(2) system call to fail. Therefore it suffices to check the return value only in the callback wrapper and abort on failure.
* mp4: Implement error checking for the write path.Andre Noll2022-05-30
| | | | | | | | | | | Although the ->write callback has a return value, it is of unsigned type and is never checked. Fix this by changing the prototype to match that of the write(2) system call, check the return value of the callback in the write_data() wrapper of mp4.c and propagate paraslash error codes back to aac_afh.c via the public mp4_meta_update(). While at it, handle short writes and EINTR properly, and fix the indentation of the callback structure in mp4.h.
* mp4: Eliminate duplication between the two open functions.Andre Noll2022-05-30
| | | | | | | | | | | | The only difference between mp4_open_read() and mp4_open_meta() is that they pass different values for the meta_only flag to parse_root_atoms(). We can avoid some duplication by moving the common code to parse_root_atoms(). Rename that function to open_file() because it now does more than just parsing atoms. The patch also changes the prototype of both public open functions to return an integer error code in addition to the pointer to an mp4 structure. This allows us to gradually improve the error diagnostics.
* mp4: Hide tracks array.Andre Noll2022-05-30
| | | | | | | | | | | | | All functions of mp4.c operate on the first audio track. This patch makes this fact implicit which allows us to remove the public mp4_get_total_tracks() and mp4_is_audio_track(). Moreover, the track parameter can be removed from all public functions. If no audio track was found in the mp4 file, we now return an error from two public open functions of mp4.c. Otherwise, we maintain a pointer to the first audio track within the mp4 structure and use that to identify the track rather than letting the API users pass the track number.
* mp4: Provide return value for mp4_set_sample_position().Andre Noll2022-05-30
| | | | | | This function fails if the given parameters are invalid. Detect this and return EINVAL in this case. Add corresponding error checking to the aac audio format handler.
* mp4: Rename mp4_total_tracks() to mp4_get_total_tracks().Andre Noll2022-05-30
| | | | | Just to be consistent with other public functions whose name contain a predicate. Move the function down to related functions.
* mp4: Improve handling of read errors.Andre Noll2022-05-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently read_data() of mp4.c is an atrocious mess. The ->read() callback is defined to return uint32_t, but the return value is stored in a signed 32 bit integer. Moreover, read_data() contains a dead store, it handles neither short nor interrupted reads correctly, and it moves the file position backwards on errors. While this is easy to fix, a more intricate problem is that most callers of read_data(), including all read_intX() helpers, ignore the return value of read_data() and return uninitialized stack contents in the error case. This is kind of dealt with by the ->read_error member of struct mp4, but this not more than a kludge, which, according to the comments, was applied after several CVEs had been filed against the library. Let's DTRT here, even though it adds a fair amount of new code: Check the return value of each read operation and fail early on errors. We have to distinguish three cases: error, EOF, and success, encoded as return values -1, 0 and 1, respectively. This commit converts most functions which read from an mp4 file to this convention. More work is required as return values are not checked everywhere yet. This was left for subsequent commits to keep the already large patch within reasonable size. Since we don't rely on ->read_error of struct mp4 any more, it can be removed.
* mp4: Drop metadata parameter from mp4_meta_update().Andre Noll2022-05-30
| | | | | | The function can as well access the modified metadata structure via the mp4 pointer. Drop the parameter also from modify_moov() for the same reason.
* mp4: Introduce mp4_get_meta().Andre Noll2022-05-30
| | | | | Simplify the API by returning a pointer to the metadata structure stored inside struct mp4. This is easier than having two accessor functions.
* mp4: Simplify and speed up metadata editing.Andre Noll2022-05-30
| | | | | | | | | | | | Currently the aac audio format handler first calls mp4_open_meta() to get the metadata tags, then alters the in-memory structure of the tags according to the command line options and passes this modified structure to mp4_meta_update() to rewrite the tags. This latter call parses the tags again, which is unnecessary overhead. This patch changes the signature of mp4_meta_update() to accept an mp4 structure instead of a callback structure and uses that instead of re-opening the file.
* mp4: Simplify and doxify meta tag accessors.Andre Noll2022-05-30
| | | | | | The integer return value is redundant, so get rid of the value parameter and simplify meta_find_by_name() accordingly. Document that tag values are allocated on the heap and should be freed by the caller.
* mp4: Mark callback function pointers as const.Andre Noll2022-05-30
| | | | | The code in mp4.c never modifies any of the members of the callback structure.
* mp4: Use uniform names for callback and mp4 structures.Andre Noll2022-05-30
| | | | | | | Currently it's a confusing mess, with callbacks called f, ff, or stream, where the former two are also used for pointers to struct mp4. Let's call a spade a spade and use cb everywhere for the callbacks while f is reserved to denote an mp4 pointer.
* mp4: Hide ->read_error.Andre Noll2022-05-30
| | | | | | This does not belong into the callback structure whose fields are supposed to get initialized by the audio format handler. Move it to the internal struct mp4 instead, next to the existing error counter.
* mp4: Introduce mp4_is_audio_track().Andre Noll2022-05-30
| | | | | | | | | | | | | | | Currently the aac audio format handler iterates over the tracks in an mp4 file. For each track it tries to get the audio-specific configuration by calling mp4_get_decoder_config() and calls into faad to check whether it is a valid configuration for the aac decoder. We can simplify all this because the mp4 code already knows the type of each track, albeit it does not expose this information yet. So provide the new mp4_is_audio_track() helper and let the aac audio format handler pick the first track for which this helper returns true. As an additional benefit, we can remove the now unused mp4_get_decoder_config().
* mp4: Replace mp4ff prefix by mp4.Andre Noll2022-05-30
| | | | | | | | | | | | | | The additional "ff" does not convey any useful information. This patch was produced by running sed -i 's/mp4ff/mp4/g' mp4.c mp4.h aac_afh.c followed by sed -i 's/MP4FF/MP4/g' aac_afh.c error.h and the manual removal of the "ff" suffix in the error strings.
* mp4: Rename mp4ff_open_read_metaonly() -> mp4ff_open_meta().Andre Noll2022-05-30
| | | | | | The old name is misleading because the returned file handle is by no means opened read-only. In fact we call mp4ff_meta_update() on it, which alters the file to store the modified metadata.
* mp4: Introduce mp4ff_get_duration().Andre Noll2022-05-30
| | | | | | This allows us to get rid of an ugly hack in aac_afh.c where we peeked at the audio-specific config structure to get the scaling factor which was needed to compute the duration.
* mp4: Remove const qualifier from non-pointer function arguments.Andre Noll2022-05-30
| | | | | | In contrast to the pointer case, it's generally not very interesting to know whether a function will modify the automatic variable which corresponds to a non-pointer argument.
* mp4: Make struct mp4ff opaque, hide struct mp4ff_track.Andre Noll2022-05-30
| | | | | | | For the former, code outside of mp4.c only needs a pointer while the latter does not need to be exposed at all. Fix the indentation of the two declarations while at it.
* mp4: Avoid typedefs for data structures.Andre Noll2022-05-30
| | | | They only obfuscate the type.
* mp4: Remove member moov_read of struct mp4ff.Andre Noll2022-05-30
| | | | It is set but never read.
* mp4: Simplify and rename mp4ff_read_sample_getsize().Andre Noll2022-05-30
| | | | | | The new code is much shorter. It is equivalent because the single caller only checks whether the return value is less or equal then zero, and does not use the return value in this case.
* aac: Let mp4ff_set_sample_position() return void.Andre Noll2022-05-30
| | | | The function used to always return zero.
* aac: Move declaration of mp4ff_set_sample_position() to mp4.h.Andre Noll2022-05-30
| | | | | | | | We used to provide the declaration of mp4ff_set_sample_position() in aac_afh.c. With the internal mp4.c this is no longer necessary as we may as well declare the function in mp4.h. Remove the documentation since it has become stale.
* mp4: Wire it in and make it compile cleanly.Andre Noll2022-05-30
| | | | | | | | | | This switches to our local copy of libmp4ff. The configure script now turns on support for the aac audio format even if libmp4ff is not installed. Some changes to mp4.c were necessary to silence warnings, most of which are trivial. The single notably non-trivial change is the missing initialization of chunk_sample and chunk in mp4ff_chunk_of_sample().
* Provide our own copy of libmp4ff.Andre Noll2022-05-30
This library was removed from the faad repository in 2017. This commit put everything we need from the libmp4ff code base into the new mp4.c and mp4.h files. All content was taken unmodified from commit 1cf5a505daf0 of the faad2 repo, the last commit that contains the library. The code needs a lot of cleanup and does not compile without warnings. We commit it as-is to track what exactly has been copied from libmp4ff. The new mp4.c has not been included into the build system, however, so this commit has no effect yet.