Projects
Essentials
gstreamer-plugins-ugly-codecs
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 39
View file
fix-build-new-faac.patch
Added
@@ -0,0 +1,370 @@ +From 5ebde10b2c5d647fe1902d590250661bbcd0e062 Mon Sep 17 00:00:00 2001 +From: Daeho Ro <email@daeho.ro> +Date: Mon, 20 Jul 2026 20:50:06 +0900 +Subject: PATCH 1/3 faac: support faac >= 2.0 (faac_* API) + +faac 2.0 removed the legacy faacEnc* API and bumped the library SONAME +to 1. Detect the new API via FAAC_VERSION_MAJOR and use it when +available, keeping the faacEnc* path for faac 1.x. + +With the new API the pad templates only offer the lc profile: faac 2.0 +dropped the MAIN/SSR/LTP object types, which were never actually +implemented by libfaac. The AudioSpecificConfig buffer is library-owned +in the new API and must not be freed. The meson header check now accepts +either faacEncOpen (1.x) or faac_encoder_open (2.0). + +Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12148> +--- + .../gst-plugins-bad/ext/faac/gstfaac.c | 137 +++++++++++++++++- + .../gst-plugins-bad/ext/faac/gstfaac.h | 9 ++ + .../gst-plugins-bad/ext/faac/meson.build | 2 +- + 3 files changed, 145 insertions(+), 3 deletions(-) + +diff --git a/subprojects/gst-plugins-bad/ext/faac/gstfaac.c b/subprojects/gst-plugins-bad/ext/faac/gstfaac.c +index 93f07a29250..8ff8567016e 100644 +--- a/subprojects/gst-plugins-bad/ext/faac/gstfaac.c ++++ b/subprojects/gst-plugins-bad/ext/faac/gstfaac.c +@@ -43,6 +43,39 @@ + + #include "gstfaac.h" + ++#if FAAC_VERSION_MAJOR >= 1 ++/* Legacy constant names for the faac >= 2.0 enums (same numeric values); ++ * MAIN/SSR/LTP only remain so the mpegversion=2 profile switch compiles. */ ++#define MAIN 1 ++#define LOW FAAC_OBJ_LOW ++#define SSR 3 ++#define LTP 4 ++#define MPEG4 FAAC_MPEG4 ++#define MPEG2 FAAC_MPEG2 ++#define SHORTCTL_NORMAL FAAC_SHORTCTL_NORMAL ++#define SHORTCTL_NOSHORT FAAC_SHORTCTL_NOSHORT ++#define SHORTCTL_NOLONG FAAC_SHORTCTL_NOLONG ++ ++/* Minimal wrappers keeping the faacEnc* call shape used below */ ++static int ++faacEncEncode (faac_encoder * handle, gint32 * input, unsigned int samples, ++ unsigned char *output, unsigned int output_size) ++{ ++ guint32 bytes_written = 0; ++ ++ if (faac_encoder_encode (handle, input, samples, output, output_size, ++ &bytes_written) < 0) ++ return -1; ++ return bytes_written; ++} ++ ++static void ++faacEncClose (faac_encoder * handle) ++{ ++ faac_encoder_close (&handle); ++} ++#endif /* FAAC_VERSION_MAJOR >= 1 */ ++ + #define SAMPLE_RATES " 8000, " \ + "11025, " \ + "12000, " \ +@@ -70,20 +103,28 @@ + "width = (int) 32, " + "rate = (int) 8000, 96000, " "channels = (int) 1, 6" + #endif ++#if FAAC_VERSION_MAJOR >= 1 ++/* faac >= 2.0 only implements the LC object type */ ++#define MPEG4_PROFILES "lc" ++#define MPEG2_PROFILES "lc" ++#else ++#define MPEG4_PROFILES "{ main, lc, ssr, ltp }" ++#define MPEG2_PROFILES "{ main, lc }" ++#endif + #define SRC_CAPS \ + "audio/mpeg, " \ + "mpegversion = (int) 4, " \ + "channels = (int) 1, 6 , " \ + "rate = (int) {" SAMPLE_RATES "}, " \ + "stream-format = (string) { adts, raw }, " \ +- "base-profile = (string) { main, lc, ssr, ltp }, " \ ++ "base-profile = (string) " MPEG4_PROFILES ", " \ + "framed = (boolean) true; " \ + "audio/mpeg, " \ + "mpegversion = (int) 2, " \ + "channels = (int) 1, 6 , " \ + "rate = (int) {" SAMPLE_RATES "}, " \ + "stream-format = (string) { adts, raw }, " \ +- "profile = (string) { main, lc }," \ ++ "profile = (string) " MPEG2_PROFILES "," \ + "framed = (boolean) true; " + static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, +@@ -466,6 +507,78 @@ gst_faac_negotiate (GstFaac * faac) + static gboolean + gst_faac_open_encoder (GstFaac * faac, GstAudioInfo * info) + { ++#if FAAC_VERSION_MAJOR >= 1 ++ faac_encoder *handle = NULL; ++ faac_params params; ++ faac_encoder_info enc_info; ++ guint maxbitrate; ++ ++ g_return_val_if_fail (info->rate != 0 && info->channels != 0, FALSE); ++ ++ /* clean up in case of re-configure */ ++ gst_faac_close_encoder (faac); ++ ++ if (faac_params_init (¶ms) < 0) ++ goto setup_failed; ++ ++ params.sample_rate = info->rate; ++ params.num_channels = info->channels; ++ params.mpeg_version = (faac->mpegversion == 4) ? FAAC_MPEG4 : FAAC_MPEG2; ++ params.object_type = FAAC_OBJ_LOW; ++ params.joint_mode = faac->midside ? FAAC_JOINT_MS : FAAC_JOINT_NONE; ++ params.use_lfe = FALSE; ++ params.use_tns = faac->tns; ++ params.input_format = (enum faac_input_format) faac->format; ++ params.output_format = ++ faac->outputformat ? FAAC_STREAM_ADTS : FAAC_STREAM_RAW; ++ params.short_control = (enum faac_shortctl_mode) faac->shortctl; ++ /* default 0 to start with, libfaac chooses based on bitrate */ ++ params.bandwidth = 0; ++ ++ if (faac->brtype == VBR) { ++ params.bit_rate = 0; ++ params.quant_quality = faac->quality; ++ } else if (faac->brtype == ABR) { ++ params.bit_rate = faac->bitrate / info->channels; ++ params.quant_quality = 0; ++ ++ /* check, warn and correct if the max bitrate for the given samplerate is ++ * exceeded. Maximum of 6144 bit for a channel */ ++ maxbitrate = ++ (unsigned int) (6144.0 * (double) info->rate / (double) 1024.0 + .5); ++ if (params.bit_rate > maxbitrate) { ++ GST_ELEMENT_WARNING (faac, RESOURCE, SETTINGS, (NULL), ++ ("bitrate %u exceeds maximum allowed bitrate of %u for samplerate %d. " ++ "Setting bitrate to %u", params.bit_rate, maxbitrate, ++ info->rate, maxbitrate)); ++ params.bit_rate = maxbitrate; ++ } ++ } ++ ++ if (faac_encoder_open (¶ms, &handle) < 0) ++ goto setup_failed; ++ ++ faac->handle = handle; ++ ++ enc_info.struct_size = sizeof (enc_info); ++ if (faac_encoder_get_info (handle, &enc_info) < 0) ++ goto setup_failed; ++ ++ faac->samples = enc_info.frame_samples; ++ faac->bytes = enc_info.max_output_bytes; ++ ++ GST_DEBUG_OBJECT (faac, "faac needs samples %d, output size %d", ++ faac->samples, faac->bytes); ++ ++ /* let's see what really happened, ++ * note that this may not really match desired rate */ ++ GST_DEBUG_OBJECT (faac, "average bitrate: %u kbps", ++ (enc_info.bit_rate + 500) / 1000 * info->channels); ++ GST_DEBUG_OBJECT (faac, "quantization quality: %u", enc_info.quant_quality); ++ GST_DEBUG_OBJECT (faac, "bandwidth: %u Hz", enc_info.bandwidth); ++ ++ return TRUE; ++#else + faacEncHandle *handle; + faacEncConfiguration *conf; + guint maxbitrate; +@@ -534,6 +647,7 @@ gst_faac_open_encoder (GstFaac * faac, GstAudioInfo * info) + GST_DEBUG_OBJECT (faac, "bandwidth: %d Hz", conf->bandWidth); + + return TRUE; ++#endif /* FAAC_VERSION_MAJOR >= 1 */ + + /* ERRORS */ + setup_failed: +@@ -570,11 +684,28 @@ gst_faac_configure_source_pad (GstFaac * faac, GstAudioInfo * info) + + /* get the config string */ + GST_DEBUG_OBJECT (faac, "retrieving decoder info"); ++#if FAAC_VERSION_MAJOR >= 1 ++ { ++ /* library-owned buffer, valid until close; must not be freed */ ++ const guint8 *asc = NULL; ++ guint32 asc_len = 0; ++ ++ if (faac_encoder_asc (faac->handle, &asc, &asc_len) < 0) { ++ gst_caps_unref (srccaps); ++ goto invalid_codec_data; ++ } ++ config = (guint8 *) asc; ++ config_len = asc_len; ++ } ++#else + faacEncGetDecoderSpecificInfo (faac->handle, &config, &config_len); ++#endif + + if (!gst_codec_utils_aac_caps_set_level_and_profile (srccaps, config, + config_len)) { ++#if FAAC_VERSION_MAJOR < 1 + free (config); ++#endif + gst_caps_unref (srccaps); + goto invalid_codec_data; + } +@@ -593,7 +724,9 @@ gst_faac_configure_source_pad (GstFaac * faac, GstAudioInfo * info) + gst_buffer_unref (codec_data); + } + ++#if FAAC_VERSION_MAJOR < 1 + free (config); ++#endif + } else { + const gchar *profile; + +diff --git a/subprojects/gst-plugins-bad/ext/faac/gstfaac.h b/subprojects/gst-plugins-bad/ext/faac/gstfaac.h +index 83a31775ef7..d9d270bd56a 100644 +--- a/subprojects/gst-plugins-bad/ext/faac/gstfaac.h ++++ b/subprojects/gst-plugins-bad/ext/faac/gstfaac.h +@@ -25,6 +25,11 @@ + + #include <faac.h> + ++/* faac < 2.0 (legacy faacEnc* API) does not define version macros */ ++#ifndef FAAC_VERSION_MAJOR ++#define FAAC_VERSION_MAJOR 0 ++#endif ++ + G_BEGIN_DECLS + + #define GST_TYPE_FAAC \ +@@ -64,7 +69,11 @@ struct _GstFaac { + midside; + + /* FAAC object */ ++#if FAAC_VERSION_MAJOR >= 1 ++ faac_encoder *handle; ++#else + faacEncHandle handle; ++#endif + }; + + struct _GstFaacClass { +diff --git a/subprojects/gst-plugins-bad/ext/faac/meson.build b/subprojects/gst-plugins-bad/ext/faac/meson.build +index cd689416eb9..eaf1e431d47 100644 +--- a/subprojects/gst-plugins-bad/ext/faac/meson.build ++++ b/subprojects/gst-plugins-bad/ext/faac/meson.build +@@ -16,7 +16,7 @@ plugin_sources += { + } + + faac_dep = cc.find_library('faac', required : get_option('faac')) +-have_faac_h = cc.has_header_symbol('faac.h', 'faacEncOpen') ++have_faac_h = cc.has_header_symbol('faac.h', 'faacEncOpen') or cc.has_header_symbol('faac.h', 'faac_encoder_open') + if not have_faac_h and get_option('faac').enabled() + error('faac plugin enabled: found libfaac, but not faac.h') + endif +-- +GitLab + + +From 48b5fd04e48763b36b13b73c7f29309a0778e64d Mon Sep 17 00:00:00 2001 +From: Daeho Ro <email@daeho.ro> +Date: Tue, 29 Sep 2026 21:36:28 +0900 +Subject: PATCH 2/3 faac: pass caller_size to faac_params_init() for faac >= + 2.2 + +faac 2.2 bumped FAAC_VERSION_MAJOR and the library SONAME to 2 and +added a caller_size argument to faac_params_init(). Pass sizeof(params) +when FAAC_VERSION_MAJOR >= 2 and keep the one-argument call for faac +2.0 and 2.1. + +Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12148> +--- + subprojects/gst-plugins-bad/ext/faac/gstfaac.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/subprojects/gst-plugins-bad/ext/faac/gstfaac.c b/subprojects/gst-plugins-bad/ext/faac/gstfaac.c +index 8ff8567016e..335133a2087 100644 +--- a/subprojects/gst-plugins-bad/ext/faac/gstfaac.c ++++ b/subprojects/gst-plugins-bad/ext/faac/gstfaac.c +@@ -518,7 +518,11 @@ gst_faac_open_encoder (GstFaac * faac, GstAudioInfo * info) + /* clean up in case of re-configure */ + gst_faac_close_encoder (faac); + ++#if FAAC_VERSION_MAJOR >= 2 ++ if (faac_params_init (¶ms, sizeof (params)) < 0) ++#else + if (faac_params_init (¶ms) < 0) ++#endif + goto setup_failed; + + params.sample_rate = info->rate; +-- +GitLab + + +From df96015dda9ce6ab90b0e617b4d7ce3ca7b48abd Mon Sep 17 00:00:00 2001 +From: Daeho Ro <email@daeho.ro> +Date: Sun, 4 Oct 2026 16:42:25 +0900 +Subject: PATCH 3/3 faac: detect libfaac via pkg-config first + +faac has installed a faac.pc since 1.31. Use it when available and only +fall back to the faac.h symbol check plus cc.find_library() for older +releases without one. Like other plugins, skip all dependency checks +when the plugin is disabled. + +Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/12148> +--- + subprojects/gst-plugins-bad/ext/faac/gstfaac.h | 6 +++++- + .../gst-plugins-bad/ext/faac/meson.build | 17 ++++++++++++----- + 2 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/subprojects/gst-plugins-bad/ext/faac/gstfaac.h b/subprojects/gst-plugins-bad/ext/faac/gstfaac.h +index d9d270bd56a..7a0afa592e6 100644 +--- a/subprojects/gst-plugins-bad/ext/faac/gstfaac.h ++++ b/subprojects/gst-plugins-bad/ext/faac/gstfaac.h +@@ -25,7 +25,11 @@ + + #include <faac.h> + +-/* faac < 2.0 (legacy faacEnc* API) does not define version macros */ ++/* FAAC_VERSION_MAJOR is the faac API version, not the release version: ++ * faac < 2.0: not defined (legacy faacEnc* API), treated as 0 ++ * faac 2.0 - 2.1: 1 (faac_* API) ++ * faac >= 2.2: 2 (faac_params_init() takes a caller_size argument) ++ */ + #ifndef FAAC_VERSION_MAJOR + #define FAAC_VERSION_MAJOR 0 + #endif +diff --git a/subprojects/gst-plugins-bad/ext/faac/meson.build b/subprojects/gst-plugins-bad/ext/faac/meson.build +index eaf1e431d47..f91a906a8de 100644 +--- a/subprojects/gst-plugins-bad/ext/faac/meson.build ++++ b/subprojects/gst-plugins-bad/ext/faac/meson.build +@@ -15,13 +15,20 @@ plugin_sources += { + 'faac': pathsep.join(doc_sources) + } + +-faac_dep = cc.find_library('faac', required : get_option('faac')) +-have_faac_h = cc.has_header_symbol('faac.h', 'faacEncOpen') or cc.has_header_symbol('faac.h', 'faac_encoder_open') +-if not have_faac_h and get_option('faac').enabled() +- error('faac plugin enabled: found libfaac, but not faac.h') ++if get_option('faac').disabled() ++ subdir_done() + endif + +-if faac_dep.found() and have_faac_h ++# faac >= 1.31 ships a pkg-config file, so try that first ++faac_dep = dependency('faac', required : false) ++if not faac_dep.found() and (cc.has_header_symbol('faac.h', 'faacEncOpen') or cc.has_header_symbol('faac.h', 'faac_encoder_open')) ++ faac_dep = cc.find_library('faac', required : false) ++endif ++if not faac_dep.found() and get_option('faac').enabled() ++ error('faac plugin enabled, but libfaac not found') ++endif ++ ++if faac_dep.found() + gstfaac = library('gstfaac', + faac_sources, + c_args : gst_plugins_bad_args, +-- +GitLab +
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.