Coverage Report

Created: 2025-08-25 07:17

/src/vlc/modules/codec/uleaddvaudio.c
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * uleaddvaudio.c
3
 *****************************************************************************
4
 * Copyright (C) 2012 Laurent Aimar
5
 *
6
 * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
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
#ifdef HAVE_CONFIG_H
24
# include "config.h"
25
#endif
26
27
#include <vlc_common.h>
28
#include <vlc_plugin.h>
29
#include <vlc_codec.h>
30
31
#include "../demux/rawdv.h"
32
33
/*****************************************************************************
34
 * Module descriptor
35
 *****************************************************************************/
36
static int  Open(vlc_object_t *);
37
38
100
vlc_module_begin()
39
50
    set_description(N_("Ulead DV audio decoder"))
40
50
    set_capability("audio decoder", 50)
41
50
    set_subcategory(SUBCAT_INPUT_ACODEC)
42
50
    set_callback(Open)
43
50
vlc_module_end()
44
45
typedef struct
46
{
47
    date_t end_date;
48
49
    bool     is_pal;
50
    bool     is_12bit;
51
    uint16_t shuffle[2000];
52
} decoder_sys_t;
53
54
static void Flush(decoder_t *dec)
55
0
{
56
0
    decoder_sys_t *sys = dec->p_sys;
57
58
0
    date_Set(&sys->end_date, VLC_TICK_INVALID);
59
0
}
60
61
static block_t *DecodeBlock(decoder_t *dec, block_t **block_ptr)
62
274k
{
63
274k
    decoder_sys_t *sys  = dec->p_sys;
64
65
274k
    if (!*block_ptr)
66
0
        return NULL;
67
68
274k
    block_t *block = *block_ptr;
69
274k
    if (block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
70
0
        Flush(dec);
71
0
        if (block->i_flags & BLOCK_FLAG_CORRUPTED) {
72
0
            block_Release(block);
73
0
            *block_ptr = NULL;
74
0
            return NULL;
75
0
        }
76
0
    }
77
78
274k
    if (block->i_pts != VLC_TICK_INVALID &&
79
274k
        block->i_pts != date_Get(&sys->end_date))
80
274k
        date_Set(&sys->end_date, block->i_pts);
81
274k
    block->i_pts = VLC_TICK_INVALID;
82
274k
    if (date_Get(&sys->end_date) == VLC_TICK_INVALID) {
83
        /* We've just started the stream, wait for the first PTS. */
84
0
        block_Release(block);
85
0
        return NULL;
86
0
    }
87
88
274k
    const unsigned int block_size = sys->is_pal ? 8640 : 7200;
89
274k
    if (block->i_buffer >= block_size) {
90
26.8k
        uint8_t *src = block->p_buffer;
91
92
26.8k
        block->i_buffer -= block_size;
93
26.8k
        block->p_buffer += block_size;
94
95
26.8k
        int sample_count = dv_get_audio_sample_count(&src[244], sys->is_pal);
96
97
26.8k
        if( decoder_UpdateAudioFormat(dec))
98
26.8k
            return NULL;
99
0
        block_t *output = decoder_NewAudioBuffer(dec, sample_count);
100
0
        if (!output)
101
0
            return NULL;
102
0
        output->i_pts    = date_Get(&sys->end_date);
103
0
        output->i_length = date_Increment(&sys->end_date, sample_count) - output->i_pts;
104
105
0
        int16_t *dst = (int16_t*)output->p_buffer;
106
0
        for (int i = 0; i < sample_count; i++) {
107
0
          const uint8_t *v = &src[sys->shuffle[i]];
108
0
          if (sys->is_12bit) {
109
0
              *dst++ = dv_audio_12to16((v[0] << 4) | ((v[2] >> 4) & 0x0f));
110
0
              *dst++ = dv_audio_12to16((v[1] << 4) | ((v[2] >> 0) & 0x0f));
111
0
          } else {
112
0
              *dst++ = GetWBE(&v[0]);
113
0
              *dst++ = GetWBE(&v[sys->is_pal ? 4320 : 3600]);
114
0
          }
115
0
        }
116
0
        return output;
117
0
    }
118
247k
    block_Release(block);
119
247k
    return NULL;
120
274k
}
121
122
static int DecodeAudio(decoder_t *dec, block_t *block)
123
549k
{
124
549k
    if (block == NULL) /* No Drain */
125
274k
        return VLCDEC_SUCCESS;
126
127
274k
    block_t **block_ptr = &block, *out;
128
274k
    while ((out = DecodeBlock(dec, block_ptr)) != NULL)
129
0
        decoder_QueueAudio(dec,out);
130
274k
    return VLCDEC_SUCCESS;
131
549k
}
132
133
static int Open(vlc_object_t *object)
134
582k
{
135
582k
    decoder_t *dec = (decoder_t*)object;
136
137
582k
    if (dec->fmt_in->i_codec != VLC_CODEC_ULEAD_DV_AUDIO_NTSC &&
138
582k
        dec->fmt_in->i_codec != VLC_CODEC_ULEAD_DV_AUDIO_PAL)
139
582k
        return VLC_EGENERIC;
140
138
    if (dec->fmt_in->audio.i_bitspersample != 12 && dec->fmt_in->audio.i_bitspersample != 16)
141
10
        return VLC_EGENERIC;
142
128
    if (dec->fmt_in->audio.i_channels != 2)
143
2
        return VLC_EGENERIC;
144
126
    if (dec->fmt_in->audio.i_rate <= 0)
145
1
        return VLC_EGENERIC;
146
147
125
    decoder_sys_t *sys = dec->p_sys = vlc_obj_malloc(object, sizeof(*sys));
148
125
    if (!sys)
149
0
        return VLC_ENOMEM;
150
151
125
    sys->is_pal = dec->fmt_in->i_codec == VLC_CODEC_ULEAD_DV_AUDIO_PAL;
152
125
    sys->is_12bit = dec->fmt_in->audio.i_bitspersample == 12;
153
154
125
    date_Init(&sys->end_date, dec->fmt_in->audio.i_rate, 1);
155
156
250k
    for (unsigned i = 0; i < sizeof(sys->shuffle) / sizeof(*sys->shuffle); i++) {
157
250k
        const unsigned a = sys->is_pal ? 18 : 15;
158
250k
        const unsigned b = 3 * a;
159
250k
        sys->shuffle[i] = 80 * ((21 * (i % 3) + 9 * (i / 3) + ((i / a) % 3)) % b) +
160
250k
                          (2 + sys->is_12bit) * (i / b) + 8;
161
250k
    }
162
163
125
    dec->fmt_out.i_codec = VLC_CODEC_S16N;
164
125
    dec->fmt_out.audio.i_rate = dec->fmt_in->audio.i_rate;
165
125
    dec->fmt_out.audio.i_channels = 2;
166
125
    dec->fmt_out.audio.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
167
168
125
    dec->pf_decode = DecodeAudio;
169
125
    dec->pf_flush  = Flush;
170
171
125
    return VLC_SUCCESS;
172
125
}