From c77f88cac675a1dbb89e40da8e3c28320523bfca Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Fri, 30 Apr 2010 13:41:17 +0530 Subject: [PATCH] pbutils: add codec-specific utility functions for AAC This allows us to add generic codec-specific functionality, like extracting profile/level data from headers, without having to duplicate code across demuxers and typefindfunctions. As a starting point, this moves over AAC level extraction code from typefindfunctions, so it can be reused in qtdemux, etc. https://bugzilla.gnome.org/show_bug.cgi?id=617314 API: gst_codec_utils_aac_get_sample_rate_from_index() API: gst_codec_utils_aac_get_level() --- gst-libs/gst/pbutils/Makefile.am | 2 + gst-libs/gst/pbutils/codec-utils.c | 278 ++++++++++++++++++ .../gst/pbutils/codec-utils.h | 35 ++- gst-libs/gst/pbutils/pbutils.h | 1 + gst/typefind/Makefile.am | 13 +- gst/typefind/gstaacutil.c | 176 ----------- gst/typefind/gsttypefindfunctions.c | 27 +- win32/common/libgstpbutils.def | 3 + 8 files changed, 320 insertions(+), 215 deletions(-) create mode 100644 gst-libs/gst/pbutils/codec-utils.c rename gst/typefind/gstaacutil.h => gst-libs/gst/pbutils/codec-utils.h (53%) delete mode 100644 gst/typefind/gstaacutil.c diff --git a/gst-libs/gst/pbutils/Makefile.am b/gst-libs/gst/pbutils/Makefile.am index 60ab464bf1..1d3d092ea8 100644 --- a/gst-libs/gst/pbutils/Makefile.am +++ b/gst-libs/gst/pbutils/Makefile.am @@ -2,6 +2,7 @@ lib_LTLIBRARIES = libgstpbutils-@GST_MAJORMINOR@.la headers_pbutils = \ pbutils.h \ + codec-utils.h \ descriptions.h \ install-plugins.h \ missing-plugins.h \ @@ -27,6 +28,7 @@ built_headers_configure = \ libgstpbutils_@GST_MAJORMINOR@_la_SOURCES = \ gstpluginsbaseversion.c \ pbutils.c \ + codec-utils.c \ descriptions.c \ install-plugins.c \ missing-plugins.c \ diff --git a/gst-libs/gst/pbutils/codec-utils.c b/gst-libs/gst/pbutils/codec-utils.c new file mode 100644 index 0000000000..18d91b6889 --- /dev/null +++ b/gst-libs/gst/pbutils/codec-utils.c @@ -0,0 +1,278 @@ +/* GStreamer base utils library codec-specific utility functions + * Copyright (C) 2010 Arun Raghavan + * 2010 Collabora Multimedia + * 2010 Nokia Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:gstpbutilscodecutils + * @short_description: Miscellaneous codec-specific utility functions + * + * + * + * Provides numerous codec-specific ulility functions such as functions to + * provide the codec profile and level in human-readable string form from + * header data. + * + * + */ + +#include "pbutils.h" + +/** + * gst_codec_utils_aac_get_sample_rate_from_index: + * @sr_idx: Sample rate index as from the AudioSpecificConfig (MPEG-4 + * container) or ADTS frame header + * + * Translates the sample rate index found in AAC headers to the actual sample + * rate. + * + * Returns: The sample rate if @sr_idx is valid, 0 otherwise. + */ +guint +gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx) +{ + static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100, + 32000, 24000, 22050, 16000, 12000, 11025, 8000 + }; + + if (G_LIKELY (sr_idx < G_N_ELEMENTS (aac_sample_rates))) + return aac_sample_rates[sr_idx]; + + GST_WARNING ("Invalid sample rate index %u", sr_idx); + return 0; +} + +/** + * gst_codec_utils_aac_get_level: + * @audio_config: a pointer to the AudioSpecificConfig as specified in the + * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see + * below for a more detailed description). + * @len: Length of @audio_config in bytes + * + * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC + * streams, the constraints from the AAC audio profile are applied. For AAC + * Main, LTP, SSR and others, the Main profile is used. + * + * The @audio_config parameter follows the following format, starting from the + * most significant bit of the first byte: + * + * Bit 0:4 contains the AudioObjectType + * Bit 5:8 contains the sample frequency index (if this is 0xf, then the next + * 24 bits define the actual sample frequency, and subsequent fields + * are appropriately shifted). + * Bit 9:12 contains the channel configuration + * + * + * HE-AAC support has not yet been implemented. + * + * + * Returns: The level as a const string and NULL if the level could not be + * determined. + */ +const gchar * +gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len) +{ + int profile, sr_idx, channel_config, rate; + /* Number of single channel elements, channel pair elements, low frequency + * elements, independently switched coupling channel elements, and + * dependently switched coupling channel elements. + * + * Note: The 2 CCE types are ignored for now as they require us to actually + * parse the first frame, and they are rarely found in actual streams. + */ + int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0; + int num_channels; + /* Processor and RAM Complexity Units (calculated and "reference" for single + * channel) */ + int pcu, rcu, pcu_ref, rcu_ref; + int ret = -1; + + g_return_val_if_fail (audio_config != NULL, NULL); + + if (len < 2) + return NULL; + + profile = audio_config[0] >> 3; + /* FIXME: add support for sr_idx = 0xf */ + sr_idx = ((audio_config[0] & 0x7) << 1) | ((audio_config[1] & 0x80) >> 7); + rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx); + channel_config = (audio_config[1] & 0x7f) >> 3; + + if (rate == 0) + return NULL; + + switch (channel_config) { + case 0: + /* Channel config is defined in the AudioObjectType's SpecificConfig, + * which requires some amount of digging through the headers. I only see + * this done in the MPEG conformance streams - FIXME */ + GST_WARNING ("Found a stream with channel configuration in the " + "AudioSpecificConfig. Please file a bug with a link to the media if " + "possible."); + return NULL; + case 1: + /* front center */ + num_sce = 1; + break; + case 2: + /* front left and right */ + num_cpe = 1; + break; + case 3: + /* front left, right, and center */ + num_sce = 1; + num_cpe = 1; + break; + case 4: + /* front left, right, and center; rear surround */ + num_sce = 2; + num_cpe = 1; + break; + case 5: + /* front left, right, and center; rear left and right surround */ + num_sce = 1; + num_cpe = 2; + break; + case 6: + /* front left, right, center and LFE; rear left and right surround */ + num_sce = 1; + num_cpe = 2; + break; + case 7: + /* front left, right, center and LFE; outside front left and right; + * rear left and right surround */ + num_sce = 1; + num_cpe = 3; + num_lfe = 1; + break; + default: + GST_WARNING ("Unknown channel config in header: %d", channel_config); + return NULL; + } + + switch (profile) { + case 0: /* NULL */ + GST_WARNING ("profile 0 is not a valid profile"); + return NULL; + case 2: /* LC */ + pcu_ref = 3; + rcu_ref = 3; + break; + case 3: /* SSR */ + pcu_ref = 4; + rcu_ref = 3; + break; + case 4: /* LTP */ + pcu_ref = 4; + rcu_ref = 4; + break; + case 1: /* Main */ + default: + /* Other than a couple of ER profiles, Main is the worst-case */ + pcu_ref = 5; + rcu_ref = 5; + break; + } + + /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as + * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */ + + pcu = ((float) rate / 48000) * pcu_ref * + ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep)); + + rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) + + (0.4 * num_cce_dep)); + + if (num_cpe < 2) + rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe; + else + rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1)); + + num_channels = num_sce + (2 * num_cpe) + num_lfe; + + if (profile == 2) { + /* AAC LC => return the level as per the 'AAC Profile' */ + if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5) + ret = 1; + else if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5) + ret = 2; + /* There is no level 3 for the AAC Profile */ + else if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15) + ret = 4; + else if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15) + ret = 5; + } else { + /* Return the level as per the 'Main Profile' */ + if (pcu < 40 && rcu < 20) + ret = 1; + else if (pcu < 80 && rcu < 64) + ret = 2; + else if (pcu < 160 && rcu < 128) + ret = 3; + else if (pcu < 320 && rcu < 256) + ret = 4; + } + + if (ret == -1) { + GST_WARNING ("couldn't determine level: profile=%u, rate=%u, " + "channel_config=%u, pcu=%d,rcu=%d", profile, rate, channel_config, pcu, + rcu); + return NULL; + } else { + /* For fast and convenient int -> string conversion */ + static const char itoa[][2] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" + }; + + g_assert (ret < G_N_ELEMENTS (itoa)); + return itoa[ret]; + } +} + +/** + * gst_codec_utils_aac_caps_set_level: + * @caps: the #GstCaps to which the level is to be added + * @audio_config: a pointer to the AudioSpecificConfig as specified in the + * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see + * below for a more details). + * @len: Length of @audio_config in bytes + * + * Sets the level in @caps if it can be determined from @audio_config. See + * #gst_codec_utils_aac_get_level() for more details on the parameters. + * + * Returns: TRUE if the level could be set, FALSE otherwise. + */ +gboolean +gst_codec_utils_aac_caps_set_level (GstCaps * caps, + const guint8 * audio_config, guint len) +{ + const gchar *level; + + g_return_val_if_fail (GST_IS_CAPS (caps), FALSE); + g_return_val_if_fail (audio_config != NULL, FALSE); + + level = gst_codec_utils_aac_get_level (audio_config, len); + + if (!level) + return FALSE; + + gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL); + + return TRUE; +} diff --git a/gst/typefind/gstaacutil.h b/gst-libs/gst/pbutils/codec-utils.h similarity index 53% rename from gst/typefind/gstaacutil.h rename to gst-libs/gst/pbutils/codec-utils.h index 4fe5a58cd9..0b54da28cc 100644 --- a/gst/typefind/gstaacutil.h +++ b/gst-libs/gst/pbutils/codec-utils.h @@ -1,9 +1,7 @@ -/* GStreamer - * Copyright (C) 2010 Nokia Corporation - * Copyright (C) 2010 Collabora Multimedia +/* GStreamer base utils library codec-specific utility functions * Copyright (C) 2010 Arun Raghavan - * - * gstaacutil.h: collection of AAC helper utilities + * 2010 Collabora Multimedia + * 2010 Nokia Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,23 +19,24 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_AAC_UTIL_H__ -#define __GST_AAC_UTIL_H__ +#ifndef __GST_PB_UTILS_CODEC_UTILS_H__ +#define __GST_PB_UTILS_CODEC_UTILS_H__ -#include - -/* FIXME: This file is duplicated in gst-plugins-* wherever needed, so if you - * update this file, please find all other instances and update them as well. - * This less-than-optimal setup is being used till there is a standard location - * for such common functionality. - */ +#include G_BEGIN_DECLS -gint gst_aac_level_from_header (guint profile, - guint sample_freq_idx, - guint channel_config); +/* AAC */ + +guint gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx); + +const gchar * gst_codec_utils_aac_get_level (const guint8 * audio_config, + guint len); + +gboolean gst_codec_utils_aac_caps_set_level (GstCaps * caps, + const guint8 * audio_config, + guint len); G_END_DECLS -#endif /* __GST_AAC_UTIL_H__*/ +#endif /* __GST_PB_UTILS_CODEC_UTILS_H__ */ diff --git a/gst-libs/gst/pbutils/pbutils.h b/gst-libs/gst/pbutils/pbutils.h index 1e401b5622..5fabf010ce 100644 --- a/gst-libs/gst/pbutils/pbutils.h +++ b/gst-libs/gst/pbutils/pbutils.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/gst/typefind/Makefile.am b/gst/typefind/Makefile.am index b5d57668f4..cf9e59e049 100644 --- a/gst/typefind/Makefile.am +++ b/gst/typefind/Makefile.am @@ -1,9 +1,12 @@ plugin_LTLIBRARIES = libgsttypefindfunctions.la -libgsttypefindfunctions_la_SOURCES = gsttypefindfunctions.c gstaacutil.c -libgsttypefindfunctions_la_CFLAGS = $(GST_CFLAGS) $(GIO_CFLAGS) +libgsttypefindfunctions_la_SOURCES = gsttypefindfunctions.c +libgsttypefindfunctions_la_CFLAGS = \ + $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_CFLAGS) $(GIO_CFLAGS) libgsttypefindfunctions_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgsttypefindfunctions_la_LIBADD = $(GST_LIBS) $(GIO_LIBS) -libgsttypefindfunctions_la_LIBTOOLFLAGS = --tag=disable-static +libgsttypefindfunctions_la_LIBADD = \ + $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la \ + $(GST_LIBS) $(GIO_LIBS) -noinst_HEADERS = gstaacutil.h +libgsttypefindfunctions_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/gst/typefind/gstaacutil.c b/gst/typefind/gstaacutil.c deleted file mode 100644 index 229b078841..0000000000 --- a/gst/typefind/gstaacutil.c +++ /dev/null @@ -1,176 +0,0 @@ -/* GStreamer - * Copyright (C) 2010 Nokia Corporation - * Copyright (C) 2010 Collabora Multimedia - * Copyright (C) 2010 Arun Raghavan - * - * gstaacutil.c: collection of AAC helper utilities - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include - -#include "gstaacutil.h" - -/* FIXME: This file is duplicated in gst-plugins-* wherever needed, so if you - * update this file, please find all other instances and update them as well. - * This less-than-optimal setup is being used till there is a standard location - * for such common functionality. - */ - -/* Determines the level of a stream as defined in ISO/IEC 14496-3. The - * sample_frequency_index and channel_configuration must be got from the ESDS - * for MP4 files and the ADTS header for ADTS streams. - * - * For AAC LC streams, we assume that apply the constraints from the AAC audio - * profile. For AAC Main/LTP/SSR/..., we use the Main profile. - * - * FIXME: HE-AAC support is TBD. - * - * Returns -1 if the level could not be determined. - */ -gint -gst_aac_level_from_header (guint profile, guint rate, guint channel_config) -{ - /* Number of single channel elements, channel pair elements, low frequency - * elements, independently switched coupling channel elements, and - * dependently switched coupling channel elements. - * - * Note: The 2 CCE types are ignored for now as they require us to actually - * parse the first frame, and they are rarely found in actual streams. - */ - int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0; - int num_channels; - /* Processor and RAM Complexity Units (calculated and "reference" for single - * channel) */ - int pcu, rcu, pcu_ref, rcu_ref; - - switch (channel_config) { - case 0: - /* Channel config is defined in the AudioObjectType's SpecificConfig, - * which requires some amount of digging through the headers. I only see - * this done in the MPEG conformance streams - FIXME */ - GST_WARNING ("Found a stream with channel configuration in the " - "AudioSpecificConfig. Please file a bug with a link to the media if " - "possible."); - return -1; - case 1: - /* front center */ - num_sce = 1; - break; - case 2: - /* front left and right */ - num_cpe = 1; - break; - case 3: - /* front left, right, and center */ - num_sce = 1; - num_cpe = 1; - break; - case 4: - /* front left, right, and center; rear surround */ - num_sce = 2; - num_cpe = 1; - break; - case 5: - /* front left, right, and center; rear left and right surround */ - num_sce = 1; - num_cpe = 2; - break; - case 6: - /* front left, right, center and LFE; rear left and right surround */ - num_sce = 1; - num_cpe = 2; - break; - case 7: - /* front left, right, center and LFE; outside front left and right; - * rear left and right surround */ - num_sce = 1; - num_cpe = 3; - num_lfe = 1; - break; - default: - GST_WARNING ("Unknown channel config in header: %d", channel_config); - return -1; - } - - switch (profile) { - case 0: /* NULL */ - GST_WARNING ("profile 0 is not a valid profile"); - return -1; - case 2: /* LC */ - pcu_ref = 3; - rcu_ref = 3; - break; - case 3: /* SSR */ - pcu_ref = 4; - rcu_ref = 3; - break; - case 4: /* LTP */ - pcu_ref = 4; - rcu_ref = 4; - break; - case 1: /* Main */ - default: - /* Other than a couple of ER profiles, Main is the worst-case */ - pcu_ref = 5; - rcu_ref = 5; - break; - } - - /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as - * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */ - - pcu = ((float) rate / 48000) * pcu_ref * - ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep)); - - rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) + - (0.4 * num_cce_dep)); - - if (num_cpe < 2) - rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe; - else - rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1)); - - num_channels = num_sce + (2 * num_cpe) + num_lfe; - - if (profile == 2) { - /* AAC LC => return the level as per the 'AAC Profile' */ - if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5) - return 1; - if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5) - return 2; - /* There is no level 3 for the AAC Profile */ - if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15) - return 4; - if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15) - return 5; - } else { - /* Return the level as per the 'Main Profile' */ - if (pcu < 40 && rcu < 20) - return 1; - if (pcu < 80 && rcu < 64) - return 2; - if (pcu < 160 && rcu < 128) - return 3; - if (pcu < 320 && rcu < 256) - return 4; - } - - GST_WARNING ("couldn't determine level: profile=%u,rate=%u,channel_config=%u," - "pcu=%d,rcu=%d", profile, rate, channel_config, pcu, rcu); - return -1; -} diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 05f8c8488d..d9a011ee3e 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -40,7 +40,7 @@ #include #include -#include "gstaacutil.h" +#include GST_DEBUG_CATEGORY_STATIC (type_find_debug); #define GST_CAT_DEFAULT type_find_debug @@ -661,9 +661,6 @@ aac_type_find (GstTypeFind * tf, gpointer unused) { /* LUT to convert the AudioObjectType from the ADTS header to a string */ static const gchar profile_to_string[][5] = { "main", "lc", "ssr", "ltp" }; - static const guint sample_freq[] = { 96000, 88200, 64000, 48000, 44100, - 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 - }; DataScanCtx c = { 0, NULL, 0 }; while (c.offset < AAC_AMOUNT) { @@ -697,7 +694,7 @@ aac_type_find (GstTypeFind * tf, gpointer unused) if ((snc & 0xfff6) == 0xfff0) { GstCaps *caps; guint mpegversion, sample_freq_idx, channel_config, profile, rate; - gint level; + guint8 audio_config[2]; mpegversion = (c.data[1] & 0x08) ? 2 : 4; profile = c.data[2] >> 6; @@ -715,11 +712,17 @@ aac_type_find (GstTypeFind * tf, gpointer unused) goto next; } - rate = sample_freq[sample_freq_idx]; + rate = gst_codec_utils_aac_get_sample_rate_from_index (sample_freq_idx); GST_LOG ("ADTS: profile=%u, rate=%u", profile, rate); + /* The ADTS frame header is slightly different from the + * AudioSpecificConfig defined for the MPEG-4 container, so we just + * construct enough of it for getting the level here. */ /* ADTS counts profiles from 0 instead of 1 to save bits */ - level = gst_aac_level_from_header (profile + 1, rate, channel_config); + audio_config[0] = (profile + 1) << 3; + audio_config[0] |= (sample_freq_idx >> 1) & 0x7; + audio_config[1] = (sample_freq_idx & 0x1) << 7; + audio_config[1] |= (channel_config & 0xf) << 3; caps = gst_caps_new_simple ("audio/mpeg", "framed", G_TYPE_BOOLEAN, FALSE, @@ -728,15 +731,7 @@ aac_type_find (GstTypeFind * tf, gpointer unused) "base-profile", G_TYPE_STRING, profile_to_string[profile], "profile", G_TYPE_STRING, profile_to_string[profile], NULL); - if (level != -1) { - gchar level_str[16]; - - /* we use a string here because h.264 levels are also strings and - * there aren't a lot of levels, so it's not too awkward to not use - * and integer here and keep the field type consistent with h.264 */ - g_snprintf (level_str, sizeof (level_str), "%d", level); - gst_caps_set_simple (caps, "level", G_TYPE_STRING, level_str, NULL); - } + gst_codec_utils_aac_caps_set_level (caps, audio_config, 2); /* add rate and number of channels if we can */ if (channel_config != 0 && channel_config <= 7) { diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def index c3435f4f56..87ce1279fc 100644 --- a/win32/common/libgstpbutils.def +++ b/win32/common/libgstpbutils.def @@ -1,4 +1,7 @@ EXPORTS + gst_codec_utils_aac_caps_set_level + gst_codec_utils_aac_get_level + gst_codec_utils_aac_get_sample_rate_from_index gst_discoverer_audio_info_get_bitrate gst_discoverer_audio_info_get_channels gst_discoverer_audio_info_get_depth