Coverage Report

Created: 2023-03-26 07:08

/src/vlc/modules/demux/rawaud.c
Line
Count
Source (jump to first uncovered line)
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
4
vlc_module_begin();
62
2
    set_shortname( "Raw Audio" );
63
2
    set_description( N_("Raw audio demuxer") );
64
2
    set_capability( "demux", 0 );
65
2
    set_subcategory( SUBCAT_INPUT_DEMUX );
66
2
    set_callbacks( Open, Close );
67
2
    add_shortcut( "rawaud" );
68
2
    add_integer_with_range( "rawaud-channels", 2, 1, 32, CHANNELS_TEXT, CHANNELS_LONGTEXT )
69
2
        change_safe()
70
2
    add_integer_with_range( "rawaud-samplerate", 48000, 1, 384000, SAMPLERATE_TEXT, SAMPLERATE_LONGTEXT )
71
2
        change_safe()
72
2
    add_string( "rawaud-fourcc", FOURCC_DEFAULT,
73
2
                FOURCC_TEXT, FOURCC_LONGTEXT );
74
2
        change_safe()
75
2
    add_string( "rawaud-lang", "eng", LANG_TEXT, LANG_LONGTEXT);
76
2
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_CreateGetString( 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
    msg_Dbg( p_demux, "elementary stream added");
191
192
    /* initialize timing */
193
0
    date_Init( &p_sys->pts, p_sys->fmt.audio.i_rate, 1 );
194
0
    date_Set( &p_sys->pts, VLC_TICK_0 );
195
196
    /* calculate 50ms frame size/time */
197
0
    p_sys->i_frame_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
198
0
    p_sys->i_seek_step  = p_sys->fmt.audio.i_channels *
199
0
                          ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
200
0
    p_sys->i_frame_size = p_sys->i_frame_samples * p_sys->i_seek_step;
201
0
    msg_Dbg( p_demux, "frame size is %d bytes ", p_sys->i_frame_size);
202
203
0
    p_demux->pf_demux   = Demux;
204
0
    p_demux->pf_control = Control;
205
0
    return VLC_SUCCESS;
206
0
}
207
208
/*****************************************************************************
209
 * Close: frees unused data
210
 *****************************************************************************/
211
static void Close( vlc_object_t *p_this )
212
0
{
213
0
    demux_t     *p_demux = (demux_t*)p_this;
214
0
    demux_sys_t *p_sys  = p_demux->p_sys;
215
216
0
    es_format_Clean( &p_sys->fmt );
217
0
    free( p_sys );
218
0
}
219
220
/*****************************************************************************
221
 * Demux: reads and demuxes data packets
222
 *****************************************************************************
223
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
224
 *****************************************************************************/
225
static int Demux( demux_t *p_demux )
226
0
{
227
0
    demux_sys_t *p_sys  = p_demux->p_sys;
228
0
    block_t     *p_block;
229
230
0
    p_block = vlc_stream_Block( p_demux->s, p_sys->i_frame_size );
231
0
    if( p_block == NULL )
232
0
        return VLC_DEMUXER_EOF;
233
234
0
    p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts );
235
236
0
    es_out_SetPCR( p_demux->out, p_block->i_pts );
237
0
    es_out_Send( p_demux->out, p_sys->p_es, p_block );
238
239
0
    date_Increment( &p_sys->pts, p_sys->i_frame_samples );
240
241
0
    return VLC_DEMUXER_SUCCESS;
242
0
}
243
244
/*****************************************************************************
245
 * Control:
246
 *****************************************************************************/
247
static int Control( demux_t *p_demux, int i_query, va_list args )
248
0
{
249
0
    demux_sys_t *p_sys  = p_demux->p_sys;
250
251
0
    return demux_vaControlHelper( p_demux->s, 0, -1,
252
0
                                  p_sys->fmt.i_bitrate, p_sys->i_seek_step, i_query, args );
253
0
}