/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 | 215k | { |
29 | 215k | if (v < (1U << 7)) return 1; |
30 | 2.38k | else if(v < (1U << 14)) return 2; |
31 | 92 | else if(v < (1U << 21)) return 3; |
32 | 0 | else if(v < (1U << 28)) return 4; |
33 | 0 | else return 5; |
34 | 215k | } Line | Count | Source | 28 | 215k | { | 29 | 215k | if (v < (1U << 7)) return 1; | 30 | 2.38k | else if(v < (1U << 14)) return 2; | 31 | 92 | else if(v < (1U << 21)) return 3; | 32 | 0 | else if(v < (1U << 28)) return 4; | 33 | 0 | else return 5; | 34 | 215k | } |
Unexecuted instantiation: mkv.cpp:leb128_expected(unsigned int) |
35 | | |
36 | | static inline void leb128_write(uint32_t v, uint8_t *p) |
37 | 215k | { |
38 | 215k | for(;;) |
39 | 218k | { |
40 | 218k | *p = v & 0x7F; |
41 | 218k | v >>= 7; |
42 | 218k | if(v == 0) |
43 | 215k | break; |
44 | 2.47k | *p++ |= 0x80; |
45 | 2.47k | } |
46 | 215k | } Line | Count | Source | 37 | 215k | { | 38 | 215k | for(;;) | 39 | 218k | { | 40 | 218k | *p = v & 0x7F; | 41 | 218k | v >>= 7; | 42 | 218k | if(v == 0) | 43 | 215k | break; | 44 | 2.47k | *p++ |= 0x80; | 45 | 2.47k | } | 46 | 215k | } |
Unexecuted instantiation: mkv.cpp:leb128_write(unsigned int, unsigned char*) |
47 | | |
48 | | static inline block_t * AV1_Unpack_Sample_ExpandSize(block_t *p_block) |
49 | 835k | { |
50 | 835k | AV1_OBU_iterator_ctx_t ctx; |
51 | 835k | AV1_OBU_iterator_init(&ctx, p_block->p_buffer, p_block->i_buffer); |
52 | 835k | const uint8_t *p_obu = NULL; size_t i_obu; |
53 | 847k | while(AV1_OBU_iterate_next(&ctx, &p_obu, &i_obu)) |
54 | 233k | { |
55 | 233k | if(AV1_OBUHasSizeField(p_obu)) |
56 | 11.9k | continue; |
57 | 221k | const uint8_t i_header = 1 + AV1_OBUHasExtensionField(p_obu); |
58 | 221k | if(i_header > i_obu) |
59 | 5.75k | break; |
60 | 215k | const uint8_t i_sizelen = leb128_expected(i_obu - i_header); |
61 | 215k | const size_t i_obu_offset = p_obu - p_block->p_buffer; |
62 | | |
63 | | /* Make room for i_sizelen after header */ |
64 | 215k | if(2 * (i_obu_offset + i_header) + i_sizelen < p_block->i_buffer) |
65 | 153k | { |
66 | | /* move data to the left */ |
67 | 153k | p_block = block_Realloc(p_block, i_sizelen, p_block->i_buffer); |
68 | 153k | if(p_block) |
69 | 153k | memmove(p_block->p_buffer, &p_block->p_buffer[i_sizelen], |
70 | 153k | i_obu_offset + i_header); |
71 | 153k | } |
72 | 62.4k | else |
73 | 62.4k | { |
74 | | /* move data to the right */ |
75 | 62.4k | p_block = block_Realloc(p_block, 0, p_block->i_buffer + i_sizelen); |
76 | 62.4k | if(p_block) |
77 | 62.4k | { |
78 | 62.4k | const size_t i_off = i_obu_offset + i_header; |
79 | 62.4k | memmove(&p_block->p_buffer[i_off + i_sizelen], &p_block->p_buffer[i_off], |
80 | 62.4k | p_block->i_buffer - i_off - i_sizelen); |
81 | 62.4k | } |
82 | 62.4k | } |
83 | | |
84 | 215k | if(likely(p_block)) |
85 | 215k | { |
86 | 215k | leb128_write(i_obu - i_header, &p_block->p_buffer[i_obu_offset + i_header]); |
87 | 215k | p_block->p_buffer[i_obu_offset] |= 0x02; |
88 | 215k | } |
89 | | |
90 | 215k | break; |
91 | 221k | } |
92 | 835k | return p_block; |
93 | 835k | } mp4.c:AV1_Unpack_Sample_ExpandSize Line | Count | Source | 49 | 835k | { | 50 | 835k | AV1_OBU_iterator_ctx_t ctx; | 51 | 835k | AV1_OBU_iterator_init(&ctx, p_block->p_buffer, p_block->i_buffer); | 52 | 835k | const uint8_t *p_obu = NULL; size_t i_obu; | 53 | 847k | while(AV1_OBU_iterate_next(&ctx, &p_obu, &i_obu)) | 54 | 233k | { | 55 | 233k | if(AV1_OBUHasSizeField(p_obu)) | 56 | 11.9k | continue; | 57 | 221k | const uint8_t i_header = 1 + AV1_OBUHasExtensionField(p_obu); | 58 | 221k | if(i_header > i_obu) | 59 | 5.75k | break; | 60 | 215k | const uint8_t i_sizelen = leb128_expected(i_obu - i_header); | 61 | 215k | const size_t i_obu_offset = p_obu - p_block->p_buffer; | 62 | | | 63 | | /* Make room for i_sizelen after header */ | 64 | 215k | if(2 * (i_obu_offset + i_header) + i_sizelen < p_block->i_buffer) | 65 | 153k | { | 66 | | /* move data to the left */ | 67 | 153k | p_block = block_Realloc(p_block, i_sizelen, p_block->i_buffer); | 68 | 153k | if(p_block) | 69 | 153k | memmove(p_block->p_buffer, &p_block->p_buffer[i_sizelen], | 70 | 153k | i_obu_offset + i_header); | 71 | 153k | } | 72 | 62.4k | else | 73 | 62.4k | { | 74 | | /* move data to the right */ | 75 | 62.4k | p_block = block_Realloc(p_block, 0, p_block->i_buffer + i_sizelen); | 76 | 62.4k | if(p_block) | 77 | 62.4k | { | 78 | 62.4k | const size_t i_off = i_obu_offset + i_header; | 79 | 62.4k | memmove(&p_block->p_buffer[i_off + i_sizelen], &p_block->p_buffer[i_off], | 80 | 62.4k | p_block->i_buffer - i_off - i_sizelen); | 81 | 62.4k | } | 82 | 62.4k | } | 83 | | | 84 | 215k | if(likely(p_block)) | 85 | 215k | { | 86 | 215k | leb128_write(i_obu - i_header, &p_block->p_buffer[i_obu_offset + i_header]); | 87 | 215k | p_block->p_buffer[i_obu_offset] |= 0x02; | 88 | 215k | } | 89 | | | 90 | 215k | break; | 91 | 221k | } | 92 | 835k | return p_block; | 93 | 835k | } |
Unexecuted instantiation: mkv.cpp:AV1_Unpack_Sample_ExpandSize(vlc_frame_t*) |
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 | 835k | { |
106 | | /* Restore last size field if missing */ |
107 | 835k | p_block = AV1_Unpack_Sample_ExpandSize(p_block); |
108 | | /* Reinsert removed TU: See av1-isobmff 2.4 */ |
109 | 835k | if(p_block && |
110 | 835k | (p_block->p_buffer[0] & 0x81) == 0 && /* reserved flags */ |
111 | 305k | (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 | 835k | return p_block; |
121 | 835k | } Line | Count | Source | 105 | 835k | { | 106 | | /* Restore last size field if missing */ | 107 | 835k | p_block = AV1_Unpack_Sample_ExpandSize(p_block); | 108 | | /* Reinsert removed TU: See av1-isobmff 2.4 */ | 109 | 835k | if(p_block && | 110 | 835k | (p_block->p_buffer[0] & 0x81) == 0 && /* reserved flags */ | 111 | 305k | (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 | 835k | return p_block; | 121 | 835k | } |
Unexecuted instantiation: mkv.cpp:AV1_Unpack_Sample(vlc_frame_t*) |
122 | | |
123 | | #endif |