Coverage Report

Created: 2026-01-16 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/dv.c
Line
Count
Source
1
/*
2
 * DV decoder
3
 * Copyright (c) 2002 Fabrice Bellard
4
 * Copyright (c) 2004 Roman Shaposhnik
5
 *
6
 * DV encoder
7
 * Copyright (c) 2003 Roman Shaposhnik
8
 *
9
 * 50 Mbps (DVCPRO50) support
10
 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
11
 *
12
 * 100 Mbps (DVCPRO HD) support
13
 * Initial code by Daniel Maas <dmaas@maasdigital.com> (funded by BBC R&D)
14
 * Final code by Roman Shaposhnik
15
 *
16
 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
17
 * of DV technical info.
18
 *
19
 * This file is part of FFmpeg.
20
 *
21
 * FFmpeg is free software; you can redistribute it and/or
22
 * modify it under the terms of the GNU Lesser General Public
23
 * License as published by the Free Software Foundation; either
24
 * version 2.1 of the License, or (at your option) any later version.
25
 *
26
 * FFmpeg is distributed in the hope that it will be useful,
27
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29
 * Lesser General Public License for more details.
30
 *
31
 * You should have received a copy of the GNU Lesser General Public
32
 * License along with FFmpeg; if not, write to the Free Software
33
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
34
 */
35
36
/**
37
 * @file
38
 * DV codec.
39
 */
40
41
#include <stdint.h>
42
43
#include "libavutil/pixfmt.h"
44
45
#include "dv_internal.h"
46
#include "dv_profile.h"
47
48
static inline void dv_calc_mb_coordinates(const AVDVProfile *d, int chan,
49
                                          int seq, int slot, uint16_t *tbl)
50
442k
{
51
442k
    static const uint8_t off[]   = {  2,  6,  8, 0,  4 };
52
442k
    static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
53
442k
    static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
54
442k
    static const uint8_t shuf3[] = { 18,  9, 27, 0, 36 };
55
56
442k
    static const uint8_t l_start[]          = { 0, 4, 9, 13, 18, 22, 27, 31, 36, 40 };
57
442k
    static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
58
59
442k
    static const uint8_t serpent1[] = {
60
442k
        0, 1, 2, 2, 1, 0,
61
442k
        0, 1, 2, 2, 1, 0,
62
442k
        0, 1, 2, 2, 1, 0,
63
442k
        0, 1, 2, 2, 1, 0,
64
442k
        0, 1, 2
65
442k
    };
66
442k
    static const uint8_t serpent2[] = {
67
442k
        0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
68
442k
        0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
69
442k
        0, 1, 2, 3, 4, 5
70
442k
    };
71
72
442k
    static const uint8_t remap[][2] = {
73
442k
        {  0,  0 }, {  0,  0 }, {  0,  0 }, {  0,  0 }, /* dummy */
74
442k
        {  0,  0 }, {  0,  1 }, {  0,  2 }, {  0,  3 }, { 10,  0 },
75
442k
        { 10,  1 }, { 10,  2 }, { 10,  3 }, { 20,  0 }, { 20,  1 },
76
442k
        { 20,  2 }, { 20,  3 }, { 30,  0 }, { 30,  1 }, { 30,  2 },
77
442k
        { 30,  3 }, { 40,  0 }, { 40,  1 }, { 40,  2 }, { 40,  3 },
78
442k
        { 50,  0 }, { 50,  1 }, { 50,  2 }, { 50,  3 }, { 60,  0 },
79
442k
        { 60,  1 }, { 60,  2 }, { 60,  3 }, { 70,  0 }, { 70,  1 },
80
442k
        { 70,  2 }, { 70,  3 }, {  0, 64 }, {  0, 65 }, {  0, 66 },
81
442k
        { 10, 64 }, { 10, 65 }, { 10, 66 }, { 20, 64 }, { 20, 65 },
82
442k
        { 20, 66 }, { 30, 64 }, { 30, 65 }, { 30, 66 }, { 40, 64 },
83
442k
        { 40, 65 }, { 40, 66 }, { 50, 64 }, { 50, 65 }, { 50, 66 },
84
442k
        { 60, 64 }, { 60, 65 }, { 60, 66 }, { 70, 64 }, { 70, 65 },
85
442k
        { 70, 66 }, {  0, 67 }, { 20, 67 }, { 40, 67 }, { 60, 67 }
86
442k
    };
87
88
442k
    int i, k, m;
89
442k
    int x, y, blk;
90
91
2.65M
    for (m = 0; m < 5; m++) {
92
2.21M
        switch (d->width) {
93
36.4k
        case 1440:
94
36.4k
            blk = (chan * 11 + seq) * 27 + slot;
95
96
36.4k
            if (chan == 0 && seq == 11) {
97
810
                x = m * 27 + slot;
98
810
                if (x < 90) {
99
540
                    y = 0;
100
540
                } else {
101
270
                    x = (x - 90) * 2;
102
270
                    y = 67;
103
270
                }
104
35.6k
            } else {
105
35.6k
                i = (4 * chan + blk + off[m]) % 11;
106
35.6k
                k = (blk / 11) % 27;
107
108
35.6k
                x = shuf1[m] + (chan & 1) * 9 + k % 9;
109
35.6k
                y = (i * 3 + k / 9) * 2 + (chan >> 1) + 1;
110
35.6k
            }
111
36.4k
            tbl[m] = (x << 1) | (y << 9);
112
36.4k
            break;
113
696k
        case 1280:
114
696k
            blk = (chan * 10 + seq) * 27 + slot;
115
116
696k
            i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10;
117
696k
            k = (blk / 5) % 27;
118
119
696k
            x = shuf1[m] + (chan & 1) * 9 + k % 9;
120
696k
            y = (i * 3 + k / 9) * 2 + (chan >> 1) + 4;
121
122
696k
            if (x >= 80) {
123
77.4k
                x = remap[y][0] + ((x - 80) << (y > 59));
124
77.4k
                y = remap[y][1];
125
77.4k
            }
126
696k
            tbl[m] = (x << 1) | (y << 9);
127
696k
            break;
128
264k
        case 960:
129
264k
            blk = (chan * 10 + seq) * 27 + slot;
130
131
264k
            i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10;
132
264k
            k = (blk / 5) % 27 + (i & 1) * 3;
133
134
264k
            x      = shuf2[m]   + k % 6 +  6 * (chan  & 1);
135
264k
            y      = l_start[i] + k / 6 + 45 * (chan >> 1);
136
264k
            tbl[m] = (x << 1) | (y << 9);
137
264k
            break;
138
1.21M
        case 720:
139
1.21M
            switch (d->pix_fmt) {
140
50.2k
            case AV_PIX_FMT_YUV422P:
141
50.2k
                x = shuf3[m] + slot / 3;
142
50.2k
                y = serpent1[slot] +
143
50.2k
                    ((((seq + off[m]) % d->difseg_size) << 1) + chan) * 3;
144
50.2k
                tbl[m] = (x << 1) | (y << 8);
145
50.2k
                break;
146
32.4k
            case AV_PIX_FMT_YUV420P:
147
32.4k
                x = shuf3[m] + slot / 3;
148
32.4k
                y = serpent1[slot] +
149
32.4k
                    ((seq + off[m]) % d->difseg_size) * 3;
150
32.4k
                tbl[m] = (x << 1) | (y << 9);
151
32.4k
                break;
152
1.12M
            case AV_PIX_FMT_YUV411P:
153
1.12M
                i = (seq + off[m]) % d->difseg_size;
154
1.12M
                k = slot + ((m == 1 || m == 2) ? 3 : 0);
155
156
1.12M
                x = l_start_shuffled[m] + k / 6;
157
1.12M
                y = serpent2[k] + i * 6;
158
1.12M
                if (x > 21)
159
25.1k
                    y = y * 2 - i * 6;
160
1.12M
                tbl[m] = (x << 2) | (y << 8);
161
1.12M
                break;
162
1.21M
            }
163
1.21M
        default:
164
1.21M
            break;
165
2.21M
        }
166
2.21M
    }
167
442k
}
168
169
void ff_dv_init_dynamic_tables(DVwork_chunk *work_chunks, const AVDVProfile *d)
170
1.10k
{
171
1.10k
    int j, i, c, s, p;
172
173
1.10k
    p = i = 0;
174
2.72k
    for (c = 0; c < d->n_difchan; c++) {
175
18.0k
        for (s = 0; s < d->difseg_size; s++) {
176
16.4k
            p += 6;
177
460k
            for (j = 0; j < 27; j++) {
178
444k
                p += !(j % 3);
179
444k
                if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
180
443k
                    !(DV_PROFILE_IS_720p50(d) && s > 9)) {
181
442k
                    dv_calc_mb_coordinates(d, c, s, j, &work_chunks[i].mb_coordinates[0]);
182
442k
                    work_chunks[i++].buf_offset = p;
183
442k
                }
184
444k
                p += 5;
185
444k
            }
186
16.4k
        }
187
1.62k
    }
188
1.10k
}