Coverage Report

Created: 2026-08-13 07:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/demux/rawaud.c
Line
Count
Source
1
/*****************************************************************************
2
 * rawaud.c : raw audio input module for vlc
3
 *****************************************************************************
4
 * Copyright (C) 2009 VLC authors and VideoLAN
5
 *
6
 * Authors: Jarmo Torvinen <jarmo.torvinen@jutel.fi>
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation; either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program; if not, write to the Free Software Foundation,
20
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21
 *****************************************************************************/
22
23
/*****************************************************************************
24
 * Preamble
25
 *****************************************************************************/
26
27
#ifdef HAVE_CONFIG_H
28
# include "config.h"
29
#endif
30
31
#include <vlc_common.h>
32
#include <vlc_plugin.h>
33
#include <vlc_demux.h>
34
35
/*****************************************************************************
36
 * Module descriptor
37
 *****************************************************************************/
38
static int  Open ( vlc_object_t * );
39
static void Close( vlc_object_t * );
40
41
42
#define SAMPLERATE_TEXT N_("Audio samplerate (Hz)")
43
#define SAMPLERATE_LONGTEXT N_("Audio sample rate in Hertz. Default is 48000 Hz.")
44
45
#define CHANNELS_TEXT N_("Audio channels")
46
#define CHANNELS_LONGTEXT N_("Audio channels in input stream. Default is 2 (stereo).")
47
48
#define FOURCC_TEXT N_("FOURCC code of raw input format")
49
#define FOURCC_LONGTEXT N_( \
50
    "FOURCC code of the raw input format. This is a four character string." )
51
52
#define LANG_TEXT N_("Forces the audio language")
53
#define LANG_LONGTEXT N_("Forces the audio language for the output mux. Three letter ISO639 code. Default is 'eng'.")
54
55
#ifdef WORDS_BIGENDIAN
56
# define FOURCC_DEFAULT "s16b"
57
#else
58
# define FOURCC_DEFAULT "s16l"
59
#endif
60
61
168
vlc_module_begin()
62
84
    set_shortname( "Raw Audio" )
63
84
    set_description( N_("Raw audio demuxer") )
64
84
    set_capability( "demux", 0 )
65
84
    set_subcategory( SUBCAT_INPUT_DEMUX )
66
84
    set_callbacks( Open, Close )
67
84
    add_shortcut( "rawaud" )
68
84
    add_integer_with_range( "rawaud-channels", 2, 1, 32, CHANNELS_TEXT, CHANNELS_LONGTEXT )
69
84
        change_safe()
70
84
    add_integer_with_range( "rawaud-samplerate", 48000, 1, 384000, SAMPLERATE_TEXT, SAMPLERATE_LONGTEXT )
71
84
        change_safe()
72
84
    add_string( "rawaud-fourcc", FOURCC_DEFAULT,
73
84
                FOURCC_TEXT, FOURCC_LONGTEXT )
74
84
        change_safe()
75
84
    add_string( "rawaud-lang", "eng", LANG_TEXT, LANG_LONGTEXT)
76
84
vlc_module_end()
77
78
/*****************************************************************************
79
 * Definitions of structures used by this plugin
80
 *****************************************************************************/
81
typedef struct
82
{
83
    es_out_id_t *p_es;
84
    es_format_t  fmt;
85
    unsigned int i_frame_size;
86
    unsigned int i_frame_samples;
87
    unsigned int i_seek_step;
88
    date_t       pts;
89
} demux_sys_t;
90
91
92
/*****************************************************************************
93
 * Local prototypes
94
 *****************************************************************************/
95
static int Demux( demux_t * );
96
static int Control( demux_t *, int i_query, va_list args );
97
98
99
/*****************************************************************************
100
 * Open: initializes raw audio demuxer
101
 *****************************************************************************/
102
static int Open( vlc_object_t * p_this )
103
0
{
104
0
    demux_t     *p_demux = (demux_t*)p_this;
105
0
    demux_sys_t *p_sys;
106
107
0
    p_demux->p_sys      = p_sys = malloc( sizeof( demux_sys_t ) );
108
0
    if( !p_sys )
109
0
        return VLC_ENOMEM;
110
111
0
    char *psz_fourcc = var_InheritString( p_demux, "rawaud-fourcc" );
112
0
    es_format_Init( &p_sys->fmt, AUDIO_ES,
113
0
                    vlc_fourcc_GetCodecFromString( AUDIO_ES, psz_fourcc ) );
114
0
    free( psz_fourcc );
115
116
0
    if( !p_sys->fmt.i_codec )
117
0
    {
118
0
        msg_Err( p_demux, "rawaud-fourcc must be a 4 character string");
119
0
        es_format_Clean( &p_sys->fmt );
120
0
        free( p_sys );
121
0
        return VLC_EGENERIC;
122
0
    }
123
124
    // get the bits per sample ratio based on codec
125
0
    switch( p_sys->fmt.i_codec )
126
0
    {
127
128
0
        case VLC_CODEC_FL64:
129
0
            p_sys->fmt.audio.i_bitspersample = 64;
130
0
            break;
131
132
0
        case VLC_CODEC_FL32:
133
0
        case VLC_CODEC_S32L:
134
0
        case VLC_CODEC_S32B:
135
0
            p_sys->fmt.audio.i_bitspersample = 32;
136
0
            break;
137
138
0
        case VLC_CODEC_S24L:
139
0
        case VLC_CODEC_S24B:
140
0
            p_sys->fmt.audio.i_bitspersample = 24;
141
0
            break;
142
143
0
        case VLC_CODEC_S16L:
144
0
        case VLC_CODEC_S16B:
145
0
            p_sys->fmt.audio.i_bitspersample = 16;
146
0
            break;
147
148
0
        case VLC_CODEC_S8:
149
0
        case VLC_CODEC_U8:
150
0
            p_sys->fmt.audio.i_bitspersample = 8;
151
0
            break;
152
153
0
        default:
154
0
            msg_Err( p_demux, "unknown fourcc format %4.4s",
155
0
                    (char *)&p_sys->fmt.i_codec);
156
0
            es_format_Clean( &p_sys->fmt );
157
0
            free( p_sys );
158
0
            return VLC_EGENERIC;
159
160
0
    }
161
162
163
0
    p_sys->fmt.psz_language = var_CreateGetString( p_demux, "rawaud-lang" );
164
0
    p_sys->fmt.audio.i_channels = var_CreateGetInteger( p_demux, "rawaud-channels" );
165
0
    p_sys->fmt.audio.i_rate = var_CreateGetInteger( p_demux, "rawaud-samplerate" );
166
167
0
    p_sys->fmt.i_bitrate = p_sys->fmt.audio.i_rate *
168
0
                           p_sys->fmt.audio.i_channels *
169
0
                           p_sys->fmt.audio.i_bitspersample;
170
171
0
    if( p_sys->fmt.i_bitrate > 50000000)
172
0
    {
173
0
        msg_Err( p_demux, "invalid bitrate");
174
0
        es_format_Clean( &p_sys->fmt );
175
0
        free( p_sys );
176
0
        return VLC_EGENERIC;
177
0
    }
178
179
0
    msg_Dbg( p_demux,
180
0
            "format initialized: channels=%d , samplerate=%d Hz, fourcc=%4.4s, bits per sample = %d, bitrate = %d bit/s",
181
0
            p_sys->fmt.audio.i_channels,
182
0
            p_sys->fmt.audio.i_rate,
183
0
            (char*)&p_sys->fmt.i_codec,
184
0
            p_sys->fmt.audio.i_bitspersample,
185
0
            p_sys->fmt.i_bitrate);
186
187
    /* add the es */
188
0
    p_sys->fmt.i_id = 0;
189
0
    p_sys->p_es = es_out_Add( p_demux->out, &p_sys->fmt );
190
0
    if( unlikely(!p_sys->p_es) )
191
0
    {
192
0
        es_format_Clean( &p_sys->fmt );
193
0
        free( p_sys );
194
0
        return VLC_EGENERIC;
195
0
    }
196
0
    msg_Dbg( p_demux, "elementary stream added");
197
198
    /* initialize timing */
199
0
    date_Init( &p_sys->pts, p_sys->fmt.audio.i_rate, 1 );
200
0
    date_Set( &p_sys->pts, VLC_TICK_0 );
201
202
    /* calculate 50ms frame size/time */
203
0
    p_sys->i_frame_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
204
0
    p_sys->i_seek_step  = p_sys->fmt.audio.i_channels *
205
0
                          ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
206
0
    p_sys->i_frame_size = p_sys->i_frame_samples * p_sys->i_seek_step;
207
0
    msg_Dbg( p_demux, "frame size is %d bytes ", p_sys->i_frame_size);
208
209
0
    p_demux->pf_demux   = Demux;
210
0
    p_demux->pf_control = Control;
211
0
    return VLC_SUCCESS;
212
0
}
213
214
/*****************************************************************************
215
 * Close: frees unused data
216
 *****************************************************************************/
217
static void Close( vlc_object_t *p_this )
218
0
{
219
0
    demux_t     *p_demux = (demux_t*)p_this;
220
0
    demux_sys_t *p_sys  = p_demux->p_sys;
221
222
0
    es_format_Clean( &p_sys->fmt );
223
0
    free( p_sys );
224
0
}
225
226
/*****************************************************************************
227
 * Demux: reads and demuxes data packets
228
 *****************************************************************************
229
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
230
 *****************************************************************************/
231
static int Demux( demux_t *p_demux )
232
0
{
233
0
    demux_sys_t *p_sys  = p_demux->p_sys;
234
0
    block_t     *p_block;
235
236
0
    p_block = vlc_stream_Block( p_demux->s, p_sys->i_frame_size );
237
0
    if( p_block == NULL )
238
0
        return VLC_DEMUXER_EOF;
239
240
0
    p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts );
241
242
0
    es_out_SetPCR( p_demux->out, p_block->i_pts );
243
0
    es_out_Send( p_demux->out, p_sys->p_es, p_block );
244
245
0
    date_Increment( &p_sys->pts, p_sys->i_frame_samples );
246
247
0
    return VLC_DEMUXER_SUCCESS;
248
0
}
249
250
/*****************************************************************************
251
 * Control:
252
 *****************************************************************************/
253
static int Control( demux_t *p_demux, int i_query, va_list args )
254
0
{
255
0
    demux_sys_t *p_sys  = p_demux->p_sys;
256
257
0
    return demux_vaControlHelper( p_demux->s, 0, -1,
258
0
                                  p_sys->fmt.i_bitrate, p_sys->i_seek_step, i_query, args );
259
0
}