Coverage Report

Created: 2026-09-01 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/contrib/contrib-build/bpg/libavcodec/hevc_sei.c
Line
Count
Source
1
/*
2
 * HEVC Supplementary Enhancement Information messages
3
 *
4
 * Copyright (C) 2012 - 2013 Guillaume Martres
5
 * Copyright (C) 2012 - 2013 Gildas Cocherel
6
 * Copyright (C) 2013 Vittorio Giovara
7
 *
8
 * This file is part of FFmpeg.
9
 *
10
 * FFmpeg is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * FFmpeg is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with FFmpeg; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 */
24
25
#include "golomb.h"
26
#include "hevc.h"
27
28
static void decode_nal_sei_decoded_picture_hash(HEVCContext *s)
29
0
{
30
0
    int cIdx, i;
31
0
    uint8_t hash_type;
32
    //uint16_t picture_crc;
33
    //uint32_t picture_checksum;
34
0
    GetBitContext *gb = &s->HEVClc->gb;
35
0
    hash_type = get_bits(gb, 8);
36
37
0
    for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) {
38
0
        if (hash_type == 0) {
39
0
            s->is_md5 = 1;
40
0
            for (i = 0; i < 16; i++)
41
0
                s->md5[cIdx][i] = get_bits(gb, 8);
42
0
        } else if (hash_type == 1) {
43
            // picture_crc = get_bits(gb, 16);
44
0
            skip_bits(gb, 16);
45
0
        } else if (hash_type == 2) {
46
            // picture_checksum = get_bits_long(gb, 32);
47
0
            skip_bits(gb, 32);
48
0
        }
49
0
    }
50
0
}
51
52
#ifdef USE_FULL
53
static void decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
54
{
55
    GetBitContext *gb = &s->HEVClc->gb;
56
57
    get_ue_golomb(gb);                  // frame_packing_arrangement_id
58
    s->sei_frame_packing_present = !get_bits1(gb);
59
60
    if (s->sei_frame_packing_present) {
61
        s->frame_packing_arrangement_type = get_bits(gb, 7);
62
        s->quincunx_subsampling           = get_bits1(gb);
63
        s->content_interpretation_type    = get_bits(gb, 6);
64
65
        // the following skips spatial_flipping_flag frame0_flipped_flag
66
        // field_views_flag current_frame_is_frame0_flag
67
        // frame0_self_contained_flag frame1_self_contained_flag
68
        skip_bits(gb, 6);
69
70
        if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5)
71
            skip_bits(gb, 16);  // frame[01]_grid_position_[xy]
72
        skip_bits(gb, 8);       // frame_packing_arrangement_reserved_byte
73
        skip_bits1(gb);         // frame_packing_arrangement_persistance_flag
74
    }
75
    skip_bits1(gb);             // upsampled_aspect_ratio_flag
76
}
77
78
static void decode_nal_sei_display_orientation(HEVCContext *s)
79
{
80
    GetBitContext *gb = &s->HEVClc->gb;
81
82
    s->sei_display_orientation_present = !get_bits1(gb);
83
84
    if (s->sei_display_orientation_present) {
85
        s->sei_hflip = get_bits1(gb);     // hor_flip
86
        s->sei_vflip = get_bits1(gb);     // ver_flip
87
88
        s->sei_anticlockwise_rotation = get_bits(gb, 16);
89
        skip_bits1(gb);     // display_orientation_persistence_flag
90
    }
91
}
92
93
static int decode_pic_timing(HEVCContext *s)
94
{
95
    GetBitContext *gb = &s->HEVClc->gb;
96
    HEVCSPS *sps;
97
98
    if (!s->sps_list[s->active_seq_parameter_set_id])
99
        return(AVERROR(ENOMEM));
100
    sps = (HEVCSPS*)s->sps_list[s->active_seq_parameter_set_id]->data;
101
102
    if (sps->vui.frame_field_info_present_flag) {
103
        int pic_struct = get_bits(gb, 4);
104
        s->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN;
105
        if (pic_struct == 2) {
106
            av_log(s->avctx, AV_LOG_DEBUG, "BOTTOM Field\n");
107
            s->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
108
        } else if (pic_struct == 1) {
109
            av_log(s->avctx, AV_LOG_DEBUG, "TOP Field\n");
110
            s->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD;
111
        }
112
        get_bits(gb, 2);                   // source_scan_type
113
        get_bits(gb, 1);                   // duplicate_flag
114
    }
115
    return 1;
116
}
117
118
static int active_parameter_sets(HEVCContext *s)
119
{
120
    GetBitContext *gb = &s->HEVClc->gb;
121
    int num_sps_ids_minus1;
122
    int i;
123
    unsigned active_seq_parameter_set_id;
124
125
    get_bits(gb, 4); // active_video_parameter_set_id
126
    get_bits(gb, 1); // self_contained_cvs_flag
127
    get_bits(gb, 1); // num_sps_ids_minus1
128
    num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1
129
130
    active_seq_parameter_set_id = get_ue_golomb_long(gb);
131
    if (active_seq_parameter_set_id >= MAX_SPS_COUNT) {
132
        av_log(s->avctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id);
133
        return AVERROR_INVALIDDATA;
134
    }
135
    s->active_seq_parameter_set_id = active_seq_parameter_set_id;
136
137
    for (i = 1; i <= num_sps_ids_minus1; i++)
138
        get_ue_golomb_long(gb); // active_seq_parameter_set_id[i]
139
140
    return 0;
141
}
142
#endif
143
144
static int decode_nal_sei_message(HEVCContext *s)
145
0
{
146
0
    GetBitContext *gb = &s->HEVClc->gb;
147
148
0
    int payload_type = 0;
149
0
    int payload_size = 0;
150
0
    int byte = 0xFF;
151
0
    av_log(s->avctx, AV_LOG_DEBUG, "Decoding SEI\n");
152
153
0
    while (byte == 0xFF) {
154
0
        byte          = get_bits(gb, 8);
155
0
        payload_type += byte;
156
0
    }
157
0
    byte = 0xFF;
158
0
    while (byte == 0xFF) {
159
0
        byte          = get_bits(gb, 8);
160
0
        payload_size += byte;
161
0
    }
162
0
    if (s->nal_unit_type == NAL_SEI_PREFIX) {
163
0
        if (payload_type == 256 /*&& s->decode_checksum_sei*/) {
164
0
            decode_nal_sei_decoded_picture_hash(s);
165
0
        } else 
166
#ifdef USE_FULL
167
        if (payload_type == 45) {
168
            decode_nal_sei_frame_packing_arrangement(s);
169
        } else if (payload_type == 47) {
170
            decode_nal_sei_display_orientation(s);
171
        } else if (payload_type == 1){
172
            int ret = decode_pic_timing(s);
173
            av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
174
            skip_bits(gb, 8 * payload_size);
175
            return ret;
176
        } else if (payload_type == 129){
177
            active_parameter_sets(s);
178
            av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
179
        } else 
180
#endif
181
0
#ifdef USE_FRAME_DURATION_SEI
182
0
        if (payload_type == 257) {
183
            /* frame duration in multiples of the frame rate period */
184
0
            s->frame_duration = get_bits(gb, 16);
185
0
        } else
186
0
#endif
187
0
        {
188
0
            av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
189
0
            skip_bits(gb, 8*payload_size);
190
0
        }
191
0
    } else { /* nal_unit_type == NAL_SEI_SUFFIX */
192
0
        if (payload_type == 132 /* && s->decode_checksum_sei */)
193
0
            decode_nal_sei_decoded_picture_hash(s);
194
0
        else {
195
0
            av_log(s->avctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", payload_type);
196
0
            skip_bits(gb, 8 * payload_size);
197
0
        }
198
0
    }
199
0
    return 1;
200
0
}
201
202
static int more_rbsp_data(GetBitContext *gb)
203
0
{
204
0
    return get_bits_left(gb) > 0 && show_bits(gb, 8) != 0x80;
205
0
}
206
207
int ff_hevc_decode_nal_sei(HEVCContext *s)
208
0
{
209
0
    int ret;
210
211
0
    do {
212
0
        ret = decode_nal_sei_message(s);
213
0
        if (ret < 0)
214
0
            return(AVERROR(ENOMEM));
215
0
    } while (more_rbsp_data(&s->HEVClc->gb));
216
0
    return 1;
217
0
}