1 /*****************************************************************************
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 *****************************************************************************/
27 #include <vlc_common.h>
28 #include <vlc_plugin.h>
29 #include <vlc_codec.h>
31 #include "../demux/rawdv.h"
33 /*****************************************************************************
35 *****************************************************************************/
36 static int Open(vlc_object_t
*);
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
)
52 uint16_t shuffle
[2000];
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
;
69 block_t
*block
= *block_ptr
;
70 if (block
->i_flags
& (BLOCK_FLAG_DISCONTINUITY
|BLOCK_FLAG_CORRUPTED
)) {
72 if (block
->i_flags
& BLOCK_FLAG_CORRUPTED
) {
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. */
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
))
100 block_t
*output
= decoder_NewAudioBuffer(dec
, sample_count
);
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
]];
110 *dst
++ = dv_audio_12to16((v
[0] << 4) | ((v
[2] >> 4) & 0x0f));
111 *dst
++ = dv_audio_12to16((v
[1] << 4) | ((v
[2] >> 0) & 0x0f));
113 *dst
++ = GetWBE(&v
[0]);
114 *dst
++ = GetWBE(&v
[sys
->is_pal
? 4320 : 3600]);
119 block_Release(block
);
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
)
141 if (dec
->fmt_in
.audio
.i_bitspersample
!= 12 && dec
->fmt_in
.audio
.i_bitspersample
!= 16)
143 if (dec
->fmt_in
.audio
.i_channels
!= 2)
145 if (dec
->fmt_in
.audio
.i_rate
<= 0)
148 decoder_sys_t
*sys
= dec
->p_sys
= vlc_obj_malloc(object
, sizeof(*sys
));
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
;