Coverage Report

Created: 2025-12-31 07:57

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
459k
{
51
459k
    static const uint8_t off[]   = {  2,  6,  8, 0,  4 };
52
459k
    static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
53
459k
    static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
54
459k
    static const uint8_t shuf3[] = { 18,  9, 27, 0, 36 };
55
56
459k
    static const uint8_t l_start[]          = { 0, 4, 9, 13, 18, 22, 27, 31, 36, 40 };
57
459k
    static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
58
59
459k
    static const uint8_t serpent1[] = {
60
459k
        0, 1, 2, 2, 1, 0,
61
459k
        0, 1, 2, 2, 1, 0,
62
459k
        0, 1, 2, 2, 1, 0,
63
459k
        0, 1, 2, 2, 1, 0,
64
459k
        0, 1, 2
65
459k
    };
66
459k
    static const uint8_t serpent2[] = {
67
459k
        0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
68
459k
        0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
69
459k
        0, 1, 2, 3, 4, 5
70
459k
    };
71
72
459k
    static const uint8_t remap[][2] = {
73
459k
        {  0,  0 }, {  0,  0 }, {  0,  0 }, {  0,  0 }, /* dummy */
74
459k
        {  0,  0 }, {  0,  1 }, {  0,  2 }, {  0,  3 }, { 10,  0 },
75
459k
        { 10,  1 }, { 10,  2 }, { 10,  3 }, { 20,  0 }, { 20,  1 },
76
459k
        { 20,  2 }, { 20,  3 }, { 30,  0 }, { 30,  1 }, { 30,  2 },
77
459k
        { 30,  3 }, { 40,  0 }, { 40,  1 }, { 40,  2 }, { 40,  3 },
78
459k
        { 50,  0 }, { 50,  1 }, { 50,  2 }, { 50,  3 }, { 60,  0 },
79
459k
        { 60,  1 }, { 60,  2 }, { 60,  3 }, { 70,  0 }, { 70,  1 },
80
459k
        { 70,  2 }, { 70,  3 }, {  0, 64 }, {  0, 65 }, {  0, 66 },
81
459k
        { 10, 64 }, { 10, 65 }, { 10, 66 }, { 20, 64 }, { 20, 65 },
82
459k
        { 20, 66 }, { 30, 64 }, { 30, 65 }, { 30, 66 }, { 40, 64 },
83
459k
        { 40, 65 }, { 40, 66 }, { 50, 64 }, { 50, 65 }, { 50, 66 },
84
459k
        { 60, 64 }, { 60, 65 }, { 60, 66 }, { 70, 64 }, { 70, 65 },
85
459k
        { 70, 66 }, {  0, 67 }, { 20, 67 }, { 40, 67 }, { 60, 67 }
86
459k
    };
87
88
459k
    int i, k, m;
89
459k
    int x, y, blk;
90
91
2.75M
    for (m = 0; m < 5; m++) {
92
2.29M
        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
675k
        case 1280:
114
675k
            blk = (chan * 10 + seq) * 27 + slot;
115
116
675k
            i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10;
117
675k
            k = (blk / 5) % 27;
118
119
675k
            x = shuf1[m] + (chan & 1) * 9 + k % 9;
120
675k
            y = (i * 3 + k / 9) * 2 + (chan >> 1) + 4;
121
122
675k
            if (x >= 80) {
123
75.0k
                x = remap[y][0] + ((x - 80) << (y > 59));
124
75.0k
                y = remap[y][1];
125
75.0k
            }
126
675k
            tbl[m] = (x << 1) | (y << 9);
127
675k
            break;
128
291k
        case 960:
129
291k
            blk = (chan * 10 + seq) * 27 + slot;
130
131
291k
            i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10;
132
291k
            k = (blk / 5) % 27 + (i & 1) * 3;
133
134
291k
            x      = shuf2[m]   + k % 6 +  6 * (chan  & 1);
135
291k
            y      = l_start[i] + k / 6 + 45 * (chan >> 1);
136
291k
            tbl[m] = (x << 1) | (y << 9);
137
291k
            break;
138
1.29M
        case 720:
139
1.29M
            switch (d->pix_fmt) {
140
52.9k
            case AV_PIX_FMT_YUV422P:
141
52.9k
                x = shuf3[m] + slot / 3;
142
52.9k
                y = serpent1[slot] +
143
52.9k
                    ((((seq + off[m]) % d->difseg_size) << 1) + chan) * 3;
144
52.9k
                tbl[m] = (x << 1) | (y << 8);
145
52.9k
                break;
146
29.1k
            case AV_PIX_FMT_YUV420P:
147
29.1k
                x = shuf3[m] + slot / 3;
148
29.1k
                y = serpent1[slot] +
149
29.1k
                    ((seq + off[m]) % d->difseg_size) * 3;
150
29.1k
                tbl[m] = (x << 1) | (y << 9);
151
29.1k
                break;
152
1.21M
            case AV_PIX_FMT_YUV411P:
153
1.21M
                i = (seq + off[m]) % d->difseg_size;
154
1.21M
                k = slot + ((m == 1 || m == 2) ? 3 : 0);
155
156
1.21M
                x = l_start_shuffled[m] + k / 6;
157
1.21M
                y = serpent2[k] + i * 6;
158
1.21M
                if (x > 21)
159
26.9k
                    y = y * 2 - i * 6;
160
1.21M
                tbl[m] = (x << 2) | (y << 8);
161
1.21M
                break;
162
1.29M
            }
163
1.29M
        default:
164
1.29M
            break;
165
2.29M
        }
166
2.29M
    }
167
459k
}
168
169
void ff_dv_init_dynamic_tables(DVwork_chunk *work_chunks, const AVDVProfile *d)
170
1.16k
{
171
1.16k
    int j, i, c, s, p;
172
173
1.16k
    p = i = 0;
174
2.85k
    for (c = 0; c < d->n_difchan; c++) {
175
18.7k
        for (s = 0; s < d->difseg_size; s++) {
176
17.1k
            p += 6;
177
478k
            for (j = 0; j < 27; j++) {
178
461k
                p += !(j % 3);
179
461k
                if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
180
461k
                    !(DV_PROFILE_IS_720p50(d) && s > 9)) {
181
459k
                    dv_calc_mb_coordinates(d, c, s, j, &work_chunks[i].mb_coordinates[0]);
182
459k
                    work_chunks[i++].buf_offset = p;
183
459k
                }
184
461k
                p += 5;
185
461k
            }
186
17.1k
        }
187
1.68k
    }
188
1.16k
}