Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * TTA (The Lossless True Audio) encoder
3
 *
4
 * This file is part of FFmpeg.
5
 *
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.
10
 *
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.
15
 *
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
19
 */
20
 
21
#define BITSTREAM_WRITER_LE
22
#include "ttadata.h"
23
#include "avcodec.h"
24
#include "put_bits.h"
25
#include "internal.h"
26
#include "libavutil/crc.h"
27
 
28
typedef struct TTAEncContext {
29
    const AVCRC *crc_table;
30
    int bps;
31
    TTAChannel *ch_ctx;
32
} TTAEncContext;
33
 
34
static av_cold int tta_encode_init(AVCodecContext *avctx)
35
{
36
    TTAEncContext *s = avctx->priv_data;
37
 
38
    s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
39
 
40
    switch (avctx->sample_fmt) {
41
    case AV_SAMPLE_FMT_U8:
42
        avctx->bits_per_raw_sample = 8;
43
        break;
44
    case AV_SAMPLE_FMT_S16:
45
        avctx->bits_per_raw_sample = 16;
46
        break;
47
    case AV_SAMPLE_FMT_S32:
48
        if (avctx->bits_per_raw_sample > 24)
49
            av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
50
        avctx->bits_per_raw_sample = 24;
51
    }
52
 
53
    s->bps = avctx->bits_per_raw_sample >> 3;
54
    avctx->frame_size = 256 * avctx->sample_rate / 245;
55
 
56
    s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx));
57
    if (!s->ch_ctx)
58
        return AVERROR(ENOMEM);
59
 
60
    return 0;
61
}
62
 
63
static inline void ttafilter_process(TTAFilter *c, int32_t *in)
64
{
65
    register int32_t *dl = c->dl, *qm = c->qm, *dx = c->dx, sum = c->round;
66
 
67
    if (c->error < 0) {
68
        qm[0] -= dx[0]; qm[1] -= dx[1]; qm[2] -= dx[2]; qm[3] -= dx[3];
69
        qm[4] -= dx[4]; qm[5] -= dx[5]; qm[6] -= dx[6]; qm[7] -= dx[7];
70
    } else if (c->error > 0) {
71
        qm[0] += dx[0]; qm[1] += dx[1]; qm[2] += dx[2]; qm[3] += dx[3];
72
        qm[4] += dx[4]; qm[5] += dx[5]; qm[6] += dx[6]; qm[7] += dx[7];
73
    }
74
 
75
    sum += dl[0] * qm[0] + dl[1] * qm[1] + dl[2] * qm[2] + dl[3] * qm[3] +
76
           dl[4] * qm[4] + dl[5] * qm[5] + dl[6] * qm[6] + dl[7] * qm[7];
77
 
78
    dx[0] = dx[1]; dx[1] = dx[2]; dx[2] = dx[3]; dx[3] = dx[4];
79
    dl[0] = dl[1]; dl[1] = dl[2]; dl[2] = dl[3]; dl[3] = dl[4];
80
 
81
    dx[4] = ((dl[4] >> 30) | 1);
82
    dx[5] = ((dl[5] >> 30) | 2) & ~1;
83
    dx[6] = ((dl[6] >> 30) | 2) & ~1;
84
    dx[7] = ((dl[7] >> 30) | 4) & ~3;
85
 
86
    dl[4] = -dl[5]; dl[5] = -dl[6];
87
    dl[6] = *in - dl[7]; dl[7] = *in;
88
    dl[5] += dl[6]; dl[4] += dl[5];
89
 
90
    *in -= (sum >> c->shift);
91
    c->error = *in;
92
}
93
 
94
static int32_t get_sample(const AVFrame *frame, int sample,
95
                          enum AVSampleFormat format)
96
{
97
    int32_t ret;
98
 
99
    if (format == AV_SAMPLE_FMT_U8) {
100
        ret = frame->data[0][sample] - 0x80;
101
    } else if (format == AV_SAMPLE_FMT_S16) {
102
        const int16_t *ptr = (const int16_t *)frame->data[0];
103
        ret = ptr[sample];
104
    } else {
105
        const int32_t *ptr = (const int32_t *)frame->data[0];
106
        ret = ptr[sample] >> 8;
107
    }
108
 
109
    return ret;
110
}
111
 
112
static int tta_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
113
                            const AVFrame *frame, int *got_packet_ptr)
114
{
115
    TTAEncContext *s = avctx->priv_data;
116
    PutBitContext pb;
117
    int ret, i, out_bytes, cur_chan = 0, res = 0, samples = 0;
118
 
119
    if ((ret = ff_alloc_packet2(avctx, avpkt, frame->nb_samples * 2 * avctx->channels * s->bps)) < 0)
120
        return ret;
121
    init_put_bits(&pb, avpkt->data, avpkt->size);
122
 
123
    // init per channel states
124
    for (i = 0; i < avctx->channels; i++) {
125
        s->ch_ctx[i].predictor = 0;
126
        ff_tta_filter_init(&s->ch_ctx[i].filter, ff_tta_filter_configs[s->bps - 1]);
127
        ff_tta_rice_init(&s->ch_ctx[i].rice, 10, 10);
128
    }
129
 
130
    for (i = 0; i < frame->nb_samples * avctx->channels; i++) {
131
        TTAChannel *c = &s->ch_ctx[cur_chan];
132
        TTAFilter *filter = &c->filter;
133
        TTARice *rice = &c->rice;
134
        uint32_t k, unary, outval;
135
        int32_t value, temp;
136
 
137
        value = get_sample(frame, samples++, avctx->sample_fmt);
138
 
139
        if (avctx->channels > 1) {
140
            if (cur_chan < avctx->channels - 1)
141
                value  = res = get_sample(frame, samples, avctx->sample_fmt) - value;
142
            else
143
                value -= res / 2;
144
        }
145
 
146
        temp = value;
147
#define PRED(x, k) (int32_t)((((uint64_t)x << k) - x) >> k)
148
        switch (s->bps) {
149
        case 1: value -= PRED(c->predictor, 4); break;
150
        case 2:
151
        case 3: value -= PRED(c->predictor, 5); break;
152
        }
153
        c->predictor = temp;
154
 
155
        ttafilter_process(filter, &value);
156
        outval = (value > 0) ? (value << 1) - 1: -value << 1;
157
 
158
        k = rice->k0;
159
 
160
        rice->sum0 += outval - (rice->sum0 >> 4);
161
        if (rice->k0 > 0 && rice->sum0 < ff_tta_shift_16[rice->k0])
162
            rice->k0--;
163
        else if (rice->sum0 > ff_tta_shift_16[rice->k0 + 1])
164
            rice->k0++;
165
 
166
        if (outval >= ff_tta_shift_1[k]) {
167
            outval -= ff_tta_shift_1[k];
168
            k = rice->k1;
169
 
170
            rice->sum1 += outval - (rice->sum1 >> 4);
171
            if (rice->k1 > 0 && rice->sum1 < ff_tta_shift_16[rice->k1])
172
                rice->k1--;
173
            else if (rice->sum1 > ff_tta_shift_16[rice->k1 + 1])
174
                rice->k1++;
175
 
176
            unary = 1 + (outval >> k);
177
            do {
178
                if (unary > 31) {
179
                    put_bits(&pb, 31, 0x7FFFFFFF);
180
                    unary -= 31;
181
                } else {
182
                    put_bits(&pb, unary, (1 << unary) - 1);
183
                    unary = 0;
184
                }
185
            } while (unary);
186
        }
187
 
188
        put_bits(&pb, 1, 0);
189
 
190
        if (k)
191
            put_bits(&pb, k, outval & (ff_tta_shift_1[k] - 1));
192
 
193
        if (cur_chan < avctx->channels - 1)
194
            cur_chan++;
195
        else
196
            cur_chan = 0;
197
    }
198
 
199
    flush_put_bits(&pb);
200
    out_bytes = put_bits_count(&pb) >> 3;
201
    put_bits32(&pb, av_crc(s->crc_table, UINT32_MAX, avpkt->data, out_bytes) ^ UINT32_MAX);
202
    flush_put_bits(&pb);
203
 
204
    avpkt->pts      = frame->pts;
205
    avpkt->size     = out_bytes + 4;
206
    avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
207
    *got_packet_ptr = 1;
208
    return 0;
209
}
210
 
211
static av_cold int tta_encode_close(AVCodecContext *avctx)
212
{
213
    TTAEncContext *s = avctx->priv_data;
214
    av_freep(&s->ch_ctx);
215
    return 0;
216
}
217
 
218
AVCodec ff_tta_encoder = {
219
    .name           = "tta",
220
    .long_name      = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
221
    .type           = AVMEDIA_TYPE_AUDIO,
222
    .id             = AV_CODEC_ID_TTA,
223
    .priv_data_size = sizeof(TTAEncContext),
224
    .init           = tta_encode_init,
225
    .close          = tta_encode_close,
226
    .encode2        = tta_encode_frame,
227
    .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_LOSSLESS,
228
    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8,
229
                                                     AV_SAMPLE_FMT_S16,
230
                                                     AV_SAMPLE_FMT_S32,
231
                                                     AV_SAMPLE_FMT_NONE },
232
};