diff --git a/spa/include/spa/param/audio/ac3-utils.h b/spa/include/spa/param/audio/ac3-utils.h new file mode 100644 index 000000000..bfea5b563 --- /dev/null +++ b/spa/include/spa/param/audio/ac3-utils.h @@ -0,0 +1,69 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_AC3_UTILS_H +#define SPA_AUDIO_AC3_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include +#include +#include +#include + +#ifndef SPA_API_AUDIO_AC3_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_AUDIO_AC3_UTILS SPA_API_IMPL + #else + #define SPA_API_AUDIO_AC3_UTILS static inline + #endif +#endif + +SPA_API_AUDIO_AC3_UTILS int +spa_format_audio_ac3_parse(const struct spa_pod *format, struct spa_audio_info_ac3 *info) +{ + int res; + res = spa_pod_parse_object(format, + SPA_TYPE_OBJECT_Format, NULL, + SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels)); + return res; +} + +SPA_API_AUDIO_AC3_UTILS struct spa_pod * +spa_format_audio_ac3_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info_ac3 *info) +{ + struct spa_pod_frame f; + spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); + spa_pod_builder_add(builder, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_ac3), + SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_ENCODED), + 0); + if (info->rate != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info->rate), 0); + if (info->channels != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info->channels), 0); + return (struct spa_pod*)spa_pod_builder_pop(builder, &f); +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_AC3_UTILS_H */ diff --git a/spa/include/spa/param/audio/ac3.h b/spa/include/spa/param/audio/ac3.h new file mode 100644 index 000000000..cab27c3e3 --- /dev/null +++ b/spa/include/spa/param/audio/ac3.h @@ -0,0 +1,35 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_AC3_H +#define SPA_AUDIO_AC3_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \addtogroup spa_param + * \{ + */ + +/** Dolby AC-3 audio info. */ +struct spa_audio_info_ac3 { + uint32_t rate; /*< sample rate */ + uint32_t channels; /*< number of channels */ +}; + +#define SPA_AUDIO_INFO_AC3_INIT(...) ((struct spa_audio_info_ac3) { __VA_ARGS__ }) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_AC3_H */ diff --git a/spa/include/spa/param/audio/compressed.h b/spa/include/spa/param/audio/compressed.h index da8b81456..d61ba321e 100644 --- a/spa/include/spa/param/audio/compressed.h +++ b/spa/include/spa/param/audio/compressed.h @@ -7,13 +7,17 @@ #define SPA_AUDIO_COMPRESSED_H #include +#include #include #include #include +#include #include #include +#include #include #include +#include #include #include diff --git a/spa/include/spa/param/audio/dts-types.h b/spa/include/spa/param/audio/dts-types.h new file mode 100644 index 000000000..6cf999a1a --- /dev/null +++ b/spa/include/spa/param/audio/dts-types.h @@ -0,0 +1,39 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_DTS_TYPES_H +#define SPA_AUDIO_DTS_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \addtogroup spa_param + * \{ + */ + +#define SPA_TYPE_INFO_AudioDTSExtType SPA_TYPE_INFO_ENUM_BASE "AudioDTSExtType" +#define SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE SPA_TYPE_INFO_AudioDTSExtType ":" + +static const struct spa_type_info spa_type_audio_dts_ext_type[] = { + { SPA_AUDIO_DTS_EXT_UNKNOWN, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "UNKNOWN", NULL }, + { SPA_AUDIO_DTS_EXT_NONE, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "NONE", NULL }, + { SPA_AUDIO_DTS_EXT_HD_HRA, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "HRA", NULL }, + { SPA_AUDIO_DTS_EXT_HD_MA, SPA_TYPE_Int, SPA_TYPE_INFO_AUDIO_DTS_EXT_TYPE_BASE "MA", NULL }, + { 0, 0, NULL, NULL }, +}; + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_DTS_TYPES_H */ diff --git a/spa/include/spa/param/audio/dts-utils.h b/spa/include/spa/param/audio/dts-utils.h new file mode 100644 index 000000000..445c7e8fb --- /dev/null +++ b/spa/include/spa/param/audio/dts-utils.h @@ -0,0 +1,73 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_DTS_UTILS_H +#define SPA_AUDIO_DTS_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include +#include +#include +#include + +#ifndef SPA_API_AUDIO_DTS_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_AUDIO_DTS_UTILS SPA_API_IMPL + #else + #define SPA_API_AUDIO_DTS_UTILS static inline + #endif +#endif + +SPA_API_AUDIO_DTS_UTILS int +spa_format_audio_dts_parse(const struct spa_pod *format, struct spa_audio_info_dts *info) +{ + int res; + res = spa_pod_parse_object(format, + SPA_TYPE_OBJECT_Format, NULL, + SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels), + SPA_FORMAT_AUDIO_DTS_extType, SPA_POD_OPT_Id(&info->ext_type)); + return res; +} + +SPA_API_AUDIO_DTS_UTILS struct spa_pod * +spa_format_audio_dts_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info_dts *info) +{ + struct spa_pod_frame f; + spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); + spa_pod_builder_add(builder, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dts), + SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_ENCODED), + 0); + if (info->rate != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info->rate), 0); + if (info->channels != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info->channels), 0); + if (info->ext_type != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_DTS_extType, SPA_POD_Id(info->ext_type), 0); + return (struct spa_pod*)spa_pod_builder_pop(builder, &f); +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_DTS_UTILS_H */ diff --git a/spa/include/spa/param/audio/dts.h b/spa/include/spa/param/audio/dts.h new file mode 100644 index 000000000..fd7a4133c --- /dev/null +++ b/spa/include/spa/param/audio/dts.h @@ -0,0 +1,51 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_DTS_H +#define SPA_AUDIO_DTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \addtogroup spa_param + * \{ + */ + +/** + * Possible high-definition DTS extensions on top of core DTS. + */ +enum spa_audio_dts_ext_type { + SPA_AUDIO_DTS_EXT_UNKNOWN, + SPA_AUDIO_DTS_EXT_NONE, /**< No extension present; this is just regular DTS data */ + SPA_AUDIO_DTS_EXT_HD_HRA, /**< DTS-HD High Resolution Audio (lossy HD audio extension) */ + SPA_AUDIO_DTS_EXT_HD_MA, /**< DTS-HD Master Audio (lossless HD audio extension) */ +}; + +/** + * DTS Coherent Acoustics audio info. Optional extensions on top + * of the DTS content can be present, resulting in what is known + * as DTS-HD. \a ext_type specifies which extension is used in + * combination with the core DTS content (if any). + */ +struct spa_audio_info_dts { + uint32_t rate; /*< sample rate */ + uint32_t channels; /*< number of channels */ + enum spa_audio_dts_ext_type ext_type; /*< DTS-HD extension type */ +}; + +#define SPA_AUDIO_INFO_DTS_INIT(...) ((struct spa_audio_info_dts) { __VA_ARGS__ }) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_DTS_H */ diff --git a/spa/include/spa/param/audio/eac3-utils.h b/spa/include/spa/param/audio/eac3-utils.h new file mode 100644 index 000000000..3cb7db25e --- /dev/null +++ b/spa/include/spa/param/audio/eac3-utils.h @@ -0,0 +1,69 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_EAC3_UTILS_H +#define SPA_AUDIO_EAC3_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include +#include +#include +#include + +#ifndef SPA_API_AUDIO_EAC3_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_AUDIO_EAC3_UTILS SPA_API_IMPL + #else + #define SPA_API_AUDIO_EAC3_UTILS static inline + #endif +#endif + +SPA_API_AUDIO_EAC3_UTILS int +spa_format_audio_eac3_parse(const struct spa_pod *format, struct spa_audio_info_eac3 *info) +{ + int res; + res = spa_pod_parse_object(format, + SPA_TYPE_OBJECT_Format, NULL, + SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels)); + return res; +} + +SPA_API_AUDIO_EAC3_UTILS struct spa_pod * +spa_format_audio_eac3_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info_eac3 *info) +{ + struct spa_pod_frame f; + spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); + spa_pod_builder_add(builder, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_eac3), + SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_ENCODED), + 0); + if (info->rate != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info->rate), 0); + if (info->channels != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info->channels), 0); + return (struct spa_pod*)spa_pod_builder_pop(builder, &f); +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_EAC3_UTILS_H */ diff --git a/spa/include/spa/param/audio/eac3.h b/spa/include/spa/param/audio/eac3.h new file mode 100644 index 000000000..8d27b460e --- /dev/null +++ b/spa/include/spa/param/audio/eac3.h @@ -0,0 +1,35 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_EAC3_H +#define SPA_AUDIO_EAC3_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \addtogroup spa_param + * \{ + */ + +/** Dolby E-AC-3 audio info. */ +struct spa_audio_info_eac3 { + uint32_t rate; /*< sample rate */ + uint32_t channels; /*< number of channels */ +}; + +#define SPA_AUDIO_INFO_EAC3_INIT(...) ((struct spa_audio_info_eac3) { __VA_ARGS__ }) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_EAC3_H */ diff --git a/spa/include/spa/param/audio/format-utils.h b/spa/include/spa/param/audio/format-utils.h index 4ff40faa1..da4d35fcb 100644 --- a/spa/include/spa/param/audio/format-utils.h +++ b/spa/include/spa/param/audio/format-utils.h @@ -27,6 +27,11 @@ extern "C" { #include #include #include +#include +#include +#include +#include +#include /** @@ -80,6 +85,16 @@ spa_format_audio_parse(const struct spa_pod *format, struct spa_audio_info *info return spa_format_audio_flac_parse(format, &info->info.flac); case SPA_MEDIA_SUBTYPE_ape: return spa_format_audio_ape_parse(format, &info->info.ape); + case SPA_MEDIA_SUBTYPE_ac3: + return spa_format_audio_ac3_parse(format, &info->info.ac3); + case SPA_MEDIA_SUBTYPE_eac3: + return spa_format_audio_eac3_parse(format, &info->info.eac3); + case SPA_MEDIA_SUBTYPE_truehd: + return spa_format_audio_truehd_parse(format, &info->info.truehd); + case SPA_MEDIA_SUBTYPE_dts: + return spa_format_audio_dts_parse(format, &info->info.dts); + case SPA_MEDIA_SUBTYPE_mpegh: + return spa_format_audio_mpegh_parse(format, &info->info.mpegh); } return -ENOTSUP; } @@ -115,6 +130,16 @@ spa_format_audio_build(struct spa_pod_builder *builder, uint32_t id, return spa_format_audio_flac_build(builder, id, &info->info.flac); case SPA_MEDIA_SUBTYPE_ape: return spa_format_audio_ape_build(builder, id, &info->info.ape); + case SPA_MEDIA_SUBTYPE_ac3: + return spa_format_audio_ac3_build(builder, id, &info->info.ac3); + case SPA_MEDIA_SUBTYPE_eac3: + return spa_format_audio_eac3_build(builder, id, &info->info.eac3); + case SPA_MEDIA_SUBTYPE_truehd: + return spa_format_audio_truehd_build(builder, id, &info->info.truehd); + case SPA_MEDIA_SUBTYPE_dts: + return spa_format_audio_dts_build(builder, id, &info->info.dts); + case SPA_MEDIA_SUBTYPE_mpegh: + return spa_format_audio_mpegh_build(builder, id, &info->info.mpegh); } errno = ENOTSUP; return NULL; diff --git a/spa/include/spa/param/audio/format.h b/spa/include/spa/param/audio/format.h index 0619de394..c38d505e3 100644 --- a/spa/include/spa/param/audio/format.h +++ b/spa/include/spa/param/audio/format.h @@ -29,6 +29,11 @@ extern "C" { #include #include #include +#include +#include +#include +#include +#include struct spa_audio_info { uint32_t media_type; @@ -48,6 +53,11 @@ struct spa_audio_info { struct spa_audio_info_flac flac; struct spa_audio_info_ape ape; struct spa_audio_info_ape opus; + struct spa_audio_info_ac3 ac3; + struct spa_audio_info_eac3 eac3; + struct spa_audio_info_truehd truehd; + struct spa_audio_info_dts dts; + struct spa_audio_info_mpegh mpegh; } info; }; diff --git a/spa/include/spa/param/audio/mpegh-utils.h b/spa/include/spa/param/audio/mpegh-utils.h new file mode 100644 index 000000000..6544c24c0 --- /dev/null +++ b/spa/include/spa/param/audio/mpegh-utils.h @@ -0,0 +1,69 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_MPEGH_UTILS_H +#define SPA_AUDIO_MPEGH_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include +#include +#include +#include + +#ifndef SPA_API_AUDIO_MPEGH_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_AUDIO_MPEGH_UTILS SPA_API_IMPL + #else + #define SPA_API_AUDIO_MPEGH_UTILS static inline + #endif +#endif + +SPA_API_AUDIO_MPEGH_UTILS int +spa_format_audio_mpegh_parse(const struct spa_pod *format, struct spa_audio_info_mpegh *info) +{ + int res; + res = spa_pod_parse_object(format, + SPA_TYPE_OBJECT_Format, NULL, + SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels)); + return res; +} + +SPA_API_AUDIO_MPEGH_UTILS struct spa_pod * +spa_format_audio_mpegh_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info_mpegh *info) +{ + struct spa_pod_frame f; + spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); + spa_pod_builder_add(builder, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_mpegh), + SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_ENCODED), + 0); + if (info->rate != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info->rate), 0); + if (info->channels != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info->channels), 0); + return (struct spa_pod*)spa_pod_builder_pop(builder, &f); +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_MPEGH_UTILS_H */ diff --git a/spa/include/spa/param/audio/mpegh.h b/spa/include/spa/param/audio/mpegh.h new file mode 100644 index 000000000..e654a500b --- /dev/null +++ b/spa/include/spa/param/audio/mpegh.h @@ -0,0 +1,46 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_MPEGH_H +#define SPA_AUDIO_MPEGH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \addtogroup spa_param + * \{ + */ + +/** + * MPEG-H 3D audio info. + * + * MPEG-H content is assumed to be provided in the form of an MPEG-H + * 3D Audio Stream (MHAS). MHAS is a lightweight bitstream format that + * encapsulates MPEG-H 3D Audio frames along with associated metadata. + * It serves a similar role to the Annex B byte stream format used for + * H.264, providing framing and synchronization for MPEG-H frames. + * + * MPEG-H is documented in the ISO/IEC 23008-3 specification. + * MHAS is specified in ISO/IEC 23008-3, Clause 14. + */ +struct spa_audio_info_mpegh { + uint32_t rate; /*< sample rate */ + uint32_t channels; /*< number of channels */ +}; + +#define SPA_AUDIO_INFO_MPEGH_INIT(...) ((struct spa_audio_info_mpegh) { __VA_ARGS__ }) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_MPEGH_H */ diff --git a/spa/include/spa/param/audio/truehd-utils.h b/spa/include/spa/param/audio/truehd-utils.h new file mode 100644 index 000000000..61c67c017 --- /dev/null +++ b/spa/include/spa/param/audio/truehd-utils.h @@ -0,0 +1,69 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_TRUEHD_UTILS_H +#define SPA_AUDIO_TRUEHD_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup spa_param + * \{ + */ + +#include +#include +#include +#include + +#ifndef SPA_API_AUDIO_TRUEHD_UTILS + #ifdef SPA_API_IMPL + #define SPA_API_AUDIO_TRUEHD_UTILS SPA_API_IMPL + #else + #define SPA_API_AUDIO_TRUEHD_UTILS static inline + #endif +#endif + +SPA_API_AUDIO_TRUEHD_UTILS int +spa_format_audio_truehd_parse(const struct spa_pod *format, struct spa_audio_info_truehd *info) +{ + int res; + res = spa_pod_parse_object(format, + SPA_TYPE_OBJECT_Format, NULL, + SPA_FORMAT_AUDIO_rate, SPA_POD_OPT_Int(&info->rate), + SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&info->channels)); + return res; +} + +SPA_API_AUDIO_TRUEHD_UTILS struct spa_pod * +spa_format_audio_truehd_build(struct spa_pod_builder *builder, uint32_t id, + const struct spa_audio_info_truehd *info) +{ + struct spa_pod_frame f; + spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id); + spa_pod_builder_add(builder, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_truehd), + SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_ENCODED), + 0); + if (info->rate != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_rate, SPA_POD_Int(info->rate), 0); + if (info->channels != 0) + spa_pod_builder_add(builder, + SPA_FORMAT_AUDIO_channels, SPA_POD_Int(info->channels), 0); + return (struct spa_pod*)spa_pod_builder_pop(builder, &f); +} + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_TRUEHD_UTILS_H */ diff --git a/spa/include/spa/param/audio/truehd.h b/spa/include/spa/param/audio/truehd.h new file mode 100644 index 000000000..44adbbb3e --- /dev/null +++ b/spa/include/spa/param/audio/truehd.h @@ -0,0 +1,35 @@ +/* Simple Plugin API */ +/* SPDX-FileCopyrightText: Copyright © 2025 Carlos Rafael Giani */ +/* SPDX-License-Identifier: MIT */ + +#ifndef SPA_AUDIO_TRUEHD_H +#define SPA_AUDIO_TRUEHD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \addtogroup spa_param + * \{ + */ + +/** Dolby TrueHD audio info. */ +struct spa_audio_info_truehd { + uint32_t rate; /*< sample rate */ + uint32_t channels; /*< number of channels */ +}; + +#define SPA_AUDIO_INFO_TRUEHD_INIT(...) ((struct spa_audio_info_truehd) { __VA_ARGS__ }) + +/** + * \} + */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_AUDIO_TRUEHD_H */ diff --git a/spa/include/spa/param/audio/type-info.h b/spa/include/spa/param/audio/type-info.h index 8a3aa49aa..1a15ad3dd 100644 --- a/spa/include/spa/param/audio/type-info.h +++ b/spa/include/spa/param/audio/type-info.h @@ -11,5 +11,6 @@ #include #include #include +#include #endif /* SPA_AUDIO_TYPES_H */ diff --git a/spa/include/spa/param/format-types.h b/spa/include/spa/param/format-types.h index 46ff10624..7af6f2784 100644 --- a/spa/include/spa/param/format-types.h +++ b/spa/include/spa/param/format-types.h @@ -65,6 +65,11 @@ static const struct spa_type_info spa_type_media_subtype[] = { { SPA_MEDIA_SUBTYPE_flac, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "flac", NULL }, { SPA_MEDIA_SUBTYPE_ape, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "ape", NULL }, { SPA_MEDIA_SUBTYPE_opus, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "opus", NULL }, + { SPA_MEDIA_SUBTYPE_ac3, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "ac3", NULL }, + { SPA_MEDIA_SUBTYPE_eac3, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "eac3", NULL }, + { SPA_MEDIA_SUBTYPE_truehd, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "truehd", NULL }, + { SPA_MEDIA_SUBTYPE_dts, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "dts", NULL }, + { SPA_MEDIA_SUBTYPE_mpegh, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "mpegh", NULL }, /* video subtypes */ { SPA_MEDIA_SUBTYPE_h264, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "h264", NULL }, { SPA_MEDIA_SUBTYPE_mjpg, SPA_TYPE_Int, SPA_TYPE_INFO_MEDIA_SUBTYPE_BASE "mjpg", NULL }, @@ -99,6 +104,8 @@ static const struct spa_type_info spa_type_media_subtype[] = { #define SPA_TYPE_INFO_FORMAT_AUDIO_AMR_BASE SPA_TYPE_INFO_FORMAT_AUDIO_AMR ":" #define SPA_TYPE_INFO_FORMAT_AUDIO_MP3 SPA_TYPE_INFO_FORMAT_AUDIO_BASE "MP3" #define SPA_TYPE_INFO_FORMAT_AUDIO_MP3_BASE SPA_TYPE_INFO_FORMAT_AUDIO_MP3 ":" +#define SPA_TYPE_INFO_FORMAT_AUDIO_DTS SPA_TYPE_INFO_FORMAT_AUDIO_BASE "DTS" +#define SPA_TYPE_INFO_FORMAT_AUDIO_DTS_BASE SPA_TYPE_INFO_FORMAT_AUDIO_DTS ":" #define SPA_TYPE_INFO_FormatVideo SPA_TYPE_INFO_FORMAT_BASE "Video" #define SPA_TYPE_INFO_FORMAT_VIDEO_BASE SPA_TYPE_INFO_FormatVideo ":" @@ -143,6 +150,8 @@ static const struct spa_type_info spa_type_format[] = { spa_type_audio_amr_band_mode }, { SPA_FORMAT_AUDIO_MP3_channelMode, SPA_TYPE_Id, SPA_TYPE_INFO_FORMAT_AUDIO_MP3_BASE "channelMode", spa_type_audio_mp3_channel_mode }, + { SPA_FORMAT_AUDIO_DTS_extType, SPA_TYPE_Id, SPA_TYPE_INFO_FORMAT_AUDIO_DTS_BASE "extType", + spa_type_audio_dts_ext_type }, { SPA_FORMAT_VIDEO_format, SPA_TYPE_Id, SPA_TYPE_INFO_FORMAT_VIDEO_BASE "format", spa_type_video_format, }, diff --git a/spa/include/spa/param/format.h b/spa/include/spa/param/format.h index ffb9959ce..25052495a 100644 --- a/spa/include/spa/param/format.h +++ b/spa/include/spa/param/format.h @@ -52,6 +52,11 @@ enum spa_media_subtype { SPA_MEDIA_SUBTYPE_flac, /** since 0.3.65 */ SPA_MEDIA_SUBTYPE_ape, /** since 0.3.65 */ SPA_MEDIA_SUBTYPE_opus, /** since 0.3.68 */ + SPA_MEDIA_SUBTYPE_ac3, /** since 1.5.1 */ + SPA_MEDIA_SUBTYPE_eac3, /** since 1.5.1 */ + SPA_MEDIA_SUBTYPE_truehd, /** since 1.5.1 */ + SPA_MEDIA_SUBTYPE_dts, /** since 1.5.1 */ + SPA_MEDIA_SUBTYPE_mpegh, /** since 1.5.1 */ SPA_MEDIA_SUBTYPE_START_Video = 0x20000, SPA_MEDIA_SUBTYPE_h264, @@ -112,6 +117,8 @@ enum spa_format { SPA_FORMAT_AUDIO_MP3_channelMode, /**< MP3 channel mode, (Id enum spa_audio_mp3_channel_mode) */ + SPA_FORMAT_AUDIO_DTS_extType, /**< DTS extension type (Id enum spa_audio_dts_ext_type) */ + /* Video Format keys */ SPA_FORMAT_START_Video = 0x20000, diff --git a/spa/lib/lib.c b/spa/lib/lib.c index e2acb9cc2..648fb82a1 100644 --- a/spa/lib/lib.c +++ b/spa/lib/lib.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include #include @@ -46,6 +48,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -57,6 +64,8 @@ #include #include #include +#include +#include #include #include #include @@ -65,6 +74,8 @@ #include #include #include +#include +#include #include #include #include