Coverage Report

Created: 2024-09-06 07:53

/src/ffmpeg/libavcodec/hevc/parse.c
Line
Count
Source (jump to first uncovered line)
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 "bytestream.h"
20
#include "h2645_parse.h"
21
#include "hevc.h"
22
#include "parse.h"
23
24
static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets *ps,
25
                                 HEVCSEI *sei, int is_nalff, int nal_length_size,
26
                                 int err_recognition, int apply_defdispwin, void *logctx)
27
21.2k
{
28
21.2k
    int i;
29
21.2k
    int ret = 0;
30
21.2k
    int flags = (H2645_FLAG_IS_NALFF * !!is_nalff) | H2645_FLAG_SMALL_PADDING;
31
21.2k
    H2645Packet pkt = { 0 };
32
33
21.2k
    ret = ff_h2645_packet_split(&pkt, buf, buf_size, logctx,
34
21.2k
                                nal_length_size, AV_CODEC_ID_HEVC, flags);
35
21.2k
    if (ret < 0) {
36
34
        goto done;
37
34
    }
38
39
25.4k
    for (i = 0; i < pkt.nb_nals; i++) {
40
5.00k
        H2645NAL *nal = &pkt.nals[i];
41
5.00k
        if (nal->nuh_layer_id > 0)
42
834
            continue;
43
44
        /* ignore everything except parameter sets and VCL NALUs */
45
4.17k
        switch (nal->type) {
46
797
        case HEVC_NAL_VPS:
47
797
            ret = ff_hevc_decode_nal_vps(&nal->gb, logctx, ps);
48
797
            if (ret < 0)
49
194
                goto done;
50
603
            break;
51
847
        case HEVC_NAL_SPS:
52
847
            ret = ff_hevc_decode_nal_sps(&nal->gb, logctx, ps, apply_defdispwin);
53
847
            if (ret < 0)
54
280
                goto done;
55
567
            break;
56
878
        case HEVC_NAL_PPS:
57
878
            ret = ff_hevc_decode_nal_pps(&nal->gb, logctx, ps);
58
878
            if (ret < 0)
59
174
                goto done;
60
704
            break;
61
704
        case HEVC_NAL_SEI_PREFIX:
62
405
        case HEVC_NAL_SEI_SUFFIX:
63
405
            ret = ff_hevc_decode_nal_sei(&nal->gb, logctx, sei, ps, nal->type);
64
405
            if (ret < 0)
65
110
                goto done;
66
295
            break;
67
1.24k
        default:
68
1.24k
            av_log(logctx, AV_LOG_VERBOSE, "Ignoring NAL type %d in extradata\n", nal->type);
69
1.24k
            break;
70
4.17k
        }
71
4.17k
    }
72
73
21.2k
done:
74
21.2k
    ff_h2645_packet_uninit(&pkt);
75
21.2k
    if (err_recognition & AV_EF_EXPLODE)
76
18.7k
        return ret;
77
78
2.40k
    return 0;
79
21.2k
}
80
81
int ff_hevc_decode_extradata(const uint8_t *data, int size, HEVCParamSets *ps,
82
                             HEVCSEI *sei, int *is_nalff, int *nal_length_size,
83
                             int err_recognition, int apply_defdispwin, void *logctx)
84
983
{
85
983
    int ret = 0;
86
983
    GetByteContext gb;
87
88
983
    bytestream2_init(&gb, data, size);
89
90
    /* data[0] == 1 is configurationVersion from 14496-15.
91
     * data[0] == 0 is for backward compatibility predates the standard.
92
     *
93
     * Minimum number of bytes of hvcC with 0 numOfArrays is 23.
94
     */
95
983
    if (size >= 23 && ((data[0] == 1) || (data[0] == 0 && (data[1] || data[2] > 1)))) {
96
        /* It seems the extradata is encoded as hvcC format. */
97
106
        int i, j, num_arrays, nal_len_size;
98
99
106
        *is_nalff = 1;
100
101
106
        bytestream2_skip(&gb, 21);
102
106
        nal_len_size = (bytestream2_get_byte(&gb) & 3) + 1;
103
106
        num_arrays   = bytestream2_get_byte(&gb);
104
105
        /* nal units in the hvcC always have length coded with 2 bytes,
106
         * so put a fake nal_length_size = 2 while parsing them */
107
106
        *nal_length_size = 2;
108
109
        /* Decode nal units from hvcC. */
110
1.68k
        for (i = 0; i < num_arrays; i++) {
111
1.61k
            int type = bytestream2_get_byte(&gb) & 0x3f;
112
1.61k
            int cnt  = bytestream2_get_be16(&gb);
113
114
21.9k
            for (j = 0; j < cnt; j++) {
115
                // +2 for the nal size field
116
20.3k
                int nalsize = bytestream2_peek_be16(&gb) + 2;
117
20.3k
                if (bytestream2_get_bytes_left(&gb) < nalsize) {
118
34
                    av_log(logctx, AV_LOG_ERROR,
119
34
                           "Invalid NAL unit size in extradata.\n");
120
34
                    return AVERROR_INVALIDDATA;
121
34
                }
122
123
20.3k
                ret = hevc_decode_nal_units(gb.buffer, nalsize, ps, sei, *is_nalff,
124
20.3k
                                            *nal_length_size, err_recognition, apply_defdispwin,
125
20.3k
                                            logctx);
126
20.3k
                if (ret < 0) {
127
2
                    av_log(logctx, AV_LOG_ERROR,
128
2
                           "Decoding nal unit %d %d from hvcC failed\n",
129
2
                           type, i);
130
2
                    return ret;
131
2
                }
132
20.3k
                bytestream2_skip(&gb, nalsize);
133
20.3k
            }
134
1.61k
        }
135
136
        /* Now store right nal length size, that will be used to parse
137
         * all other nals */
138
70
        *nal_length_size = nal_len_size;
139
877
    } else {
140
877
        *is_nalff = 0;
141
877
        ret = hevc_decode_nal_units(data, size, ps, sei, *is_nalff, *nal_length_size,
142
877
                                    err_recognition, apply_defdispwin, logctx);
143
877
        if (ret < 0)
144
3
            return ret;
145
877
    }
146
147
944
    return ret;
148
983
}