/src/gstreamer/subprojects/gst-plugins-base/gst-libs/gst/audio/gstdsd.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* GStreamer |
2 | | * Copyright (C) 2023 Carlos Rafael Giani <crg7475@mailbox.org> |
3 | | * |
4 | | * This library is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU Library General Public |
6 | | * License as published by the Free Software Foundation; either |
7 | | * version 2 of the License, or (at your option) any later version. |
8 | | * |
9 | | * This library is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | | * Library General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Library General Public |
15 | | * License along with this library; if not, write to the |
16 | | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
17 | | * Boston, MA 02110-1301, USA. |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <gst/gst.h> |
23 | | #include <gst/audio/audio.h> |
24 | | #include <gst/audio/gstdsdformat.h> |
25 | | |
26 | | G_BEGIN_DECLS |
27 | | |
28 | | /** |
29 | | * GST_DSD_MEDIA_TYPE: |
30 | | * |
31 | | * The GStreamer media type for DSD. |
32 | | * |
33 | | * Since: 1.24 |
34 | | */ |
35 | 0 | #define GST_DSD_MEDIA_TYPE "audio/x-dsd" |
36 | | |
37 | | /** |
38 | | * GST_DSD_CAPS_MAKE: |
39 | | * @format: string format that describes the DSD bits grouping, |
40 | | * as string (e.g. "DSDU32BE", "DSDU8", etc.) |
41 | | * |
42 | | * Generic caps string for DSD audio, for use in pad templates. |
43 | | * |
44 | | * Since: 1.24 |
45 | | */ |
46 | | #define GST_DSD_CAPS_MAKE(format) \ |
47 | | GST_DSD_MEDIA_TYPE ", " \ |
48 | | "format = (string) " format ", " \ |
49 | | "rate = " GST_AUDIO_RATE_RANGE ", " \ |
50 | | "layout = (string) { interleaved, non-interleaved }, " \ |
51 | | "reversed-bytes = (gboolean) { false, true }, " \ |
52 | | "channels = " GST_AUDIO_CHANNELS_RANGE |
53 | | |
54 | | /** |
55 | | * GST_DSD_MAKE_DSD_RATE_44x: |
56 | | * |
57 | | * Calculates a valid DSD-44x rate (in bytes) from commonly used rate |
58 | | * multiplier specifications like DSD64, DSD128 etc. |
59 | | * |
60 | | * For example, to get the rate for DSD64-44x, use 64 as the multiplier |
61 | | * argument. |
62 | | * |
63 | | * Since: 1.24 |
64 | | */ |
65 | | #define GST_DSD_MAKE_DSD_RATE_44x(multiplier) \ |
66 | | ((gint) ((gint64) multiplier) * 44100 / 8) |
67 | | |
68 | | /** |
69 | | * GST_DSD_MAKE_DSD_RATE_48x: |
70 | | * |
71 | | * Calculates a valid DSD-48x rate (in bytes) from commonly used rate |
72 | | * multiplier specifications like DSD64, DSD128 etc. |
73 | | * |
74 | | * For example, to get the rate for DSD64-48x, use 64 as the multiplier |
75 | | * argument. |
76 | | * |
77 | | * Since: 1.24 |
78 | | */ |
79 | | #define GST_DSD_MAKE_DSD_RATE_48x(multiplier) \ |
80 | | ((gint) ((gint64) multiplier) * 48000 / 8) |
81 | | /** |
82 | | * GST_DSD_SILENCE_PATTERN_BYTE: |
83 | | * |
84 | | * Silence pattern for DSD data. |
85 | | * |
86 | | * In DSD, a nullbyte does not correspond to silence. To fill memory regions |
87 | | * with "DSD silence", these regions must be filled with byte 0x69 instead |
88 | | * (this is the DSD silence pattern). This constant provides that pattern |
89 | | * in a more readable fashion. |
90 | | * |
91 | | * Since: 1.24 |
92 | | */ |
93 | 0 | #define GST_DSD_SILENCE_PATTERN_BYTE (0x69) |
94 | | |
95 | | typedef struct _GstDsdInfo GstDsdInfo; |
96 | | |
97 | | /** |
98 | | * GstDsdInfo: |
99 | | * @format: DSD grouping format |
100 | | * @rate: DSD rate |
101 | | * @channels: number of channels (must be at least 1) |
102 | | * @layout: audio layout |
103 | | * @reversed_bytes: true if the DSD bits in the data bytes are reversed, |
104 | | * that is, the least significant bit comes first |
105 | | * @positions: positions for each channel |
106 | | * |
107 | | * Information describing DSD audio properties. |
108 | | * |
109 | | * In DSD, the "sample format" is the bit. Unlike PCM, there are no further |
110 | | * "sample formats" in DSD. However, in software, DSD bits are grouped into |
111 | | * bytes (since dealing with individual bits is impractical), and these bytes |
112 | | * in turn are grouped into words. This becomes relevant when interleaving |
113 | | * channels and transmitting DSD data through audio APIs. The different |
114 | | * types of grouping DSD bytes are referred to as the "DSD grouping forma" |
115 | | * or just "DSD format". #GstDsdFormat has a list of valid ways of grouping |
116 | | * DSD bytes into words. |
117 | | * |
118 | | * DSD rates are equivalent to PCM sample rates, except that they specify |
119 | | * how many DSD bytes are consumed per second. This refers to the bytes per |
120 | | * second _per channel_; the rate does not change when the number of channel |
121 | | * changes. (Strictly speaking, it would be more correct to measure the |
122 | | * *bits* per second, since the bit is the DSD "sample format", but it is |
123 | | * more practical to use bytes.) In DSD, bit rates are always an integer |
124 | | * multiple of the CD audio rate (44100) or the DAT rate (48000). DSD64-44x |
125 | | * is 44100 * 64 = 2822400 bits per second, or 352800 bytes per second |
126 | | * (the latter would be used in this info structure). DSD64-48x is |
127 | | * 48000 * 64 = 3072000 bits per second, or 384000 bytes per second. |
128 | | * #GST_DSD_MAKE_DSD_RATE_44x can be used for specifying DSD-44x rates, |
129 | | * *and #GST_DSD_MAKE_DSD_RATE_48x can be used for specifying DSD-48x ones. |
130 | | * Also, since DSD-48x is less well known, when the multiplier is given |
131 | | * without the 44x/48x specifier, 44x is typically implied. |
132 | | * |
133 | | * It is important to know that in DSD, different format widths correspond |
134 | | * to different playtimes. That is, a word with 32 DSD bits covers two times |
135 | | * as much playtime as a word with 16 DSD bits. This is in contrast to PCM, |
136 | | * where one word (= one PCM sample) always covers a time period of 1/samplerate, |
137 | | * no matter how many bits a PCM sample is made of. For this reason, DSD |
138 | | * and PCM widths and strides cannot be used the same way. |
139 | | * |
140 | | * Multiple channels are arranged in DSD data either interleaved or non- |
141 | | * interleaved. This is similar to PCM. Interleaved layouts rotate between |
142 | | * channels and words. First, word 0 of channel 0 is present. Then word |
143 | | * 0 of channel 1 follows. Then word 0 of channel 2 etc. until all |
144 | | * channels are through, then comes word 1 of channel 0 etc. |
145 | | * |
146 | | * Non-interleaved data is planar. First, all words of channel 0 are |
147 | | * present, then all words of channel 1 etc. Unlike interleaved data, |
148 | | * non-interleaved data can be sparse, that is, there can be space in |
149 | | * between the planes. the @positions array specifies the plane offsets. |
150 | | * |
151 | | * In uncommon cases, the DSD bits in the data bytes can be stored in reverse |
152 | | * order. For example, normally, in DSDU8, the first byte contains DSD bits |
153 | | * 0 to 7, and the most significant bit of that byte is DSD bit 0. If this |
154 | | * order is reversed, then bit 7 is the first one instead. In that ase, |
155 | | * @reversed_bytes is set to TRUE. |
156 | | * |
157 | | * Use the provided macros to access the info in this structure. |
158 | | * |
159 | | * Since: 1.24 |
160 | | */ |
161 | | struct _GstDsdInfo { |
162 | | GstDsdFormat format; |
163 | | gint rate; |
164 | | gint channels; |
165 | | GstAudioLayout layout; |
166 | | gboolean reversed_bytes; |
167 | | GstAudioChannelPosition positions[64]; |
168 | | GstAudioFlags flags; |
169 | | |
170 | | /*< private >*/ |
171 | | gpointer _gst_reserved[GST_PADDING]; |
172 | | }; |
173 | | |
174 | | #define GST_TYPE_DSD_INFO (gst_dsd_info_get_type ()) |
175 | | GST_AUDIO_API |
176 | | GType gst_dsd_info_get_type (void); |
177 | | |
178 | | #define GST_DSD_INFO_IS_VALID(i) ((i)->format < GST_NUM_DSD_FORMATS && (i)->rate > 0 && (i)->channels > 0) |
179 | | |
180 | 0 | #define GST_DSD_INFO_FORMAT(info) ((info)->format) |
181 | 0 | #define GST_DSD_INFO_RATE(info) ((info)->rate) |
182 | 0 | #define GST_DSD_INFO_CHANNELS(info) ((info)->channels) |
183 | 0 | #define GST_DSD_INFO_LAYOUT(info) ((info)->layout) |
184 | 0 | #define GST_DSD_INFO_REVERSED_BYTES(info) ((info)->reversed_bytes) |
185 | | #define GST_DSD_INFO_POSITION(info,c) ((info)->position[c]) |
186 | | |
187 | | /** |
188 | | * GST_DSD_INFO_STRIDE: |
189 | | * |
190 | | * Calculates the stride for a given #GstDsdInfo. |
191 | | * |
192 | | * Note that this is only useful if the info's audio layout |
193 | | * is GST_AUDIO_LAYOUT_INTERLEAVED. |
194 | | * |
195 | | * Since: 1.24 |
196 | | */ |
197 | | #define GST_DSD_INFO_STRIDE(info) (gst_dsd_format_get_width((info)->format) * (info)->channels) |
198 | | |
199 | | /*** GstDsdPlaneOffsetMeta ***/ |
200 | | |
201 | 0 | #define GST_DSD_PLANE_OFFSET_META_API_TYPE (gst_dsd_plane_offset_meta_api_get_type()) |
202 | 0 | #define GST_DSD_PLANE_OFFSET_META_INFO (gst_dsd_plane_offset_meta_get_info()) |
203 | | |
204 | | /** |
205 | | * GST_META_TAG_DSD_PLANE_OFFSETS_STR: |
206 | | * |
207 | | * This metadata stays relevant as long as the DSD plane offsets are unchanged. |
208 | | * |
209 | | * Since: 1.24 |
210 | | */ |
211 | 0 | #define GST_META_TAG_DSD_PLANE_OFFSETS_STR "dsdplaneoffsets" |
212 | | |
213 | | typedef struct _GstDsdPlaneOffsetMeta GstDsdPlaneOffsetMeta; |
214 | | |
215 | | /** |
216 | | * GstDsdPlaneOffsetMeta: |
217 | | * @meta: parent #GstMeta |
218 | | * @num_channels: number of channels in the DSD data |
219 | | * @num_bytes_per_channel: the number of valid bytes per channel in the buffer |
220 | | * @offsets: the offsets (in bytes) where each channel plane starts in the buffer |
221 | | * |
222 | | * Buffer metadata describing planar DSD contents in the buffer. This is not needed |
223 | | * for interleaved DSD data, and is required for non-interleaved (= planar) data. |
224 | | * |
225 | | * The different channels in @offsets are always in the GStreamer channel order. |
226 | | * Zero-copy channel reordering can be implemented by swapping the values in |
227 | | * @offsets. |
228 | | * |
229 | | * It is not allowed for channels to overlap in memory, |
230 | | * i.e. for each i in [0, channels), the range |
231 | | * [@offsets[i], @offsets[i] + @num_bytes_per_channel) must not overlap |
232 | | * with any other such range. |
233 | | * |
234 | | * It is, however, allowed to have parts of the buffer memory unused, by using |
235 | | * @offsets and @num_bytes_per_channel in such a way that leave gaps on it. |
236 | | * This is used to implement zero-copy clipping in non-interleaved buffers. |
237 | | * |
238 | | * Obviously, due to the above, it is not safe to infer the |
239 | | * number of valid bytes from the size of the buffer. You should always |
240 | | * use the @num_bytes_per_channel variable of this metadata. |
241 | | * |
242 | | * Since: 1.24 |
243 | | */ |
244 | | struct _GstDsdPlaneOffsetMeta { |
245 | | GstMeta meta; |
246 | | gint num_channels; |
247 | | gsize num_bytes_per_channel; |
248 | | gsize *offsets; |
249 | | |
250 | | /*< private >*/ |
251 | | gsize priv_offsets_arr[8]; |
252 | | gpointer _gst_reserved[GST_PADDING]; |
253 | | }; |
254 | | |
255 | | GST_AUDIO_API |
256 | | GType gst_dsd_plane_offset_meta_api_get_type (void); |
257 | | |
258 | | GST_AUDIO_API |
259 | | const GstMetaInfo * gst_dsd_plane_offset_meta_get_info (void); |
260 | | |
261 | | #define gst_buffer_get_dsd_plane_offset_meta(b) \ |
262 | | ((GstDsdPlaneOffsetMeta*)gst_buffer_get_meta((b), GST_DSD_PLANE_OFFSET_META_API_TYPE)) |
263 | | |
264 | | GST_AUDIO_API |
265 | | GstDsdPlaneOffsetMeta * gst_buffer_add_dsd_plane_offset_meta (GstBuffer *buffer, |
266 | | gint num_channels, |
267 | | gsize num_bytes_per_channel, |
268 | | gsize offsets[]); |
269 | | |
270 | | GST_AUDIO_API |
271 | | GstDsdInfo * gst_dsd_info_new (void); |
272 | | |
273 | | GST_AUDIO_API |
274 | | GstDsdInfo * gst_dsd_info_new_from_caps (const GstCaps * caps); |
275 | | |
276 | | GST_AUDIO_API |
277 | | void gst_dsd_info_init (GstDsdInfo * info); |
278 | | |
279 | | GST_AUDIO_API |
280 | | void gst_dsd_info_set_format (GstDsdInfo * info, |
281 | | GstDsdFormat format, |
282 | | gint rate, |
283 | | gint channels, |
284 | | const GstAudioChannelPosition * positions); |
285 | | |
286 | | GST_AUDIO_API |
287 | | GstDsdInfo * gst_dsd_info_copy (const GstDsdInfo * info); |
288 | | |
289 | | GST_AUDIO_API |
290 | | void gst_dsd_info_free (GstDsdInfo * info); |
291 | | |
292 | | GST_AUDIO_API |
293 | | gboolean gst_dsd_info_from_caps (GstDsdInfo *info, |
294 | | const GstCaps *caps); |
295 | | |
296 | | GST_AUDIO_API |
297 | | GstCaps * gst_dsd_info_to_caps (const GstDsdInfo *info); |
298 | | |
299 | | GST_AUDIO_API |
300 | | gboolean gst_dsd_info_is_equal (const GstDsdInfo *info, |
301 | | const GstDsdInfo *other); |
302 | | |
303 | | GST_AUDIO_API |
304 | | void gst_dsd_convert (const guint8 *input_data, |
305 | | guint8 *output_data, |
306 | | GstDsdFormat input_format, |
307 | | GstDsdFormat output_format, |
308 | | GstAudioLayout input_layout, |
309 | | GstAudioLayout output_layout, |
310 | | const gsize *input_plane_offsets, |
311 | | const gsize *output_plane_offsets, |
312 | | gsize num_dsd_bytes, |
313 | | gint num_channels, |
314 | | gboolean reverse_byte_bits); |
315 | | |
316 | | /** |
317 | | * gst_dsd_format_is_le: |
318 | | * @format: The format. |
319 | | * |
320 | | * Useful for determining whether a format is a little-endian. |
321 | | * GST_DSD_FORMAT_U8 and GST_DSD_FORMAT_UNKNOWN |
322 | | * are not considered little-endian. |
323 | | * |
324 | | * Returns: TRUE if the format is a little-endian one. |
325 | | */ |
326 | | static inline gboolean |
327 | | gst_dsd_format_is_le (GstDsdFormat format) |
328 | 0 | { |
329 | 0 | switch (format) { |
330 | 0 | case GST_DSD_FORMAT_U16LE: |
331 | 0 | case GST_DSD_FORMAT_U32LE: |
332 | 0 | return TRUE; |
333 | 0 | default: |
334 | 0 | return FALSE; |
335 | 0 | } |
336 | 0 | } Unexecuted instantiation: gst-discoverer.c:gst_dsd_format_is_le Unexecuted instantiation: pbutils-enumtypes.c:gst_dsd_format_is_le Unexecuted instantiation: pbutils.c:gst_dsd_format_is_le Unexecuted instantiation: codec-utils.c:gst_dsd_format_is_le Unexecuted instantiation: descriptions.c:gst_dsd_format_is_le Unexecuted instantiation: missing-plugins.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiovisualizer.c:gst_dsd_format_is_le Unexecuted instantiation: gstdiscoverer.c:gst_dsd_format_is_le Unexecuted instantiation: gstdiscoverer-types.c:gst_dsd_format_is_le Unexecuted instantiation: audio-enumtypes.c:gst_dsd_format_is_le Unexecuted instantiation: audio.c:gst_dsd_format_is_le Unexecuted instantiation: audio-buffer.c:gst_dsd_format_is_le Unexecuted instantiation: audio-channel-mixer.c:gst_dsd_format_is_le Unexecuted instantiation: audio-channels.c:gst_dsd_format_is_le Unexecuted instantiation: audio-converter.c:gst_dsd_format_is_le Unexecuted instantiation: audio-format.c:gst_dsd_format_is_le Unexecuted instantiation: audio-info.c:gst_dsd_format_is_le Unexecuted instantiation: audio-quantize.c:gst_dsd_format_is_le Unexecuted instantiation: audio-resampler.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudioaggregator.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiobasesink.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiobasesrc.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiocdsrc.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudioclock.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiodecoder.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudioencoder.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiofilter.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudioiec61937.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiometa.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudioringbuffer.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiosink.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudiosrc.c:gst_dsd_format_is_le Unexecuted instantiation: gstaudioutilsprivate.c:gst_dsd_format_is_le Unexecuted instantiation: gstdsd.c:gst_dsd_format_is_le |
337 | | |
338 | | G_END_DECLS |