blob: 2c5c357acc51fa86740e37d142b95d77077d8e85
1 | /* |
2 | * Direct Stream Digital (DSD) decoder |
3 | * based on BSD licensed dsd2pcm by Sebastian Gesemann |
4 | * Copyright (c) 2009, 2011 Sebastian Gesemann. All rights reserved. |
5 | * Copyright (c) 2014 Peter Ross |
6 | * |
7 | * This file is part of FFmpeg. |
8 | * |
9 | * FFmpeg is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU Lesser General Public |
11 | * License as published by the Free Software Foundation; either |
12 | * version 2.1 of the License, or (at your option) any later version. |
13 | * |
14 | * FFmpeg is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * Lesser General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Lesser General Public |
20 | * License along with FFmpeg; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | */ |
23 | |
24 | /** |
25 | * @file |
26 | * Direct Stream Digital (DSD) decoder |
27 | */ |
28 | |
29 | #include "libavcodec/internal.h" |
30 | #include "libavcodec/mathops.h" |
31 | #include "avcodec.h" |
32 | #include "dsd.h" |
33 | |
34 | #define DSD_SILENCE 0x69 |
35 | /* 0x69 = 01101001 |
36 | * This pattern "on repeat" makes a low energy 352.8 kHz tone |
37 | * and a high energy 1.0584 MHz tone which should be filtered |
38 | * out completely by any playback system --> silence |
39 | */ |
40 | |
41 | static av_cold int decode_init(AVCodecContext *avctx) |
42 | { |
43 | DSDContext * s; |
44 | int i; |
45 | uint8_t silence; |
46 | |
47 | ff_init_dsd_data(); |
48 | |
49 | s = av_malloc_array(sizeof(DSDContext), avctx->channels); |
50 | if (!s) |
51 | return AVERROR(ENOMEM); |
52 | |
53 | silence = avctx->codec_id == AV_CODEC_ID_DSD_LSBF || avctx->codec_id == AV_CODEC_ID_DSD_LSBF_PLANAR ? ff_reverse[DSD_SILENCE] : DSD_SILENCE; |
54 | for (i = 0; i < avctx->channels; i++) { |
55 | s[i].pos = 0; |
56 | memset(s[i].buf, silence, sizeof(s[i].buf)); |
57 | } |
58 | |
59 | avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; |
60 | avctx->priv_data = s; |
61 | return 0; |
62 | } |
63 | |
64 | static int decode_frame(AVCodecContext *avctx, void *data, |
65 | int *got_frame_ptr, AVPacket *avpkt) |
66 | { |
67 | DSDContext * s = avctx->priv_data; |
68 | AVFrame *frame = data; |
69 | int ret, i; |
70 | int lsbf = avctx->codec_id == AV_CODEC_ID_DSD_LSBF || avctx->codec_id == AV_CODEC_ID_DSD_LSBF_PLANAR; |
71 | int src_next; |
72 | int src_stride; |
73 | |
74 | frame->nb_samples = avpkt->size / avctx->channels; |
75 | |
76 | if (avctx->codec_id == AV_CODEC_ID_DSD_LSBF_PLANAR || avctx->codec_id == AV_CODEC_ID_DSD_MSBF_PLANAR) { |
77 | src_next = frame->nb_samples; |
78 | src_stride = 1; |
79 | } else { |
80 | src_next = 1; |
81 | src_stride = avctx->channels; |
82 | } |
83 | |
84 | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
85 | return ret; |
86 | |
87 | for (i = 0; i < avctx->channels; i++) { |
88 | float * dst = ((float **)frame->extended_data)[i]; |
89 | ff_dsd2pcm_translate(&s[i], frame->nb_samples, lsbf, |
90 | avpkt->data + i * src_next, src_stride, |
91 | dst, 1); |
92 | } |
93 | |
94 | *got_frame_ptr = 1; |
95 | return frame->nb_samples * avctx->channels; |
96 | } |
97 | |
98 | #define DSD_DECODER(id_, name_, long_name_) \ |
99 | AVCodec ff_##name_##_decoder = { \ |
100 | .name = #name_, \ |
101 | .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ |
102 | .type = AVMEDIA_TYPE_AUDIO, \ |
103 | .id = AV_CODEC_ID_##id_, \ |
104 | .init = decode_init, \ |
105 | .decode = decode_frame, \ |
106 | .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, \ |
107 | AV_SAMPLE_FMT_NONE }, \ |
108 | }; |
109 | |
110 | DSD_DECODER(DSD_LSBF, dsd_lsbf, "DSD (Direct Stream Digital), least significant bit first") |
111 | DSD_DECODER(DSD_MSBF, dsd_msbf, "DSD (Direct Stream Digital), most significant bit first") |
112 | DSD_DECODER(DSD_MSBF_PLANAR, dsd_msbf_planar, "DSD (Direct Stream Digital), most significant bit first, planar") |
113 | DSD_DECODER(DSD_LSBF_PLANAR, dsd_lsbf_planar, "DSD (Direct Stream Digital), least significant bit first, planar") |
114 |