av_free_packet() got finally deprecated. Use av_packet_unref() instead,
which has almost the same semantics, has existed for a while, and is
available in all FFmpeg and Libav versions we support.
Until recently, the channel layout code happened to catch this, but now
an explicit check is needed. Otherwise, it'd try to pad the missing
channels with NA in the channel map fallback code.
This is intended for the case when CoreAudio returns only unknown
channel layouts, or no channel layout matches the number of channels the
CoreAudio device forces. Assume that outputting stereo or mono to the
first channels is safe, and that it's better than outputting nothing.
It's notable that XBMC/kodi falls back to a static channel layout in
this case. For some messed up reason, the layout it uses happens to
match with the channel order in ALSA's/mpv's "7.1(alsa)" layout.
Share some code between ca_init_chmap() and ca_get_active_chmap(), which
also makes it look slightly nicer. No functional changes, other than the
additional log message.
If no channel layouts were determined (which can actually happen with
some "strange" devices), the selection code was falling back to mono,
because mono is always added as a fallback. This doesn't seem quite
right.
Allow a fallback to stereo too, if no channel layout could be retrieved
at all. So we always assume that mono and stereo work, if no other
layouts are available.
(I still don't know what the CoreAudio stereo layout is supposed to do.
It could be used to swap left and right channels. It could also be used
to pad/move the channels, but I have never seen that. And it can be set
to non-stereo channels, which breaks mpv. Whatever.)
The main reason is that ao_coreaudio_exclusive needs this for some OSX
devices. They want packed audio, and special-casing this in the
coreaudio code would be too much of a pain.
The maximum of channels we can support is 64 (because FFmpeg uses 64 bit
masks for channel layouts), but since struct mp_audio can get pretty
big (has static allocations of 2 pointers for each channel for planar
mode), it's less wasteful to stay lower for now.
av_get_default_channel_layout() fails with channel counts larger than 8.
The channel layout doesn't need to make sense, so pick an arbitrary
fallback.
libswresample also has options for setting the channel counts directly,
but better not introduce new concepts in the code. Also, libavresample
doesn't have these options.
Change it so that it will always return a bitmask with the correct
number of channels set if an unknown channel map is passed. This didn't
work for channel counts larger than 8, as there are not any standard
channel layouts defined with more than 8 channels (both in mpv and
FFmpeg). Instead, it returned 0.
This will help when raising the maximum allowed channel count in mpv.
Some code in af_lavrresample relies on it, more or less.
One change is that unknown channel maps won't result in lavc standard
channel layouts anymore, just a set of random speakers. This should be
fine, as the caller of mp_chmap_to_lavc_unchecked() should handle these
cases. For mp_chmap_reorder_to_lavc() this is not so clear anymore, but
should also be ok.
For normal channel maps, simply dropping NA channels is still the
correct and wanted behavior.
Currently, the mpv maximum channel count is 8. This commit is
preparation for raising this limit.
mNumberChannelDescriptions being 0 is pretty much an error, but if it
can happen, then the code checking the chmap below will trigger UB, as
chmap is not initialized at all.
Also, simplify the code a little: we never change the number of
channels, so this is just fine.
This code removes filters which can not take spdif inout. This was made
so that PCM filters are transparently dropped in spdif mode.
This entered an endless loop with:
--af=lavcac3enc:::2 --audio-channels=5.1
The forced number of output channels is incompatible with spdif. It's
trying to insert af_lavrresample as conversion filter to compensate for
it. Of course this doesn't work, which triggers the PCM filter removal.
Then it goes on normally - since the new state is exactly as before, it
will try the same thing again, forever.
Fix by reusing the retry counter, which is a very dumb but very
effective measure against these cases of filter negotiation failure. We
could try to be more clever (for example, if the removed filter is a
conversion filter, we can be sure this won't work, and error out
immediately). But better keep it simple and robust.
Coreaudio gives us a channel map with all entries set to
kAudioChannelLabel_Unknown. This is translated to a mpv channel map with
all channels set to NA, which has special meaning: it's an "unknown"
channel map, which acts as wildcard and can be converted from/to any
channel layout. Not really what we want.
I've got this with USB audio, playing stereo. The multichannel layout
consisted of 2 unknown channels, while the stereo channel map was
stereo (as expected).
Note that channel maps with _some_ NA entries are not affected by this,
and must still work.
If the device returns an unexpected number of channels instead of the
requested count on init, don't immediately error out. Instead, look if
there's a channel map with the given number of channels.
If there isn't, still error out, because we don't want to guess the
channel layout.
Reportedly fixes operation with "USB connected Parasound ZDAC v.2". (OSX
and USB audio sure is not nice at all.)
This might be perceived as hang by some users, so it's quite possible
that this will have to be adjusted again somehow.
Fixes#2409.
Small adjustments to the playback speed use swr_set_compensation()
to stretch the audio as it is required. But since large adjustments
are now handled by actually reinitializing libswresample, the small
adjustments get rounded off completely with typical frame sizes.
Compensate for this by accounting for the rounding error and keeping
track of fractional samples that should have been output to achieve
the correct ratio.
This fixes display sync mode behavior, which requires these adjustments
to be relatively accurate.
swr/avresample_set_compensation() was made for small speed adjustments.
Non-documentation says it should be used for changes not larger than 1%,
so reinitialize the sampler if the change is larger than that.
swr_set_compensation() changes the apparent sample rate on the fly (who
would have guessed). It is thus very well-suited for adjusting audio
speed on the fly during playback (like needed by the display-sync mode).
It skips the relatively slow resampler reinitialization.
If this doesn't work (libswresample soxr backend), then fall back to the
old method.
The previous commit handled not falling back to normal decoding if the
AO was reloaded (I think...), and this tries to re-engage spdif pass-
through if it was previously falling back to normal decoding (e.g.
because it temporarily switched to an audio device incapable of
passthrough).
The manpage entry explains this.
(Maybe this option could be always enabled and removed. I don't quite
remember what valid use-cases there are for just disabling audio
entirely, other than that this is also needed for audio decoder init
failure.)
Make the code a bit more uniform. Always build a "dummy" audio output
list before probing, which means that opening preferred devices and
pure auto-probing is done with the same code. We can drop the second
ao_init() call.
This also makes the next commit easier, which wants to selectively
fallback to ao_null. This could have been implemented by passing a
different requested audio output list (instead of reading it from
MPOptions), but I think it's better if this rather special feature
is handled internally in the AO code. This also makes sure the AO
code can handle its own options (such as the audio output list) in
a self-contained way.
This can happen with USB audio. There was already code for this, but
something in mpv and ALSA changed - and now the old code is not
necessarily triggered anymore. It probably depends on the exact
situation.
This could sometimes cause crashes in hotplug events. (Apparently in
cases when CoreAudio changes its state asynchronously, or such.)
CA_GET_STR() does not set the string if there was an error, so errors
have to be strictly checked before using it.
This flag was used by some filters and made sure none of these filters
were inserted twice. This triggers only if the user explicitly tries to
add multiple filters (and not e.g. due to auto-insertion), so at best
this warned the user from doing something potentially pointless. At
worst, it blocked some (mildly) legitimate use-cases. Get rid of it.
Also see #2322.
The reason MPlayer traditionally duplicated them all over the place is
that it wanted every component to be a self-contained library (e.g.
audio filters were in "libaf"). But this is not necessarily helpful, and
this change makes the following commit a bit simpler.
* (de)planarize -1
* pad 1 byte -8
* truncate 1 byte -1024
* float -> int 1048576 * (8 - dst_bytes)
* int -> float -512
Now the score is negative if and only if the conversion is lossy
(e.g. previously s24 -> float was given a negative (lossy) score),
However, int->float is still considered bad
(s16->float is worse than than s16->s32).
This penalizes any loss of precision more than performance / bandwidth hits.
For example, previously s24->s16p was considered equal to s24->u8.
Finally, we penalize padding more than (de)planarizing as this will
increase the output size for example with ao_lavc.
This is just a refactor, which makes it use the previously introduced
function, and allows us to make af_format_conversion_score() private.
(We drop 2 unlikely warning messages too... who cares.)
This mixed up the returned score for some interleaved/non-interleaved
comparisons. Changing interleaving subtracted 1 point, while extending
sample size by 1 byte also subtracted 1 point.
(This scoring system is not ideal - it'd be much cleaner to do a 3-way
sample format comparison instead, and sort the formats according to the
comparison instead of the score.)
Not sure why struct af_resample_opts even exists. It seems useful to
group the fields set by user options. But storing the current format
conversion parameters doesn't seem very elegant, and having a separate
instance in the "ctx" field isn't helpful either.
Some users still use this filter, so the filter was going to be kept.
But I overlooked that libavfilter provides this filter. Remove the
redundant wrapper from mpv. Something like --af=lavfi=bs2b should work
and give exactly the same results.