/src/ffmpeg/libavcodec/dsddec.c
Line | Count | Source |
1 | | /* |
2 | | * Direct Stream Digital (DSD) decoder |
3 | | * Copyright (c) 2014 Peter Ross |
4 | | * |
5 | | * This file is part of FFmpeg. |
6 | | * |
7 | | * FFmpeg is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2.1 of the License, or (at your option) any later version. |
11 | | * |
12 | | * FFmpeg is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with FFmpeg; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | /** |
23 | | * @file |
24 | | * Direct Stream Digital (DSD) decoder |
25 | | */ |
26 | | |
27 | | #include "config.h" |
28 | | |
29 | | #include <string.h> |
30 | | |
31 | | #include "libavutil/avassert.h" |
32 | | #include "libavutil/mem.h" |
33 | | #include "libavutil/reverse.h" |
34 | | |
35 | | #include "avcodec.h" |
36 | | #include "codec_internal.h" |
37 | | #include "decode.h" |
38 | | #include "dsd.h" |
39 | | |
40 | | #if CONFIG_SWRESAMPLE && FF_API_DSD_PCM |
41 | | #include "libswresample/swresample.h" |
42 | | |
43 | | typedef struct DSDDecContext { |
44 | | struct SwrContext *swr; |
45 | | uint8_t *scratch; |
46 | | unsigned scratch_size; |
47 | | } DSDDecContext; |
48 | | |
49 | | #define PRIV_DATA_SIZE sizeof(DSDDecContext) |
50 | | #else |
51 | | #define PRIV_DATA_SIZE 0 |
52 | | #endif |
53 | | |
54 | | static av_cold int decode_init(AVCodecContext *avctx) |
55 | 2.35k | { |
56 | 2.35k | if (!avctx->ch_layout.nb_channels) |
57 | 0 | return AVERROR_INVALIDDATA; |
58 | | |
59 | 2.35k | avctx->sample_fmt = AV_SAMPLE_FMT_DSD; |
60 | | |
61 | 2.35k | #if CONFIG_SWRESAMPLE && FF_API_DSD_PCM |
62 | 2.35k | if (avctx->request_sample_fmt != AV_SAMPLE_FMT_DSD) |
63 | 2.35k | avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; |
64 | 2.35k | #endif |
65 | | |
66 | 2.35k | return 0; |
67 | 2.35k | } |
68 | | |
69 | | static av_cold int decode_close(AVCodecContext *avctx) |
70 | 2.35k | { |
71 | 2.35k | #if CONFIG_SWRESAMPLE && FF_API_DSD_PCM |
72 | 2.35k | DSDDecContext *s = avctx->priv_data; |
73 | | |
74 | 2.35k | swr_free(&s->swr); |
75 | 2.35k | av_freep(&s->scratch); |
76 | 2.35k | #endif |
77 | 2.35k | return 0; |
78 | 2.35k | } |
79 | | |
80 | | // repack the input to interleaved DSD bytes, most significant bit first |
81 | | static void repack(AVCodecContext *avctx, uint8_t *dst, const uint8_t *src, |
82 | | int nb_samples) |
83 | 707k | { |
84 | 707k | const int channels = avctx->ch_layout.nb_channels; |
85 | | |
86 | 707k | switch (avctx->codec_id) { |
87 | 244k | case AV_CODEC_ID_DSD_MSBF: |
88 | 244k | memcpy(dst, src, nb_samples * channels); |
89 | 244k | break; |
90 | 160k | case AV_CODEC_ID_DSD_LSBF: |
91 | 17.8M | for (int i = 0; i < nb_samples * channels; i++) |
92 | 17.7M | dst[i] = ff_reverse[src[i]]; |
93 | 160k | break; |
94 | 164k | case AV_CODEC_ID_DSD_MSBF_PLANAR: |
95 | 376k | for (int ch = 0; ch < channels; ch++) { |
96 | 211k | const uint8_t *plane = src + ch * nb_samples; |
97 | 17.3M | for (int i = 0; i < nb_samples; i++) |
98 | 17.1M | dst[i * channels + ch] = plane[i]; |
99 | 211k | } |
100 | 164k | break; |
101 | 138k | case AV_CODEC_ID_DSD_LSBF_PLANAR: |
102 | 308k | for (int ch = 0; ch < channels; ch++) { |
103 | 169k | const uint8_t *plane = src + ch * nb_samples; |
104 | 16.6M | for (int i = 0; i < nb_samples; i++) |
105 | 16.5M | dst[i * channels + ch] = ff_reverse[plane[i]]; |
106 | 169k | } |
107 | 138k | break; |
108 | 0 | default: |
109 | 0 | av_assert1(0); |
110 | 707k | } |
111 | 707k | } |
112 | | |
113 | | static int decode_frame(AVCodecContext *avctx, AVFrame *frame, |
114 | | int *got_frame_ptr, AVPacket *avpkt) |
115 | 1.39M | { |
116 | 1.39M | const int channels = avctx->ch_layout.nb_channels; |
117 | 1.39M | int ret; |
118 | | |
119 | 1.39M | frame->nb_samples = avpkt->size / channels; |
120 | | |
121 | 1.39M | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
122 | 668k | return ret; |
123 | | |
124 | 725k | #if CONFIG_SWRESAMPLE && FF_API_DSD_PCM |
125 | 725k | DSDDecContext *s = avctx->priv_data; |
126 | 725k | if (avctx->sample_fmt != AV_SAMPLE_FMT_DSD) { |
127 | 725k | if (!s->swr && (ret = ff_dsd_to_pcm_init(avctx, &s->swr)) < 0) |
128 | 17.9k | return ret; |
129 | | |
130 | 707k | av_fast_malloc(&s->scratch, &s->scratch_size, |
131 | 707k | frame->nb_samples * channels); |
132 | 707k | if (!s->scratch) |
133 | 0 | return AVERROR(ENOMEM); |
134 | | |
135 | 707k | repack(avctx, s->scratch, avpkt->data, frame->nb_samples); |
136 | | |
137 | 707k | ret = swr_convert(s->swr, frame->extended_data, frame->nb_samples, |
138 | 707k | (const uint8_t *const []){ s->scratch }, |
139 | 707k | frame->nb_samples); |
140 | 707k | if (ret != frame->nb_samples) |
141 | 0 | return ret < 0 ? ret : AVERROR_BUG; |
142 | | |
143 | 707k | *got_frame_ptr = 1; |
144 | 707k | return frame->nb_samples * channels; |
145 | 707k | } |
146 | 0 | #endif |
147 | | |
148 | 0 | repack(avctx, frame->data[0], avpkt->data, frame->nb_samples); |
149 | |
|
150 | 0 | *got_frame_ptr = 1; |
151 | 0 | return frame->nb_samples * channels; |
152 | 725k | } |
153 | | |
154 | | #define DSD_DECODER(id_, name_, long_name_) \ |
155 | | const FFCodec ff_ ## name_ ## _decoder = { \ |
156 | | .p.name = #name_, \ |
157 | | CODEC_LONG_NAME(long_name_), \ |
158 | | .p.type = AVMEDIA_TYPE_AUDIO, \ |
159 | | .p.id = AV_CODEC_ID_##id_, \ |
160 | | .priv_data_size = PRIV_DATA_SIZE, \ |
161 | | .init = decode_init, \ |
162 | | .close = decode_close, \ |
163 | | FF_CODEC_DECODE_CB(decode_frame), \ |
164 | | .p.capabilities = AV_CODEC_CAP_DR1, \ |
165 | | }; |
166 | | |
167 | | DSD_DECODER(DSD_LSBF, dsd_lsbf, "DSD (Direct Stream Digital), least significant bit first") |
168 | | DSD_DECODER(DSD_MSBF, dsd_msbf, "DSD (Direct Stream Digital), most significant bit first") |
169 | | DSD_DECODER(DSD_MSBF_PLANAR, dsd_msbf_planar, "DSD (Direct Stream Digital), most significant bit first, planar") |
170 | | DSD_DECODER(DSD_LSBF_PLANAR, dsd_lsbf_planar, "DSD (Direct Stream Digital), least significant bit first, planar") |