2 * Copyright (c) 2012 Laurent Aimar
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "libavutil/channel_layout.h"
22 #include "libavutil/intreadwrite.h"
24 #include "codec_internal.h"
28 typedef struct DVAudioContext
{
32 int16_t shuffle
[2000];
35 static av_cold
int decode_init(AVCodecContext
*avctx
)
37 DVAudioContext
*s
= avctx
->priv_data
;
40 if (avctx
->codec_tag
== 0x0215) {
42 } else if (avctx
->codec_tag
== 0x0216) {
44 } else if (avctx
->block_align
== 7200 ||
45 avctx
->block_align
== 8640) {
46 s
->block_size
= avctx
->block_align
;
48 return AVERROR(EINVAL
);
51 s
->is_pal
= s
->block_size
== 8640;
52 s
->is_12bit
= avctx
->bits_per_coded_sample
== 12;
53 avctx
->sample_fmt
= AV_SAMPLE_FMT_S16
;
54 av_channel_layout_uninit(&avctx
->ch_layout
);
55 avctx
->ch_layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_STEREO
;
57 for (i
= 0; i
< FF_ARRAY_ELEMS(s
->shuffle
); i
++) {
58 const unsigned a
= s
->is_pal
? 18 : 15;
59 const unsigned b
= 3 * a
;
61 s
->shuffle
[i
] = 80 * ((21 * (i
% 3) + 9 * (i
/ 3) + ((i
/ a
) % 3)) % b
) +
62 (2 + s
->is_12bit
) * (i
/ b
) + 8;
68 static inline uint16_t dv_audio_12to16(uint16_t sample
)
70 uint16_t shift
, result
;
72 sample
= (sample
< 0x800) ? sample
: sample
| 0xf000;
73 shift
= (sample
& 0xf00) >> 8;
75 if (shift
< 0x2 || shift
> 0xd) {
77 } else if (shift
< 0x8) {
79 result
= (sample
- (256 * shift
)) << shift
;
82 result
= ((sample
+ ((256 * shift
) + 1)) << shift
) - 1;
88 static int decode_frame(AVCodecContext
*avctx
, AVFrame
*frame
,
89 int *got_frame_ptr
, AVPacket
*pkt
)
91 DVAudioContext
*s
= avctx
->priv_data
;
92 const uint8_t *src
= pkt
->data
;
96 if (pkt
->size
< s
->block_size
)
97 return AVERROR_INVALIDDATA
;
99 frame
->nb_samples
= dv_get_audio_sample_count(pkt
->data
+ 244, s
->is_pal
);
100 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
102 dst
= (int16_t *)frame
->data
[0];
104 for (i
= 0; i
< frame
->nb_samples
; i
++) {
105 const uint8_t *v
= &src
[s
->shuffle
[i
]];
108 *dst
++ = dv_audio_12to16((v
[0] << 4) | ((v
[2] >> 4) & 0x0f));
109 *dst
++ = dv_audio_12to16((v
[1] << 4) | ((v
[2] >> 0) & 0x0f));
111 *dst
++ = AV_RB16(&v
[0]);
112 *dst
++ = AV_RB16(&v
[s
->is_pal
? 4320 : 3600]);
118 return s
->block_size
;
121 const FFCodec ff_dvaudio_decoder
= {
123 CODEC_LONG_NAME("Ulead DV Audio"),
124 .p
.type
= AVMEDIA_TYPE_AUDIO
,
125 .p
.id
= AV_CODEC_ID_DVAUDIO
,
127 FF_CODEC_DECODE_CB(decode_frame
),
128 .p
.capabilities
= AV_CODEC_CAP_DR1
,
129 .priv_data_size
= sizeof(DVAudioContext
),