Coverage Report

Created: 2025-09-05 06:29

/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