FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/ttaenc.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 85 103 82.5%
Functions: 4 4 100.0%
Branches: 39 53 73.6%

Line Branch Exec Source
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 "ttaencdsp.h"
24 #include "avcodec.h"
25 #include "codec_internal.h"
26 #include "encode.h"
27 #include "put_bits.h"
28 #include "libavutil/crc.h"
29 #include "libavutil/mem.h"
30
31 typedef struct TTAEncContext {
32 const AVCRC *crc_table;
33 int bps;
34 TTAChannel *ch_ctx;
35 TTAEncDSPContext dsp;
36 } TTAEncContext;
37
38 3 static av_cold int tta_encode_init(AVCodecContext *avctx)
39 {
40 3 TTAEncContext *s = avctx->priv_data;
41
42 3 s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
43
44
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 switch (avctx->sample_fmt) {
45 case AV_SAMPLE_FMT_U8:
46 avctx->bits_per_raw_sample = 8;
47 break;
48 3 case AV_SAMPLE_FMT_S16:
49 3 avctx->bits_per_raw_sample = 16;
50 3 break;
51 case AV_SAMPLE_FMT_S32:
52 if (avctx->bits_per_raw_sample > 24)
53 av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
54 avctx->bits_per_raw_sample = 24;
55 }
56
57 3 s->bps = avctx->bits_per_raw_sample >> 3;
58 3 avctx->frame_size = 256 * avctx->sample_rate / 245;
59
60 3 s->ch_ctx = av_malloc_array(avctx->ch_layout.nb_channels, sizeof(*s->ch_ctx));
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!s->ch_ctx)
62 return AVERROR(ENOMEM);
63
64 3 ff_ttaencdsp_init(&s->dsp);
65
66 3 return 0;
67 }
68
69 882000 static int32_t get_sample(const AVFrame *frame, int sample,
70 enum AVSampleFormat format)
71 {
72 int32_t ret;
73
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 882000 times.
882000 if (format == AV_SAMPLE_FMT_U8) {
75 ret = frame->data[0][sample] - 0x80;
76
1/2
✓ Branch 0 taken 882000 times.
✗ Branch 1 not taken.
882000 } else if (format == AV_SAMPLE_FMT_S16) {
77 882000 const int16_t *ptr = (const int16_t *)frame->data[0];
78 882000 ret = ptr[sample];
79 } else {
80 const int32_t *ptr = (const int32_t *)frame->data[0];
81 ret = ptr[sample] >> 8;
82 }
83
84 882000 return ret;
85 }
86
87 8 static int tta_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
88 const AVFrame *frame, int *got_packet_ptr)
89 {
90 8 TTAEncContext *s = avctx->priv_data;
91 PutBitContext pb;
92 int ret, i, out_bytes, cur_chan, res, samples;
93 8 int64_t pkt_size = frame->nb_samples * 2LL * avctx->ch_layout.nb_channels * s->bps;
94
95 8 pkt_alloc:
96 8 cur_chan = 0, res = 0, samples = 0;
97
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if ((ret = ff_alloc_packet(avctx, avpkt, pkt_size)) < 0)
98 return ret;
99 8 init_put_bits(&pb, avpkt->data, avpkt->size);
100
101 // init per channel states
102
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 8 times.
22 for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
103 14 s->ch_ctx[i].predictor = 0;
104 14 ff_tta_filter_init(&s->ch_ctx[i].filter, ff_tta_filter_configs[s->bps - 1]);
105 14 ff_tta_rice_init(&s->ch_ctx[i].rice, 10, 10);
106 }
107
108
2/2
✓ Branch 0 taken 617400 times.
✓ Branch 1 taken 8 times.
617408 for (i = 0; i < frame->nb_samples * avctx->ch_layout.nb_channels; i++) {
109 617400 TTAChannel *c = &s->ch_ctx[cur_chan];
110 617400 TTAFilter *filter = &c->filter;
111 617400 TTARice *rice = &c->rice;
112 uint32_t k, unary, outval;
113 int32_t value, temp;
114
115 617400 value = get_sample(frame, samples++, avctx->sample_fmt);
116
117
2/2
✓ Branch 0 taken 529200 times.
✓ Branch 1 taken 88200 times.
617400 if (avctx->ch_layout.nb_channels > 1) {
118
2/2
✓ Branch 0 taken 264600 times.
✓ Branch 1 taken 264600 times.
529200 if (cur_chan < avctx->ch_layout.nb_channels - 1)
119 264600 value = res = get_sample(frame, samples, avctx->sample_fmt) - value;
120 else
121 264600 value -= res / 2;
122 }
123
124 617400 temp = value;
125 #define PRED(x, k) (int32_t)((((uint64_t)(x) << (k)) - (x)) >> (k))
126
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 617400 times.
✗ Branch 2 not taken.
617400 switch (s->bps) {
127 case 1: value -= PRED(c->predictor, 4); break;
128 617400 case 2:
129 617400 case 3: value -= PRED(c->predictor, 5); break;
130 }
131 617400 c->predictor = temp;
132
133 617400 s->dsp.filter_process(filter->qm, filter->dx, filter->dl, &filter->error, &value,
134 filter->shift, filter->round);
135
2/2
✓ Branch 0 taken 223671 times.
✓ Branch 1 taken 393729 times.
617400 outval = (value > 0) ? (value << 1) - 1: -value << 1;
136
137 617400 k = rice->k0;
138
139 617400 rice->sum0 += outval - (rice->sum0 >> 4);
140
4/4
✓ Branch 0 taken 483852 times.
✓ Branch 1 taken 133548 times.
✓ Branch 2 taken 17694 times.
✓ Branch 3 taken 466158 times.
617400 if (rice->k0 > 0 && rice->sum0 < ff_tta_shift_16[rice->k0])
141 17694 rice->k0--;
142
2/2
✓ Branch 0 taken 17600 times.
✓ Branch 1 taken 582106 times.
599706 else if (rice->sum0 > ff_tta_shift_16[rice->k0 + 1])
143 17600 rice->k0++;
144
145
2/2
✓ Branch 0 taken 257183 times.
✓ Branch 1 taken 360217 times.
617400 if (outval >= ff_tta_shift_1[k]) {
146 257183 outval -= ff_tta_shift_1[k];
147 257183 k = rice->k1;
148
149 257183 rice->sum1 += outval - (rice->sum1 >> 4);
150
4/4
✓ Branch 0 taken 253882 times.
✓ Branch 1 taken 3301 times.
✓ Branch 2 taken 7967 times.
✓ Branch 3 taken 245915 times.
257183 if (rice->k1 > 0 && rice->sum1 < ff_tta_shift_16[rice->k1])
151 7967 rice->k1--;
152
2/2
✓ Branch 0 taken 7889 times.
✓ Branch 1 taken 241327 times.
249216 else if (rice->sum1 > ff_tta_shift_16[rice->k1 + 1])
153 7889 rice->k1++;
154
155 257183 unary = 1 + (outval >> k);
156
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 257183 times.
257183 if (unary + 100LL > put_bits_left(&pb)) {
157 if (pkt_size < INT_MAX/2) {
158 pkt_size *= 2;
159 av_packet_unref(avpkt);
160 goto pkt_alloc;
161 } else
162 return AVERROR(ENOMEM);
163 }
164 do {
165
2/2
✓ Branch 0 taken 580 times.
✓ Branch 1 taken 257183 times.
257763 if (unary > 31) {
166 580 put_bits(&pb, 31, 0x7FFFFFFF);
167 580 unary -= 31;
168 } else {
169 257183 put_bits(&pb, unary, (1U << unary) - 1);
170 257183 unary = 0;
171 }
172
2/2
✓ Branch 0 taken 580 times.
✓ Branch 1 taken 257183 times.
257763 } while (unary);
173 }
174
175 617400 put_bits(&pb, 1, 0);
176
177
2/2
✓ Branch 0 taken 481630 times.
✓ Branch 1 taken 135770 times.
617400 if (k)
178 481630 put_bits(&pb, k, outval & (ff_tta_shift_1[k] - 1));
179
180
2/2
✓ Branch 0 taken 264600 times.
✓ Branch 1 taken 352800 times.
617400 if (cur_chan < avctx->ch_layout.nb_channels - 1)
181 264600 cur_chan++;
182 else
183 352800 cur_chan = 0;
184 }
185
186 8 flush_put_bits(&pb);
187 8 out_bytes = put_bytes_output(&pb);
188 8 put_bits32(&pb, av_crc(s->crc_table, UINT32_MAX, avpkt->data, out_bytes) ^ UINT32_MAX);
189 8 flush_put_bits(&pb);
190
191 8 avpkt->size = out_bytes + 4;
192 8 *got_packet_ptr = 1;
193 8 return 0;
194 }
195
196 3 static av_cold int tta_encode_close(AVCodecContext *avctx)
197 {
198 3 TTAEncContext *s = avctx->priv_data;
199 3 av_freep(&s->ch_ctx);
200 3 return 0;
201 }
202
203 const FFCodec ff_tta_encoder = {
204 .p.name = "tta",
205 CODEC_LONG_NAME("TTA (True Audio)"),
206 .p.type = AVMEDIA_TYPE_AUDIO,
207 .p.id = AV_CODEC_ID_TTA,
208 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
209 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
210 .priv_data_size = sizeof(TTAEncContext),
211 .init = tta_encode_init,
212 .close = tta_encode_close,
213 FF_CODEC_ENCODE_CB(tta_encode_frame),
214 .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8,
215 AV_SAMPLE_FMT_S16,
216 AV_SAMPLE_FMT_S32,
217 AV_SAMPLE_FMT_NONE },
218 };
219