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