Coverage Report

Created: 2026-07-12 08:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/demux/av1_unpack.h
Line
Count
Source
1
/*****************************************************************************
2
 * av1_unpack.h: AV1 samples expander
3
 *****************************************************************************
4
 * Copyright (C) 2018 VideoLabs, VLC authors and VideoLAN
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program; if not, write to the Free Software Foundation,
18
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19
 *****************************************************************************/
20
#ifndef VLC_AV1_UNPACK_H
21
#define VLC_AV1_UNPACK_H
22
23
#include "../packetizer/av1_obu.h"
24
#include <vlc_common.h>
25
#include <vlc_block.h>
26
27
static inline uint8_t leb128_expected(uint32_t v)
28
207k
{
29
207k
    if     (v < (1U << 7))  return 1;
30
9.02k
    else if(v < (1U << 14)) return 2;
31
142
    else if(v < (1U << 21)) return 3;
32
0
    else if(v < (1U << 28)) return 4;
33
0
    else                    return 5;
34
207k
}
mp4.c:leb128_expected
Line
Count
Source
28
140k
{
29
140k
    if     (v < (1U << 7))  return 1;
30
146
    else if(v < (1U << 14)) return 2;
31
142
    else if(v < (1U << 21)) return 3;
32
0
    else if(v < (1U << 28)) return 4;
33
0
    else                    return 5;
34
140k
}
mkv.cpp:leb128_expected(unsigned int)
Line
Count
Source
28
67.6k
{
29
67.6k
    if     (v < (1U << 7))  return 1;
30
8.87k
    else if(v < (1U << 14)) return 2;
31
0
    else if(v < (1U << 21)) return 3;
32
0
    else if(v < (1U << 28)) return 4;
33
0
    else                    return 5;
34
67.6k
}
35
36
static inline void leb128_write(uint32_t v, uint8_t *p)
37
207k
{
38
207k
    for(;;)
39
216k
    {
40
216k
        *p = v & 0x7F;
41
216k
        v >>= 7;
42
216k
        if(v == 0)
43
207k
            break;
44
9.16k
        *p++ |= 0x80;
45
9.16k
    }
46
207k
}
mp4.c:leb128_write
Line
Count
Source
37
140k
{
38
140k
    for(;;)
39
140k
    {
40
140k
        *p = v & 0x7F;
41
140k
        v >>= 7;
42
140k
        if(v == 0)
43
140k
            break;
44
288
        *p++ |= 0x80;
45
288
    }
46
140k
}
mkv.cpp:leb128_write(unsigned int, unsigned char*)
Line
Count
Source
37
67.6k
{
38
67.6k
    for(;;)
39
76.5k
    {
40
76.5k
        *p = v & 0x7F;
41
76.5k
        v >>= 7;
42
76.5k
        if(v == 0)
43
67.6k
            break;
44
8.87k
        *p++ |= 0x80;
45
8.87k
    }
46
67.6k
}
47
48
static inline block_t * AV1_Unpack_Sample_ExpandSize(block_t *p_block)
49
935k
{
50
935k
    AV1_OBU_iterator_ctx_t ctx;
51
935k
    AV1_OBU_iterator_init(&ctx, p_block->p_buffer, p_block->i_buffer);
52
935k
    const uint8_t *p_obu = NULL; size_t i_obu;
53
951k
    while(AV1_OBU_iterate_next(&ctx, &p_obu, &i_obu))
54
223k
    {
55
223k
        if(AV1_OBUHasSizeField(p_obu))
56
15.7k
            continue;
57
207k
        const uint8_t i_header = 1 + AV1_OBUHasExtensionField(p_obu);
58
207k
        if(i_header > i_obu)
59
36
            break;
60
207k
        const uint8_t i_sizelen = leb128_expected(i_obu - i_header);
61
207k
        const size_t i_obu_offset = p_obu - p_block->p_buffer;
62
63
        /* Make room for i_sizelen after header */
64
207k
        if(2 * (i_obu_offset + i_header) + i_sizelen < p_block->i_buffer)
65
180k
        {
66
            /* move data to the left */
67
180k
            p_block = block_Realloc(p_block, i_sizelen, p_block->i_buffer);
68
180k
            if(p_block)
69
180k
                memmove(p_block->p_buffer, &p_block->p_buffer[i_sizelen],
70
180k
                        i_obu_offset + i_header);
71
180k
        }
72
27.4k
        else
73
27.4k
        {
74
            /* move data to the right */
75
27.4k
            p_block = block_Realloc(p_block, 0, p_block->i_buffer + i_sizelen);
76
27.4k
            if(p_block)
77
27.4k
            {
78
27.4k
                const size_t i_off = i_obu_offset + i_header;
79
27.4k
                memmove(&p_block->p_buffer[i_off + i_sizelen], &p_block->p_buffer[i_off],
80
27.4k
                        p_block->i_buffer - i_off - i_sizelen);
81
27.4k
            }
82
27.4k
        }
83
84
207k
        if(likely(p_block))
85
207k
        {
86
207k
            leb128_write(i_obu - i_header, &p_block->p_buffer[i_obu_offset + i_header]);
87
207k
            p_block->p_buffer[i_obu_offset] |= 0x02;
88
207k
        }
89
90
207k
        break;
91
207k
    }
92
935k
    return p_block;
93
935k
}
mp4.c:AV1_Unpack_Sample_ExpandSize
Line
Count
Source
49
731k
{
50
731k
    AV1_OBU_iterator_ctx_t ctx;
51
731k
    AV1_OBU_iterator_init(&ctx, p_block->p_buffer, p_block->i_buffer);
52
731k
    const uint8_t *p_obu = NULL; size_t i_obu;
53
738k
    while(AV1_OBU_iterate_next(&ctx, &p_obu, &i_obu))
54
147k
    {
55
147k
        if(AV1_OBUHasSizeField(p_obu))
56
7.12k
            continue;
57
140k
        const uint8_t i_header = 1 + AV1_OBUHasExtensionField(p_obu);
58
140k
        if(i_header > i_obu)
59
36
            break;
60
140k
        const uint8_t i_sizelen = leb128_expected(i_obu - i_header);
61
140k
        const size_t i_obu_offset = p_obu - p_block->p_buffer;
62
63
        /* Make room for i_sizelen after header */
64
140k
        if(2 * (i_obu_offset + i_header) + i_sizelen < p_block->i_buffer)
65
138k
        {
66
            /* move data to the left */
67
138k
            p_block = block_Realloc(p_block, i_sizelen, p_block->i_buffer);
68
138k
            if(p_block)
69
138k
                memmove(p_block->p_buffer, &p_block->p_buffer[i_sizelen],
70
138k
                        i_obu_offset + i_header);
71
138k
        }
72
1.99k
        else
73
1.99k
        {
74
            /* move data to the right */
75
1.99k
            p_block = block_Realloc(p_block, 0, p_block->i_buffer + i_sizelen);
76
1.99k
            if(p_block)
77
1.99k
            {
78
1.99k
                const size_t i_off = i_obu_offset + i_header;
79
1.99k
                memmove(&p_block->p_buffer[i_off + i_sizelen], &p_block->p_buffer[i_off],
80
1.99k
                        p_block->i_buffer - i_off - i_sizelen);
81
1.99k
            }
82
1.99k
        }
83
84
140k
        if(likely(p_block))
85
140k
        {
86
140k
            leb128_write(i_obu - i_header, &p_block->p_buffer[i_obu_offset + i_header]);
87
140k
            p_block->p_buffer[i_obu_offset] |= 0x02;
88
140k
        }
89
90
140k
        break;
91
140k
    }
92
731k
    return p_block;
93
731k
}
mkv.cpp:AV1_Unpack_Sample_ExpandSize(vlc_frame_t*)
Line
Count
Source
49
203k
{
50
203k
    AV1_OBU_iterator_ctx_t ctx;
51
203k
    AV1_OBU_iterator_init(&ctx, p_block->p_buffer, p_block->i_buffer);
52
203k
    const uint8_t *p_obu = NULL; size_t i_obu;
53
212k
    while(AV1_OBU_iterate_next(&ctx, &p_obu, &i_obu))
54
76.2k
    {
55
76.2k
        if(AV1_OBUHasSizeField(p_obu))
56
8.62k
            continue;
57
67.6k
        const uint8_t i_header = 1 + AV1_OBUHasExtensionField(p_obu);
58
67.6k
        if(i_header > i_obu)
59
0
            break;
60
67.6k
        const uint8_t i_sizelen = leb128_expected(i_obu - i_header);
61
67.6k
        const size_t i_obu_offset = p_obu - p_block->p_buffer;
62
63
        /* Make room for i_sizelen after header */
64
67.6k
        if(2 * (i_obu_offset + i_header) + i_sizelen < p_block->i_buffer)
65
42.2k
        {
66
            /* move data to the left */
67
42.2k
            p_block = block_Realloc(p_block, i_sizelen, p_block->i_buffer);
68
42.2k
            if(p_block)
69
42.2k
                memmove(p_block->p_buffer, &p_block->p_buffer[i_sizelen],
70
42.2k
                        i_obu_offset + i_header);
71
42.2k
        }
72
25.4k
        else
73
25.4k
        {
74
            /* move data to the right */
75
25.4k
            p_block = block_Realloc(p_block, 0, p_block->i_buffer + i_sizelen);
76
25.4k
            if(p_block)
77
25.4k
            {
78
25.4k
                const size_t i_off = i_obu_offset + i_header;
79
25.4k
                memmove(&p_block->p_buffer[i_off + i_sizelen], &p_block->p_buffer[i_off],
80
25.4k
                        p_block->i_buffer - i_off - i_sizelen);
81
25.4k
            }
82
25.4k
        }
83
84
67.6k
        if(likely(p_block))
85
67.6k
        {
86
67.6k
            leb128_write(i_obu - i_header, &p_block->p_buffer[i_obu_offset + i_header]);
87
67.6k
            p_block->p_buffer[i_obu_offset] |= 0x02;
88
67.6k
        }
89
90
67.6k
        break;
91
67.6k
    }
92
203k
    return p_block;
93
203k
}
94
95
/*
96
    Restores TD OBU and last size field from MP4/MKV sample format
97
    to full AV1 low overhead format.
98
99
    AV1 ISOBMFF Mapping 2.4
100
    https://aomediacodec.github.io/av1-isobmff/#sampleformat
101
    Matroska/WebM
102
    https://github.com/Matroska-Org/matroska-specification/blob/master/codec/av1.md
103
*/
104
static inline block_t * AV1_Unpack_Sample(block_t *p_block)
105
935k
{
106
    /* Restore last size field if missing */
107
935k
    p_block = AV1_Unpack_Sample_ExpandSize(p_block);
108
    /* Reinsert removed TU: See av1-isobmff 2.4 */
109
935k
    if(p_block &&
110
935k
       (p_block->p_buffer[0] & 0x81) == 0 && /* reserved flags */
111
311k
       (p_block->p_buffer[0] & 0x7A) != 0x12) /* no TEMPORAL_DELIMITER */
112
295k
    {
113
295k
        p_block = block_Realloc(p_block, 2, p_block->i_buffer);
114
295k
        if(p_block)
115
295k
        {
116
295k
            p_block->p_buffer[0] = 0x12;
117
295k
            p_block->p_buffer[1] = 0x00;
118
295k
        }
119
295k
    }
120
935k
    return p_block;
121
935k
}
mp4.c:AV1_Unpack_Sample
Line
Count
Source
105
731k
{
106
    /* Restore last size field if missing */
107
731k
    p_block = AV1_Unpack_Sample_ExpandSize(p_block);
108
    /* Reinsert removed TU: See av1-isobmff 2.4 */
109
731k
    if(p_block &&
110
731k
       (p_block->p_buffer[0] & 0x81) == 0 && /* reserved flags */
111
222k
       (p_block->p_buffer[0] & 0x7A) != 0x12) /* no TEMPORAL_DELIMITER */
112
211k
    {
113
211k
        p_block = block_Realloc(p_block, 2, p_block->i_buffer);
114
211k
        if(p_block)
115
211k
        {
116
211k
            p_block->p_buffer[0] = 0x12;
117
211k
            p_block->p_buffer[1] = 0x00;
118
211k
        }
119
211k
    }
120
731k
    return p_block;
121
731k
}
mkv.cpp:AV1_Unpack_Sample(vlc_frame_t*)
Line
Count
Source
105
203k
{
106
    /* Restore last size field if missing */
107
203k
    p_block = AV1_Unpack_Sample_ExpandSize(p_block);
108
    /* Reinsert removed TU: See av1-isobmff 2.4 */
109
203k
    if(p_block &&
110
203k
       (p_block->p_buffer[0] & 0x81) == 0 && /* reserved flags */
111
88.9k
       (p_block->p_buffer[0] & 0x7A) != 0x12) /* no TEMPORAL_DELIMITER */
112
83.6k
    {
113
83.6k
        p_block = block_Realloc(p_block, 2, p_block->i_buffer);
114
83.6k
        if(p_block)
115
83.6k
        {
116
83.6k
            p_block->p_buffer[0] = 0x12;
117
83.6k
            p_block->p_buffer[1] = 0x00;
118
83.6k
        }
119
83.6k
    }
120
203k
    return p_block;
121
203k
}
122
123
#endif