2010-01-30 16:57:40 +00:00
|
|
|
/*
|
2015-04-13 07:36:54 +00:00
|
|
|
* This file is part of mpv.
|
2010-01-30 16:57:40 +00:00
|
|
|
*
|
dec_audio, ad_lavc: change license to LGPL
All relevant authors of the current code have agreed.
As always, there are the usual historical artifacts that could be
mentioned. For example, there used to be a large number of decoders
by various authors who were not asked, but whose code was all 100%
removed. (Mostly due to FFmpeg providing all codecs.)
One point of contention is that Nick Kurshev might have refactored the
old audio decoder code in 2001. Basically, there are hints that it might
have been done by him, such as Arpi's commit message stating that the
code was imported from MPlayerXP (Nick's fork), or all the files having
his name in the "maintainer" field. On the other hand, the murky history
of ad.h weakens this - it could be that Arpi started this work, and Nick
took it (and possibly finished it).
In any case, Nick could not be reached, so there is no agreement for
LGPL relicensing from him. We're changing the license anyway, and assume
that his change in itself is not copyrightable. He only moved code, and
in addition used the equivalent video decoder framework (done by Arpi,
who agreed) as template. For example, ad_functions_s was basically
vd_functions_s, which the signature of the decode callback changed to
the same as audio_decode(). ad_functions_s also had a comment that said
it interfaces with "video decoder drivers" (I'm fixing this comment in
this commit).
I verified that no additional code was added that is copyright-relevant,
still in today's code, and not copied from the existing code at the time
(either from the previous audio decoder code or the video framework
code). What apparently matters here is that none of the old code was not
written by Nick, and the authors of the old code have given his
agreement, and (probably) that Nick didn't add actual new code (none
that would have survived), that was not trivially based on the old one
(i.e. no new copyrightable "work").
A copyright expert told me that this kind of change can be considered
not relevant for copyright, so here we go.
Rewriting this would end with the same code anyway, and the naming
conventions can't be copyrighted.
2017-06-14 14:20:56 +00:00
|
|
|
* mpv is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2010-01-30 16:57:40 +00:00
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* mpv is distributed in the hope that it will be useful,
|
2010-01-30 16:57:40 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
dec_audio, ad_lavc: change license to LGPL
All relevant authors of the current code have agreed.
As always, there are the usual historical artifacts that could be
mentioned. For example, there used to be a large number of decoders
by various authors who were not asked, but whose code was all 100%
removed. (Mostly due to FFmpeg providing all codecs.)
One point of contention is that Nick Kurshev might have refactored the
old audio decoder code in 2001. Basically, there are hints that it might
have been done by him, such as Arpi's commit message stating that the
code was imported from MPlayerXP (Nick's fork), or all the files having
his name in the "maintainer" field. On the other hand, the murky history
of ad.h weakens this - it could be that Arpi started this work, and Nick
took it (and possibly finished it).
In any case, Nick could not be reached, so there is no agreement for
LGPL relicensing from him. We're changing the license anyway, and assume
that his change in itself is not copyrightable. He only moved code, and
in addition used the equivalent video decoder framework (done by Arpi,
who agreed) as template. For example, ad_functions_s was basically
vd_functions_s, which the signature of the decode callback changed to
the same as audio_decode(). ad_functions_s also had a comment that said
it interfaces with "video decoder drivers" (I'm fixing this comment in
this commit).
I verified that no additional code was added that is copyright-relevant,
still in today's code, and not copied from the existing code at the time
(either from the previous audio decoder code or the video framework
code). What apparently matters here is that none of the old code was not
written by Nick, and the authors of the old code have given his
agreement, and (probably) that Nick didn't add actual new code (none
that would have survived), that was not trivially based on the old one
(i.e. no new copyrightable "work").
A copyright expert told me that this kind of change can be considered
not relevant for copyright, so here we go.
Rewriting this would end with the same code anyway, and the naming
conventions can't be copyrighted.
2017-06-14 14:20:56 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2010-01-30 16:57:40 +00:00
|
|
|
*
|
dec_audio, ad_lavc: change license to LGPL
All relevant authors of the current code have agreed.
As always, there are the usual historical artifacts that could be
mentioned. For example, there used to be a large number of decoders
by various authors who were not asked, but whose code was all 100%
removed. (Mostly due to FFmpeg providing all codecs.)
One point of contention is that Nick Kurshev might have refactored the
old audio decoder code in 2001. Basically, there are hints that it might
have been done by him, such as Arpi's commit message stating that the
code was imported from MPlayerXP (Nick's fork), or all the files having
his name in the "maintainer" field. On the other hand, the murky history
of ad.h weakens this - it could be that Arpi started this work, and Nick
took it (and possibly finished it).
In any case, Nick could not be reached, so there is no agreement for
LGPL relicensing from him. We're changing the license anyway, and assume
that his change in itself is not copyrightable. He only moved code, and
in addition used the equivalent video decoder framework (done by Arpi,
who agreed) as template. For example, ad_functions_s was basically
vd_functions_s, which the signature of the decode callback changed to
the same as audio_decode(). ad_functions_s also had a comment that said
it interfaces with "video decoder drivers" (I'm fixing this comment in
this commit).
I verified that no additional code was added that is copyright-relevant,
still in today's code, and not copied from the existing code at the time
(either from the previous audio decoder code or the video framework
code). What apparently matters here is that none of the old code was not
written by Nick, and the authors of the old code have given his
agreement, and (probably) that Nick didn't add actual new code (none
that would have survived), that was not trivially based on the old one
(i.e. no new copyrightable "work").
A copyright expert told me that this kind of change can be considered
not relevant for copyright, so here we go.
Rewriting this would end with the same code anyway, and the naming
conventions can't be copyrighted.
2017-06-14 14:20:56 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2010-01-30 16:57:40 +00:00
|
|
|
*/
|
|
|
|
|
2002-03-25 21:06:01 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
2011-08-21 19:47:59 +00:00
|
|
|
#include <stdbool.h>
|
2011-12-22 03:54:48 +00:00
|
|
|
#include <assert.h>
|
2002-03-25 21:06:01 +00:00
|
|
|
|
2011-08-21 19:13:49 +00:00
|
|
|
#include <libavcodec/avcodec.h>
|
2012-01-28 11:41:36 +00:00
|
|
|
#include <libavutil/opt.h>
|
2013-07-11 17:20:41 +00:00
|
|
|
#include <libavutil/common.h>
|
2014-10-03 15:29:53 +00:00
|
|
|
#include <libavutil/intreadwrite.h>
|
2011-08-21 19:13:49 +00:00
|
|
|
|
2022-05-24 19:52:54 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2016-01-11 18:03:40 +00:00
|
|
|
#include "mpv_talloc.h"
|
2018-01-29 05:18:33 +00:00
|
|
|
#include "audio/aframe.h"
|
2022-05-24 19:52:54 +00:00
|
|
|
#include "audio/chmap_avchannel.h"
|
2018-01-29 05:18:33 +00:00
|
|
|
#include "audio/fmt-conversion.h"
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/av_common.h"
|
|
|
|
#include "common/codecs.h"
|
2018-01-29 05:18:33 +00:00
|
|
|
#include "common/global.h"
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/msg.h"
|
2018-01-29 05:18:33 +00:00
|
|
|
#include "demux/packet.h"
|
|
|
|
#include "demux/stheader.h"
|
|
|
|
#include "filters/f_decoder_wrapper.h"
|
|
|
|
#include "filters/filter_internal.h"
|
2018-05-21 14:25:52 +00:00
|
|
|
#include "options/m_config.h"
|
2013-12-17 01:02:25 +00:00
|
|
|
#include "options/options.h"
|
2002-03-25 21:06:01 +00:00
|
|
|
|
2011-08-21 19:47:59 +00:00
|
|
|
struct priv {
|
|
|
|
AVCodecContext *avctx;
|
2012-04-18 22:26:56 +00:00
|
|
|
AVFrame *avframe;
|
ffmpeg: update to handle deprecation of `av_init_packet`
This has been a long standing annoyance - ffmpeg is removing
sizeof(AVPacket) from the API which means you cannot stack-allocate
AVPacket anymore. However, that is something we take advantage of
because we use short-lived AVPackets to bridge from native mpv packets
in our main decoding paths.
We don't think that switching these to `av_packet_alloc` is desirable,
given the cost of heap allocation, so this change takes a different
approach - allocating a single packet in the relevant context and
reusing it over and over.
That's fairly straight-forward, with the main caveat being that
re-initialising the packet is unintuitive. There is no function that
does exactly what we need (what `av_init_packet` did). The closest is
`av_packet_unref`, which additionally frees buffers and side-data.
However, we don't copy those things - we just assign them in from our
own packet, so we have to explicitly clear the pointers before calling
`av_packet_unref`. But at least we can make a wrapper function for
that.
The weirdest part of the change is the handling of the vtt subtitle
conversion. This requires two packets, so I had to pre-allocate two in
the context struct. That sounds excessive, but if allocating the
primary packet is too expensive, then allocating the secondary one for
vtt subtitles must also be too expensive.
This change is not conditional as heap allocated AVPackets were
available for years and years before the deprecation.
2022-11-29 19:15:16 +00:00
|
|
|
AVPacket *avpkt;
|
2018-01-29 05:18:33 +00:00
|
|
|
struct mp_chmap force_channel_map;
|
2016-02-22 18:58:11 +00:00
|
|
|
uint32_t skip_samples, trim_samples;
|
2016-02-22 19:10:38 +00:00
|
|
|
bool preroll_done;
|
2016-02-22 12:08:08 +00:00
|
|
|
double next_pts;
|
2016-03-24 15:39:15 +00:00
|
|
|
AVRational codec_timebase;
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
struct lavc_state state;
|
2011-08-21 19:47:59 +00:00
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
struct mp_decoder public;
|
|
|
|
};
|
2013-07-22 12:41:56 +00:00
|
|
|
|
2014-06-10 23:39:51 +00:00
|
|
|
#define OPT_BASE_STRUCT struct ad_lavc_params
|
|
|
|
struct ad_lavc_params {
|
|
|
|
float ac3drc;
|
|
|
|
int downmix;
|
|
|
|
int threads;
|
2014-08-02 01:12:09 +00:00
|
|
|
char **avopts;
|
2014-06-10 23:39:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct m_sub_options ad_lavc_conf = {
|
|
|
|
.opts = (const m_option_t[]) {
|
options: change option macros and all option declarations
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with
{"name", ...
followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.
I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.
Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.
Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.
In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
2020-03-14 20:28:01 +00:00
|
|
|
{"ac3drc", OPT_FLOAT(ac3drc), M_RANGE(0, 6)},
|
|
|
|
{"downmix", OPT_FLAG(downmix)},
|
|
|
|
{"threads", OPT_INT(threads), M_RANGE(0, 16)},
|
|
|
|
{"o", OPT_KEYVALUELIST(avopts)},
|
2014-06-10 23:39:51 +00:00
|
|
|
{0}
|
|
|
|
},
|
|
|
|
.size = sizeof(struct ad_lavc_params),
|
|
|
|
.defaults = &(const struct ad_lavc_params){
|
2015-03-30 17:44:52 +00:00
|
|
|
.ac3drc = 0,
|
2020-02-29 21:08:38 +00:00
|
|
|
.downmix = 0,
|
2014-06-10 23:39:51 +00:00
|
|
|
.threads = 1,
|
|
|
|
},
|
2011-08-21 19:47:59 +00:00
|
|
|
};
|
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
static bool init(struct mp_filter *da, struct mp_codec_params *codec,
|
|
|
|
const char *decoder)
|
2002-03-25 21:06:01 +00:00
|
|
|
{
|
2018-01-29 05:18:33 +00:00
|
|
|
struct priv *ctx = da->priv;
|
2019-11-28 23:16:52 +00:00
|
|
|
struct MPOpts *mpopts = mp_get_config_group(ctx, da->global, &mp_opt_root);
|
2018-05-21 14:25:52 +00:00
|
|
|
struct ad_lavc_params *opts =
|
|
|
|
mp_get_config_group(ctx, da->global, &ad_lavc_conf);
|
2002-04-03 21:01:15 +00:00
|
|
|
AVCodecContext *lavc_context;
|
2021-05-01 19:53:56 +00:00
|
|
|
const AVCodec *lavc_codec;
|
2013-04-06 23:27:33 +00:00
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
ctx->codec_timebase = mp_get_codec_timebase(codec);
|
2016-03-24 15:39:15 +00:00
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
if (codec->force_channels)
|
|
|
|
ctx->force_channel_map = codec->channels;
|
2014-09-24 20:55:50 +00:00
|
|
|
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
lavc_codec = avcodec_find_decoder_by_name(decoder);
|
|
|
|
if (!lavc_codec) {
|
2013-12-21 17:23:59 +00:00
|
|
|
MP_ERR(da, "Cannot find codec '%s' in libavcodec...\n", decoder);
|
2018-01-29 05:18:33 +00:00
|
|
|
return false;
|
2002-03-25 21:06:01 +00:00
|
|
|
}
|
2009-07-06 23:26:13 +00:00
|
|
|
|
2012-01-28 11:41:36 +00:00
|
|
|
lavc_context = avcodec_alloc_context3(lavc_codec);
|
2011-08-21 19:47:59 +00:00
|
|
|
ctx->avctx = lavc_context;
|
2014-03-16 11:50:15 +00:00
|
|
|
ctx->avframe = av_frame_alloc();
|
ffmpeg: update to handle deprecation of `av_init_packet`
This has been a long standing annoyance - ffmpeg is removing
sizeof(AVPacket) from the API which means you cannot stack-allocate
AVPacket anymore. However, that is something we take advantage of
because we use short-lived AVPackets to bridge from native mpv packets
in our main decoding paths.
We don't think that switching these to `av_packet_alloc` is desirable,
given the cost of heap allocation, so this change takes a different
approach - allocating a single packet in the relevant context and
reusing it over and over.
That's fairly straight-forward, with the main caveat being that
re-initialising the packet is unintuitive. There is no function that
does exactly what we need (what `av_init_packet` did). The closest is
`av_packet_unref`, which additionally frees buffers and side-data.
However, we don't copy those things - we just assign them in from our
own packet, so we have to explicitly clear the pointers before calling
`av_packet_unref`. But at least we can make a wrapper function for
that.
The weirdest part of the change is the handling of the vtt subtitle
conversion. This requires two packets, so I had to pre-allocate two in
the context struct. That sounds excessive, but if allocating the
primary packet is too expensive, then allocating the secondary one for
vtt subtitles must also be too expensive.
This change is not conditional as heap allocated AVPackets were
available for years and years before the deprecation.
2022-11-29 19:15:16 +00:00
|
|
|
ctx->avpkt = av_packet_alloc();
|
demux_lavf, ad_lavc, vd_lavc: pass codec header data directly
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
2013-02-09 14:15:37 +00:00
|
|
|
lavc_context->codec_type = AVMEDIA_TYPE_AUDIO;
|
|
|
|
lavc_context->codec_id = lavc_codec->id;
|
2016-08-29 10:46:12 +00:00
|
|
|
lavc_context->pkt_timebase = ctx->codec_timebase;
|
demux_lavf, ad_lavc, vd_lavc: pass codec header data directly
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
2013-02-09 14:15:37 +00:00
|
|
|
|
2016-08-04 18:49:20 +00:00
|
|
|
if (opts->downmix && mpopts->audio_output_channels.num_chmaps == 1) {
|
2022-05-24 19:52:54 +00:00
|
|
|
const struct mp_chmap *requested_layout =
|
|
|
|
&mpopts->audio_output_channels.chmaps[0];
|
|
|
|
#if !HAVE_AV_CHANNEL_LAYOUT
|
2013-04-06 20:43:12 +00:00
|
|
|
lavc_context->request_channel_layout =
|
2022-05-24 19:52:54 +00:00
|
|
|
mp_chmap_to_lavc(requested_layout);
|
|
|
|
#else
|
|
|
|
AVChannelLayout av_layout = { 0 };
|
|
|
|
mp_chmap_to_av_layout(&av_layout, requested_layout);
|
|
|
|
|
|
|
|
// Always try to set requested output layout - currently only something
|
|
|
|
// supported by AC3, MLP/TrueHD, DTS and the fdk-aac wrapper.
|
|
|
|
av_opt_set_chlayout(lavc_context, "downmix", &av_layout,
|
|
|
|
AV_OPT_SEARCH_CHILDREN);
|
|
|
|
|
|
|
|
av_channel_layout_uninit(&av_layout);
|
|
|
|
#endif
|
2013-04-06 20:43:12 +00:00
|
|
|
}
|
2002-10-28 00:40:42 +00:00
|
|
|
|
2012-01-28 11:41:36 +00:00
|
|
|
// Always try to set - option only exists for AC3 at the moment
|
2013-03-31 02:24:53 +00:00
|
|
|
av_opt_set_double(lavc_context, "drc_scale", opts->ac3drc,
|
2012-01-28 11:41:36 +00:00
|
|
|
AV_OPT_SEARCH_CHILDREN);
|
demux_lavf, ad_lavc, vd_lavc: pass codec header data directly
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
2013-02-09 14:15:37 +00:00
|
|
|
|
2014-10-03 15:29:53 +00:00
|
|
|
// Let decoder add AV_FRAME_DATA_SKIP_SAMPLES.
|
|
|
|
av_opt_set(lavc_context, "flags2", "+skip_manual", AV_OPT_SEARCH_CHILDREN);
|
|
|
|
|
2014-08-02 01:12:09 +00:00
|
|
|
mp_set_avopts(da->log, lavc_context, opts->avopts);
|
2013-03-31 02:24:53 +00:00
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
if (mp_set_avctx_codec_headers(lavc_context, codec) < 0) {
|
2017-01-25 07:24:19 +00:00
|
|
|
MP_ERR(da, "Could not set decoder parameters.\n");
|
2018-01-29 05:18:33 +00:00
|
|
|
return false;
|
2017-01-25 07:24:19 +00:00
|
|
|
}
|
demux_lavf, ad_lavc, vd_lavc: pass codec header data directly
Instead of putting codec header data into WAVEFORMATEX and
BITMAPINFOHEADER, pass it directly via AVCodecContext. To do this, we
add mp_copy_lav_codec_headers(), which copies the codec header data
from one AVCodecContext to another (originally, the plan was to use
avcodec_copy_context() for this, but it looks like this would turn
decoder initialization into an even worse mess).
Get rid of the silly CodecID <-> codec_tag mapping. This was originally
needed for codecs.conf: codec tags were used to identify codecs, but
libavformat didn't always return useful codec tags (different file
formats can have different, overlapping tag numbers). Since we don't
go through WAVEFORMATEX etc. and pass all header data directly via
AVCodecContext, we can be absolutely sure that the codec tag mapping is
not needed anymore.
Note that this also destroys the "standard" MPlayer method of exporting
codec header data. WAVEFORMATEX and BITMAPINFOHEADER made sure that
other non-libavcodec decoders could be initialized. However, all these
decoders have been removed, so this is just cruft full of old hacks that
are not needed anymore. There's still ad_spdif and ad_mpg123, bu neither
of these need codec header data. Should we ever add non-libavcodec
decoders, better data structures without the past hacks could be added
to export the headers.
2013-02-09 14:15:37 +00:00
|
|
|
|
2015-01-05 11:17:55 +00:00
|
|
|
mp_set_avcodec_threads(da->log, lavc_context, opts->threads);
|
2013-12-04 19:58:53 +00:00
|
|
|
|
2002-03-25 21:06:01 +00:00
|
|
|
/* open it */
|
2012-01-28 11:41:36 +00:00
|
|
|
if (avcodec_open2(lavc_context, lavc_codec, NULL) < 0) {
|
2013-12-21 17:23:59 +00:00
|
|
|
MP_ERR(da, "Could not open codec.\n");
|
2018-01-29 05:18:33 +00:00
|
|
|
return false;
|
2002-03-25 21:06:01 +00:00
|
|
|
}
|
|
|
|
|
2016-02-22 12:08:08 +00:00
|
|
|
ctx->next_pts = MP_NOPTS_VALUE;
|
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
return true;
|
2002-03-25 21:06:01 +00:00
|
|
|
}
|
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
static void destroy(struct mp_filter *da)
|
2002-03-25 21:06:01 +00:00
|
|
|
{
|
2013-11-23 20:22:17 +00:00
|
|
|
struct priv *ctx = da->priv;
|
2002-10-28 00:40:42 +00:00
|
|
|
|
2017-07-06 14:12:50 +00:00
|
|
|
avcodec_free_context(&ctx->avctx);
|
2014-03-16 11:50:15 +00:00
|
|
|
av_frame_free(&ctx->avframe);
|
ffmpeg: update to handle deprecation of `av_init_packet`
This has been a long standing annoyance - ffmpeg is removing
sizeof(AVPacket) from the API which means you cannot stack-allocate
AVPacket anymore. However, that is something we take advantage of
because we use short-lived AVPackets to bridge from native mpv packets
in our main decoding paths.
We don't think that switching these to `av_packet_alloc` is desirable,
given the cost of heap allocation, so this change takes a different
approach - allocating a single packet in the relevant context and
reusing it over and over.
That's fairly straight-forward, with the main caveat being that
re-initialising the packet is unintuitive. There is no function that
does exactly what we need (what `av_init_packet` did). The closest is
`av_packet_unref`, which additionally frees buffers and side-data.
However, we don't copy those things - we just assign them in from our
own packet, so we have to explicitly clear the pointers before calling
`av_packet_unref`. But at least we can make a wrapper function for
that.
The weirdest part of the change is the handling of the vtt subtitle
conversion. This requires two packets, so I had to pre-allocate two in
the context struct. That sounds excessive, but if allocating the
primary packet is too expensive, then allocating the secondary one for
vtt subtitles must also be too expensive.
This change is not conditional as heap allocated AVPackets were
available for years and years before the deprecation.
2022-11-29 19:15:16 +00:00
|
|
|
mp_free_av_packet(&ctx->avpkt);
|
2002-03-25 21:06:01 +00:00
|
|
|
}
|
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
static void reset(struct mp_filter *da)
|
2002-03-25 21:06:01 +00:00
|
|
|
{
|
2013-11-23 20:22:17 +00:00
|
|
|
struct priv *ctx = da->priv;
|
2018-01-29 05:18:33 +00:00
|
|
|
|
|
|
|
avcodec_flush_buffers(ctx->avctx);
|
|
|
|
ctx->skip_samples = 0;
|
|
|
|
ctx->trim_samples = 0;
|
|
|
|
ctx->preroll_done = false;
|
|
|
|
ctx->next_pts = MP_NOPTS_VALUE;
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
ctx->state = (struct lavc_state){0};
|
2002-03-25 21:06:01 +00:00
|
|
|
}
|
|
|
|
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
static int send_packet(struct mp_filter *da, struct demux_packet *mpkt)
|
2012-04-18 22:26:56 +00:00
|
|
|
{
|
2013-11-23 20:22:17 +00:00
|
|
|
struct priv *priv = da->priv;
|
2012-04-18 22:26:56 +00:00
|
|
|
AVCodecContext *avctx = priv->avctx;
|
audio: add support for using non-interleaved audio from decoders directly
Most libavcodec decoders output non-interleaved audio. Add direct
support for this, and remove the hack that repacked non-interleaved
audio back to packed audio.
Remove the minlen argument from the decoder callback. Instead of
forcing every decoder to have its own decode loop to fill the buffer
until minlen is reached, leave this to the caller. So if a decoder
doesn't return enough data, it's simply called again. (In future, I
even want to change it so that decoders don't read packets directly,
but instead the caller has to pass packets to the decoders. This fits
well with this change, because now the decoder callback typically
decodes at most one packet.)
ad_mpg123.c receives some heavy refactoring. The main problem is that
it wanted to handle format changes when there was no data in the decode
output buffer yet. This sounds reasonable, but actually it would write
data into a buffer prepared for old data, since the caller doesn't know
about the format change yet. (I.e. the best place for a format change
would be _after_ writing the last sample to the output buffer.) It's
possible that this code was not perfectly sane before this commit,
and perhaps lost one frame of data after a format change, but I didn't
confirm this. Trying to fix this, I ended up rewriting the decoding
and also the probing.
2013-11-12 21:27:44 +00:00
|
|
|
|
2016-07-01 13:51:34 +00:00
|
|
|
// If the decoder discards the timestamp for some reason, we use the
|
|
|
|
// interpolated PTS. Initialize it so that it works for the initial
|
|
|
|
// packet as well.
|
|
|
|
if (mpkt && priv->next_pts == MP_NOPTS_VALUE)
|
|
|
|
priv->next_pts = mpkt->pts;
|
|
|
|
|
ffmpeg: update to handle deprecation of `av_init_packet`
This has been a long standing annoyance - ffmpeg is removing
sizeof(AVPacket) from the API which means you cannot stack-allocate
AVPacket anymore. However, that is something we take advantage of
because we use short-lived AVPackets to bridge from native mpv packets
in our main decoding paths.
We don't think that switching these to `av_packet_alloc` is desirable,
given the cost of heap allocation, so this change takes a different
approach - allocating a single packet in the relevant context and
reusing it over and over.
That's fairly straight-forward, with the main caveat being that
re-initialising the packet is unintuitive. There is no function that
does exactly what we need (what `av_init_packet` did). The closest is
`av_packet_unref`, which additionally frees buffers and side-data.
However, we don't copy those things - we just assign them in from our
own packet, so we have to explicitly clear the pointers before calling
`av_packet_unref`. But at least we can make a wrapper function for
that.
The weirdest part of the change is the handling of the vtt subtitle
conversion. This requires two packets, so I had to pre-allocate two in
the context struct. That sounds excessive, but if allocating the
primary packet is too expensive, then allocating the secondary one for
vtt subtitles must also be too expensive.
This change is not conditional as heap allocated AVPackets were
available for years and years before the deprecation.
2022-11-29 19:15:16 +00:00
|
|
|
mp_set_av_packet(priv->avpkt, mpkt, &priv->codec_timebase);
|
2013-06-02 23:55:48 +00:00
|
|
|
|
ffmpeg: update to handle deprecation of `av_init_packet`
This has been a long standing annoyance - ffmpeg is removing
sizeof(AVPacket) from the API which means you cannot stack-allocate
AVPacket anymore. However, that is something we take advantage of
because we use short-lived AVPackets to bridge from native mpv packets
in our main decoding paths.
We don't think that switching these to `av_packet_alloc` is desirable,
given the cost of heap allocation, so this change takes a different
approach - allocating a single packet in the relevant context and
reusing it over and over.
That's fairly straight-forward, with the main caveat being that
re-initialising the packet is unintuitive. There is no function that
does exactly what we need (what `av_init_packet` did). The closest is
`av_packet_unref`, which additionally frees buffers and side-data.
However, we don't copy those things - we just assign them in from our
own packet, so we have to explicitly clear the pointers before calling
`av_packet_unref`. But at least we can make a wrapper function for
that.
The weirdest part of the change is the handling of the vtt subtitle
conversion. This requires two packets, so I had to pre-allocate two in
the context struct. That sounds excessive, but if allocating the
primary packet is too expensive, then allocating the secondary one for
vtt subtitles must also be too expensive.
This change is not conditional as heap allocated AVPackets were
available for years and years before the deprecation.
2022-11-29 19:15:16 +00:00
|
|
|
int ret = avcodec_send_packet(avctx, mpkt ? priv->avpkt : NULL);
|
2017-01-11 10:58:26 +00:00
|
|
|
if (ret < 0)
|
|
|
|
MP_ERR(da, "Error decoding audio.\n");
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
return ret;
|
2017-01-11 10:58:26 +00:00
|
|
|
}
|
|
|
|
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
static int receive_frame(struct mp_filter *da, struct mp_frame *out)
|
2017-01-11 10:58:26 +00:00
|
|
|
{
|
|
|
|
struct priv *priv = da->priv;
|
|
|
|
AVCodecContext *avctx = priv->avctx;
|
|
|
|
|
|
|
|
int ret = avcodec_receive_frame(avctx, priv->avframe);
|
|
|
|
|
|
|
|
if (ret == AVERROR_EOF) {
|
|
|
|
// If flushing was initialized earlier and has ended now, make it start
|
|
|
|
// over in case we get new packets at some point in the future.
|
2018-01-29 05:18:33 +00:00
|
|
|
// (Dont' reset the filter itself, we want to keep other state.)
|
|
|
|
avcodec_flush_buffers(priv->avctx);
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
return ret;
|
2017-01-11 10:58:26 +00:00
|
|
|
} else if (ret < 0 && ret != AVERROR(EAGAIN)) {
|
2014-07-21 17:29:37 +00:00
|
|
|
MP_ERR(da, "Error decoding audio.\n");
|
2012-04-18 22:26:56 +00:00
|
|
|
}
|
2017-01-11 10:58:26 +00:00
|
|
|
|
2017-01-24 07:04:53 +00:00
|
|
|
if (priv->avframe->flags & AV_FRAME_FLAG_DISCARD)
|
|
|
|
av_frame_unref(priv->avframe);
|
|
|
|
|
2017-01-11 10:58:26 +00:00
|
|
|
if (!priv->avframe->buf[0])
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
return ret;
|
audio: add support for using non-interleaved audio from decoders directly
Most libavcodec decoders output non-interleaved audio. Add direct
support for this, and remove the hack that repacked non-interleaved
audio back to packed audio.
Remove the minlen argument from the decoder callback. Instead of
forcing every decoder to have its own decode loop to fill the buffer
until minlen is reached, leave this to the caller. So if a decoder
doesn't return enough data, it's simply called again. (In future, I
even want to change it so that decoders don't read packets directly,
but instead the caller has to pass packets to the decoders. This fits
well with this change, because now the decoder callback typically
decodes at most one packet.)
ad_mpg123.c receives some heavy refactoring. The main problem is that
it wanted to handle format changes when there was no data in the decode
output buffer yet. This sounds reasonable, but actually it would write
data into a buffer prepared for old data, since the caller doesn't know
about the format change yet. (I.e. the best place for a format change
would be _after_ writing the last sample to the output buffer.) It's
possible that this code was not perfectly sane before this commit,
and perhaps lost one frame of data after a format change, but I didn't
confirm this. Trying to fix this, I ended up rewriting the decoding
and also the probing.
2013-11-12 21:27:44 +00:00
|
|
|
|
2016-12-07 18:44:29 +00:00
|
|
|
double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase);
|
2013-12-04 19:57:52 +00:00
|
|
|
|
audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).
The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.
Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.
For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.
Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 19:00:20 +00:00
|
|
|
struct mp_aframe *mpframe = mp_aframe_from_avframe(priv->avframe);
|
2019-09-27 19:24:24 +00:00
|
|
|
if (!mpframe) {
|
|
|
|
MP_ERR(da, "Converting libavcodec frame to mpv frame failed.\n");
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
return ret;
|
2019-09-27 19:24:24 +00:00
|
|
|
}
|
2014-11-10 21:01:23 +00:00
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
if (priv->force_channel_map.num)
|
|
|
|
mp_aframe_set_chmap(mpframe, &priv->force_channel_map);
|
2014-11-10 21:01:23 +00:00
|
|
|
|
audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).
The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.
Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.
For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.
Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 19:00:20 +00:00
|
|
|
if (out_pts == MP_NOPTS_VALUE)
|
|
|
|
out_pts = priv->next_pts;
|
|
|
|
mp_aframe_set_pts(mpframe, out_pts);
|
2015-11-08 16:22:56 +00:00
|
|
|
|
audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).
The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.
Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.
For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.
Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 19:00:20 +00:00
|
|
|
priv->next_pts = mp_aframe_end_pts(mpframe);
|
2016-02-22 12:08:08 +00:00
|
|
|
|
2014-11-10 21:01:23 +00:00
|
|
|
AVFrameSideData *sd =
|
|
|
|
av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES);
|
|
|
|
if (sd && sd->size >= 10) {
|
|
|
|
char *d = sd->data;
|
|
|
|
priv->skip_samples += AV_RL32(d + 0);
|
2016-02-22 18:58:11 +00:00
|
|
|
priv->trim_samples += AV_RL32(d + 4);
|
2014-11-10 21:01:23 +00:00
|
|
|
}
|
|
|
|
|
2016-02-22 19:10:38 +00:00
|
|
|
if (!priv->preroll_done) {
|
|
|
|
// Skip only if this isn't already handled by AV_FRAME_DATA_SKIP_SAMPLES.
|
|
|
|
if (!priv->skip_samples)
|
|
|
|
priv->skip_samples = avctx->delay;
|
|
|
|
priv->preroll_done = true;
|
|
|
|
}
|
|
|
|
|
audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).
The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.
Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.
For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.
Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 19:00:20 +00:00
|
|
|
uint32_t skip = MPMIN(priv->skip_samples, mp_aframe_get_size(mpframe));
|
2016-02-22 18:50:09 +00:00
|
|
|
if (skip) {
|
audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).
The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.
Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.
For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.
Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 19:00:20 +00:00
|
|
|
mp_aframe_skip_samples(mpframe, skip);
|
2016-02-22 18:50:09 +00:00
|
|
|
priv->skip_samples -= skip;
|
|
|
|
}
|
audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).
The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.
Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.
For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.
Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 19:00:20 +00:00
|
|
|
uint32_t trim = MPMIN(priv->trim_samples, mp_aframe_get_size(mpframe));
|
2016-02-22 18:58:11 +00:00
|
|
|
if (trim) {
|
audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).
The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.
Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.
For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.
Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 19:00:20 +00:00
|
|
|
mp_aframe_set_size(mpframe, mp_aframe_get_size(mpframe) - trim);
|
2016-02-22 18:58:11 +00:00
|
|
|
priv->trim_samples -= trim;
|
|
|
|
}
|
2016-02-22 18:50:09 +00:00
|
|
|
|
2022-06-16 01:12:44 +00:00
|
|
|
// Strip possibly bogus float values like Infinity, NaN, denormalized
|
|
|
|
mp_aframe_sanitize_float(mpframe);
|
|
|
|
|
2019-05-22 19:45:54 +00:00
|
|
|
if (mp_aframe_get_size(mpframe) > 0) {
|
|
|
|
*out = MAKE_FRAME(MP_FRAME_AUDIO, mpframe);
|
|
|
|
} else {
|
|
|
|
talloc_free(mpframe);
|
|
|
|
}
|
2014-11-10 21:01:23 +00:00
|
|
|
|
|
|
|
av_frame_unref(priv->avframe);
|
2014-10-03 15:29:53 +00:00
|
|
|
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
return ret;
|
2002-03-25 21:06:01 +00:00
|
|
|
}
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
static void process(struct mp_filter *ad)
|
|
|
|
{
|
|
|
|
struct priv *priv = ad->priv;
|
|
|
|
|
ad_lavc, vd_lavc: return full error codes to shared decoder loop
ad_lavc and vd_lavc use the lavc_process() helper to translate the
FFmpeg push/pull API to the internal filter API (which completely
mismatch, even though I'm responsible for both, just fucking kill me).
This interface was "slightly" too tight. It returned only a bool
indicating "progress", which was not enough to handle some cases (see
following commit).
While we're at it, move all state into a struct. This is only a single
bool, but we get the chance to add more if needed.
This fixes mpv falling asleep if decoding returns an error during
draining. If decoding fails when we already sent EOF, the state machine
stopped making progress. This left mpv just sitting around and doing
nothing.
A test case can be created with: echo $RANDOM >> image.png
This makes libavformat read a proper packet plus a packet of garbage.
libavcodec will decode a frame, and then return an error code. The
lavc_process() wrapper could not deal with this, because there was no
way to differentiate between "retry" and "send new packet". Normally, it
would send a new packet, so decoding would make progress anyway. If
there was "progress", we couldn't just retry, because it'd retry
forever.
This is made worse by the fact that it tries to decode at least two
frames before starting display, meaning it will "sit around and do
nothing" before the picture is displayed.
Change it so that on error return, "receiving" a frame is retried. This
will make it return the EOF, so everything works properly.
This is a high-risk change, because all these funny bullshit exceptions
for hardware decoding are in the way, and I didn't retest them. For
example, if hardware decoding is enabled, it keeps a list of packets,
that are fed into the decoder again if hardware decoding fails, and a
software fallback is performed. Another case of horrifying accidental
complexity.
Fixes: #6618
2019-10-24 16:40:46 +00:00
|
|
|
lavc_process(ad, &priv->state, send_packet, receive_frame);
|
2018-01-29 05:18:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct mp_filter_info ad_lavc_filter = {
|
|
|
|
.name = "ad_lavc",
|
|
|
|
.priv_size = sizeof(struct priv),
|
|
|
|
.process = process,
|
|
|
|
.reset = reset,
|
|
|
|
.destroy = destroy,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct mp_decoder *create(struct mp_filter *parent,
|
|
|
|
struct mp_codec_params *codec,
|
|
|
|
const char *decoder)
|
|
|
|
{
|
|
|
|
struct mp_filter *da = mp_filter_create(parent, &ad_lavc_filter);
|
|
|
|
if (!da)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
mp_filter_add_pin(da, MP_PIN_IN, "in");
|
|
|
|
mp_filter_add_pin(da, MP_PIN_OUT, "out");
|
|
|
|
|
|
|
|
da->log = mp_log_new(da, parent->log, NULL);
|
|
|
|
|
|
|
|
struct priv *priv = da->priv;
|
|
|
|
priv->public.f = da;
|
|
|
|
|
|
|
|
if (!init(da, codec, decoder)) {
|
|
|
|
talloc_free(da);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return &priv->public;
|
|
|
|
}
|
|
|
|
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
static void add_decoders(struct mp_decoder_list *list)
|
|
|
|
{
|
|
|
|
mp_add_lavc_decoders(list, AVMEDIA_TYPE_AUDIO);
|
|
|
|
}
|
2013-07-22 12:41:56 +00:00
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
const struct mp_decoder_fns ad_lavc = {
|
|
|
|
.create = create,
|
2013-07-22 12:41:56 +00:00
|
|
|
.add_decoders = add_decoders,
|
|
|
|
};
|