Coverage Report

Created: 2026-01-16 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/evc_parse.c
Line
Count
Source
1
/*
2
 * This file is part of FFmpeg.
3
 *
4
 * FFmpeg is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * FFmpeg is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with FFmpeg; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18
19
#include "golomb.h"
20
#include "evc.h"
21
#include "evc_parse.h"
22
23
// @see ISO_IEC_23094-1 (7.3.2.6 Slice layer RBSP syntax)
24
int ff_evc_parse_slice_header(GetBitContext *gb, EVCParserSliceHeader *sh,
25
                              const EVCParamSets *ps, enum EVCNALUnitType nalu_type)
26
181k
{
27
181k
    const EVCParserPPS *pps;
28
181k
    const EVCParserSPS *sps;
29
181k
    int num_tiles_in_slice = 0;
30
181k
    unsigned slice_pic_parameter_set_id;
31
32
181k
    slice_pic_parameter_set_id = get_ue_golomb_31(gb);
33
34
181k
    if (slice_pic_parameter_set_id >= EVC_MAX_PPS_COUNT)
35
0
        return AVERROR_INVALIDDATA;
36
37
181k
    pps = ps->pps[slice_pic_parameter_set_id];
38
181k
    if(!pps)
39
20.4k
        return AVERROR_INVALIDDATA;
40
41
161k
    sps = ps->sps[pps->pps_seq_parameter_set_id];
42
161k
    if(!sps)
43
1.52k
        return AVERROR_INVALIDDATA;
44
45
160k
    memset(sh, 0, sizeof(*sh));
46
160k
    sh->slice_pic_parameter_set_id = slice_pic_parameter_set_id;
47
48
160k
    if (!pps->single_tile_in_pic_flag) {
49
68.5k
        sh->single_tile_in_slice_flag = get_bits1(gb);
50
68.5k
        sh->first_tile_id = get_bits(gb, pps->tile_id_len_minus1 + 1);
51
68.5k
    } else
52
91.4k
        sh->single_tile_in_slice_flag = 1;
53
54
160k
    if (!sh->single_tile_in_slice_flag) {
55
54.0k
        if (pps->arbitrary_slice_present_flag)
56
36.3k
            sh->arbitrary_slice_flag = get_bits1(gb);
57
58
54.0k
        if (!sh->arbitrary_slice_flag)
59
34.7k
            sh->last_tile_id = get_bits(gb, pps->tile_id_len_minus1 + 1);
60
19.2k
        else {
61
19.2k
            unsigned num_remaining_tiles_in_slice_minus1 = get_ue_golomb_long(gb);
62
19.2k
            if (num_remaining_tiles_in_slice_minus1 > EVC_MAX_TILE_ROWS * EVC_MAX_TILE_COLUMNS - 2)
63
723
                return AVERROR_INVALIDDATA;
64
65
18.5k
            num_tiles_in_slice = num_remaining_tiles_in_slice_minus1 + 2;
66
18.5k
            sh->num_remaining_tiles_in_slice_minus1 = num_remaining_tiles_in_slice_minus1;
67
413k
            for (int i = 0; i < num_tiles_in_slice - 1; ++i)
68
394k
                sh->delta_tile_id_minus1[i] = get_ue_golomb_long(gb);
69
18.5k
        }
70
54.0k
    }
71
72
159k
    sh->slice_type = get_ue_golomb_31(gb);
73
74
159k
    if (nalu_type == EVC_IDR_NUT)
75
34.8k
        sh->no_output_of_prior_pics_flag = get_bits1(gb);
76
77
159k
    if (sps->sps_mmvd_flag && ((sh->slice_type == EVC_SLICE_TYPE_B) || (sh->slice_type == EVC_SLICE_TYPE_P)))
78
32.6k
        sh->mmvd_group_enable_flag = get_bits1(gb);
79
126k
    else
80
126k
        sh->mmvd_group_enable_flag = 0;
81
82
159k
    if (sps->sps_alf_flag) {
83
124k
        int ChromaArrayType = sps->chroma_format_idc;
84
85
124k
        sh->slice_alf_enabled_flag = get_bits1(gb);
86
87
124k
        if (sh->slice_alf_enabled_flag) {
88
39.5k
            sh->slice_alf_luma_aps_id = get_bits(gb, 5);
89
39.5k
            sh->slice_alf_map_flag = get_bits1(gb);
90
39.5k
            sh->slice_alf_chroma_idc = get_bits(gb, 2);
91
92
39.5k
            if ((ChromaArrayType == 1 || ChromaArrayType == 2) && sh->slice_alf_chroma_idc > 0)
93
6.27k
                sh->slice_alf_chroma_aps_id =  get_bits(gb, 5);
94
39.5k
        }
95
124k
        if (ChromaArrayType == 3) {
96
29.2k
            int sliceChromaAlfEnabledFlag = 0;
97
29.2k
            int sliceChroma2AlfEnabledFlag = 0;
98
99
29.2k
            if (sh->slice_alf_chroma_idc == 1) { // @see ISO_IEC_23094-1 (7.4.5)
100
2.09k
                sliceChromaAlfEnabledFlag = 1;
101
2.09k
                sliceChroma2AlfEnabledFlag = 0;
102
27.1k
            } else if (sh->slice_alf_chroma_idc == 2) {
103
2.25k
                sliceChromaAlfEnabledFlag = 0;
104
2.25k
                sliceChroma2AlfEnabledFlag = 1;
105
24.8k
            } else if (sh->slice_alf_chroma_idc == 3) {
106
3.42k
                sliceChromaAlfEnabledFlag = 1;
107
3.42k
                sliceChroma2AlfEnabledFlag = 1;
108
21.4k
            } else {
109
21.4k
                sliceChromaAlfEnabledFlag = 0;
110
21.4k
                sliceChroma2AlfEnabledFlag = 0;
111
21.4k
            }
112
113
29.2k
            if (!sh->slice_alf_enabled_flag)
114
17.3k
                sh->slice_alf_chroma_idc = get_bits(gb, 2);
115
116
29.2k
            if (sliceChromaAlfEnabledFlag) {
117
5.52k
                sh->slice_alf_chroma_aps_id = get_bits(gb, 5);
118
5.52k
                sh->slice_alf_chroma_map_flag = get_bits1(gb);
119
5.52k
            }
120
121
29.2k
            if (sliceChroma2AlfEnabledFlag) {
122
5.67k
                sh->slice_alf_chroma2_aps_id = get_bits(gb, 5);
123
5.67k
                sh->slice_alf_chroma2_map_flag = get_bits1(gb);
124
5.67k
            }
125
29.2k
        }
126
124k
    }
127
128
159k
    if (nalu_type != EVC_IDR_NUT) {
129
124k
        if (sps->sps_pocs_flag)
130
98.4k
            sh->slice_pic_order_cnt_lsb = get_bits(gb, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
131
124k
    }
132
133
    // @note
134
    // If necessary, add the missing fields to the EVCParserSliceHeader structure
135
    // and then extend parser implementation
136
137
159k
    return 0;
138
160k
}
139
140
int ff_evc_derive_poc(const EVCParamSets *ps, const EVCParserSliceHeader *sh,
141
                      EVCParserPoc *poc, enum EVCNALUnitType nalu_type, int tid)
142
159k
{
143
159k
    const EVCParserPPS *pps = ps->pps[sh->slice_pic_parameter_set_id];
144
159k
    const EVCParserSPS *sps;
145
146
159k
    if (!pps)
147
0
        return AVERROR_INVALIDDATA;
148
149
159k
    sps = ps->sps[pps->pps_seq_parameter_set_id];
150
159k
    if (!sps)
151
0
        return AVERROR_INVALIDDATA;
152
153
159k
    if (sps->sps_pocs_flag) {
154
124k
        int PicOrderCntMsb = 0;
155
124k
        poc->prevPicOrderCntVal = poc->PicOrderCntVal;
156
157
124k
        if (nalu_type == EVC_IDR_NUT)
158
26.0k
            PicOrderCntMsb = 0;
159
98.4k
        else {
160
98.4k
            int MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
161
98.4k
            int prevPicOrderCntLsb = poc->PicOrderCntVal & (MaxPicOrderCntLsb - 1);
162
98.4k
            int prevPicOrderCntMsb = poc->PicOrderCntVal - prevPicOrderCntLsb;
163
164
98.4k
            if ((sh->slice_pic_order_cnt_lsb < prevPicOrderCntLsb) &&
165
8.29k
                ((prevPicOrderCntLsb - sh->slice_pic_order_cnt_lsb) >= (MaxPicOrderCntLsb / 2)))
166
4.52k
                PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
167
93.8k
            else if ((sh->slice_pic_order_cnt_lsb > prevPicOrderCntLsb) &&
168
11.6k
                     ((sh->slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > (MaxPicOrderCntLsb / 2)))
169
5.86k
                PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
170
88.0k
            else
171
88.0k
                PicOrderCntMsb = prevPicOrderCntMsb;
172
98.4k
        }
173
124k
        poc->PicOrderCntVal = PicOrderCntMsb + sh->slice_pic_order_cnt_lsb;
174
124k
    } else {
175
34.8k
        if (nalu_type == EVC_IDR_NUT) {
176
8.81k
            poc->PicOrderCntVal = 0;
177
8.81k
            poc->DocOffset = -1;
178
26.0k
        } else {
179
26.0k
            int SubGopLength = 1 << sps->log2_sub_gop_length;
180
181
26.0k
            if (tid > (SubGopLength > 1 ? 1 + av_log2(SubGopLength - 1) : 0))
182
4.52k
                return AVERROR_INVALIDDATA;
183
184
21.4k
            if (tid == 0) {
185
11.9k
                poc->PicOrderCntVal = poc->prevPicOrderCntVal + SubGopLength;
186
11.9k
                poc->DocOffset = 0;
187
11.9k
                poc->prevPicOrderCntVal = poc->PicOrderCntVal;
188
11.9k
            } else {
189
9.55k
                int ExpectedTemporalId;
190
9.55k
                int PocOffset;
191
9.55k
                int prevDocOffset = poc->DocOffset;
192
193
9.55k
                poc->DocOffset = (prevDocOffset + 1) % SubGopLength;
194
9.55k
                if (poc->DocOffset == 0) {
195
1.77k
                    poc->prevPicOrderCntVal += SubGopLength;
196
1.77k
                    ExpectedTemporalId = 0;
197
1.77k
                } else
198
7.78k
                    ExpectedTemporalId = 1 + av_log2(poc->DocOffset);
199
200
49.7k
                while (tid != ExpectedTemporalId) {
201
40.1k
                    poc->DocOffset = (poc->DocOffset + 1) % SubGopLength;
202
40.1k
                    if (poc->DocOffset == 0)
203
3.57k
                        ExpectedTemporalId = 0;
204
36.6k
                    else
205
36.6k
                        ExpectedTemporalId = 1 + av_log2(poc->DocOffset);
206
40.1k
                }
207
9.55k
                PocOffset = (int)(SubGopLength * ((2.0 * poc->DocOffset + 1) / (1 << tid) - 2));
208
9.55k
                poc->PicOrderCntVal = poc->prevPicOrderCntVal + PocOffset;
209
9.55k
            }
210
21.4k
        }
211
34.8k
    }
212
213
154k
    return 0;
214
159k
}