avdemux: Remove typefinder implementation

Direct access to AVInputFormat::read_probe() is not possible anymore
with ffmpeg 7.0, and the usefulness of this typefinder seems limited
anyway. An alternative implementation around av_probe_input_format3() or
similar would be possible but it would be going over all possible ffmpeg
probes at once.

Having a typefinder here means that basically every application will
load the gst-libav plugin when typefinding is necessary, which has
unnecessary performance impacts. If a typefinder from here was indeed
missing from typefindfunctions in gst-plugins-base then it would be
better to add it there directly.

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3378

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6505>
This commit is contained in:
Sebastian Dröge 2024-04-02 10:17:56 +03:00 committed by GStreamer Marge Bot
parent 1c238aaa37
commit 9d465d9e68

View file

@ -1372,63 +1372,6 @@ beach:
} }
} }
#define GST_FFMPEG_TYPE_FIND_SIZE 4096
#define GST_FFMPEG_TYPE_FIND_MIN_SIZE 256
static void
gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
{
const guint8 *data;
AVInputFormat *in_plugin = (AVInputFormat *) priv;
gint res = 0;
guint64 length;
GstCaps *sinkcaps;
/* We want GST_FFMPEG_TYPE_FIND_SIZE bytes, but if the file is shorter than
* that we'll give it a try... */
length = gst_type_find_get_length (tf);
if (length == 0 || length > GST_FFMPEG_TYPE_FIND_SIZE)
length = GST_FFMPEG_TYPE_FIND_SIZE;
/* The ffmpeg typefinders assume there's a certain minimum amount of data
* and will happily do invalid memory access if there isn't, so let's just
* skip the ffmpeg typefinders if the data available is too short
* (in which case it's unlikely to be a media file anyway) */
if (length < GST_FFMPEG_TYPE_FIND_MIN_SIZE) {
GST_LOG ("not typefinding %" G_GUINT64_FORMAT " bytes, too short", length);
return;
}
GST_LOG ("typefinding %" G_GUINT64_FORMAT " bytes", length);
if (in_plugin->read_probe &&
(data = gst_type_find_peek (tf, 0, length)) != NULL) {
AVProbeData probe_data;
probe_data.filename = "";
probe_data.buf = (guint8 *) data;
probe_data.buf_size = length;
res = in_plugin->read_probe (&probe_data);
if (res > 0) {
res = MAX (1, res * GST_TYPE_FIND_MAXIMUM / AVPROBE_SCORE_MAX);
/* Restrict the probability for MPEG-TS streams, because there is
* probably a better version in plugins-base, if the user has a recent
* plugins-base (in fact we shouldn't even get here for ffmpeg mpegts or
* mpegtsraw typefinders, since we blacklist them) */
if (g_str_has_prefix (in_plugin->name, "mpegts"))
res = MIN (res, GST_TYPE_FIND_POSSIBLE);
sinkcaps = gst_ffmpeg_formatid_to_caps (in_plugin->name);
GST_LOG ("libav typefinder '%s' suggests %" GST_PTR_FORMAT ", p=%u%%",
in_plugin->name, sinkcaps, res);
gst_type_find_suggest (tf, res, sinkcaps);
gst_caps_unref (sinkcaps);
}
}
}
/* Task */ /* Task */
static void static void
gst_ffmpegdemux_loop (GstFFMpegDemux * demux) gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
@ -2055,7 +1998,6 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
while ((in_plugin = av_demuxer_iterate (&i))) { while ((in_plugin = av_demuxer_iterate (&i))) {
gchar *type_name, *typefind_name; gchar *type_name, *typefind_name;
gint rank; gint rank;
gboolean register_typefind_func = TRUE;
GST_LOG ("Attempting to handle libav demuxer plugin %s [%s]", GST_LOG ("Attempting to handle libav demuxer plugin %s [%s]",
in_plugin->name, in_plugin->long_name); in_plugin->name, in_plugin->long_name);
@ -2102,42 +2044,6 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
!strcmp (in_plugin->name, "ffmetadata")) !strcmp (in_plugin->name, "ffmetadata"))
continue; continue;
/* Don't use the typefind functions of formats for which we already have
* better typefind functions */
if (!strcmp (in_plugin->name, "mov,mp4,m4a,3gp,3g2,mj2") ||
!strcmp (in_plugin->name, "ass") ||
!strcmp (in_plugin->name, "avi") ||
!strcmp (in_plugin->name, "asf") ||
!strcmp (in_plugin->name, "mpegvideo") ||
!strcmp (in_plugin->name, "mp3") ||
!strcmp (in_plugin->name, "matroska") ||
!strcmp (in_plugin->name, "matroska_webm") ||
!strcmp (in_plugin->name, "matroska,webm") ||
!strcmp (in_plugin->name, "mpeg") ||
!strcmp (in_plugin->name, "wav") ||
!strcmp (in_plugin->name, "au") ||
!strcmp (in_plugin->name, "tta") ||
!strcmp (in_plugin->name, "rm") ||
!strcmp (in_plugin->name, "amr") ||
!strcmp (in_plugin->name, "ogg") ||
!strcmp (in_plugin->name, "aiff") ||
!strcmp (in_plugin->name, "ape") ||
!strcmp (in_plugin->name, "dv") ||
!strcmp (in_plugin->name, "flv") ||
!strcmp (in_plugin->name, "mpc") ||
!strcmp (in_plugin->name, "mpc8") ||
!strcmp (in_plugin->name, "mpegts") ||
!strcmp (in_plugin->name, "mpegtsraw") ||
!strcmp (in_plugin->name, "mxf") ||
!strcmp (in_plugin->name, "nuv") ||
!strcmp (in_plugin->name, "swf") ||
!strcmp (in_plugin->name, "voc") ||
!strcmp (in_plugin->name, "pva") ||
!strcmp (in_plugin->name, "gif") ||
!strcmp (in_plugin->name, "vc1test") ||
!strcmp (in_plugin->name, "ivf"))
register_typefind_func = FALSE;
/* Set the rank of demuxers known to work to MARGINAL. /* Set the rank of demuxers known to work to MARGINAL.
* Set demuxers for which we already have another implementation to NONE * Set demuxers for which we already have another implementation to NONE
* Set All others to NONE*/ * Set All others to NONE*/
@ -2214,11 +2120,7 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
else else
extensions = NULL; extensions = NULL;
if (!gst_element_register (plugin, type_name, rank, type) || if (!gst_element_register (plugin, type_name, rank, type)) {
(register_typefind_func == TRUE &&
!gst_type_find_register (plugin, typefind_name, rank,
gst_ffmpegdemux_type_find, extensions, NULL,
(gpointer) in_plugin, NULL))) {
g_warning ("Registration of type %s failed", type_name); g_warning ("Registration of type %s failed", type_name);
g_free (type_name); g_free (type_name);
g_free (typefind_name); g_free (typefind_name);