FFmpeg coverage


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