demux: libmp4: fix reading last iinf entry v0
[vlc.git] / modules / demux / av1_unpack.h
blobaf7f056abf25a1c161a32198fd003367d783a8c8
1 /*****************************************************************************
2 * av1_unpack.h: AV1 samples expander
3 *****************************************************************************
4 * Copyright (C) 2018 VideoLabs, VLC authors and VideoLAN
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.
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.
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
23 #include "../packetizer/av1_obu.h"
24 #include <vlc_common.h>
25 #include <vlc_block.h>
27 static inline uint8_t leb128_expected(uint32_t v)
29 if (v < (1U << 7)) return 1;
30 else if(v < (1U << 14)) return 2;
31 else if(v < (1U << 21)) return 3;
32 else if(v < (1U << 28)) return 4;
33 else return 5;
36 static inline void leb128_write(uint32_t v, uint8_t *p)
38 for(;;)
40 *p = v & 0x7F;
41 v >>= 7;
42 if(v == 0)
43 break;
44 *p++ |= 0x80;
48 static inline block_t * AV1_Unpack_Sample_ExpandSize(block_t *p_block)
50 AV1_OBU_iterator_ctx_t ctx;
51 AV1_OBU_iterator_init(&ctx, p_block->p_buffer, p_block->i_buffer);
52 const uint8_t *p_obu = NULL; size_t i_obu;
53 while(AV1_OBU_iterate_next(&ctx, &p_obu, &i_obu))
55 if(AV1_OBUHasSizeField(p_obu))
56 continue;
57 const uint8_t i_header = 1 + AV1_OBUHasExtensionField(p_obu);
58 const uint8_t i_sizelen = leb128_expected(i_obu - i_header);
59 const size_t i_obu_offset = p_obu - p_block->p_buffer;
61 /* Make room for i_sizelen after header */
62 if(2 * (i_obu_offset + i_header) + i_sizelen < p_block->i_buffer)
64 /* move data to the left */
65 p_block = block_Realloc(p_block, i_sizelen, p_block->i_buffer);
66 if(p_block)
67 memmove(p_block->p_buffer, &p_block->p_buffer[i_sizelen],
68 i_obu_offset + i_header);
70 else
72 /* move data to the right */
73 p_block = block_Realloc(p_block, 0, p_block->i_buffer + i_sizelen);
74 if(p_block)
76 const size_t i_off = i_obu_offset + i_header;
77 memmove(&p_block->p_buffer[i_off + i_sizelen], &p_block->p_buffer[i_off],
78 p_block->i_buffer - i_off - i_sizelen);
82 if(likely(p_block))
84 leb128_write(i_obu - i_header, &p_block->p_buffer[i_obu_offset + i_header]);
85 p_block->p_buffer[i_obu_offset] |= 0x02;
88 break;
90 return p_block;
94 Restores TD OBU and last size field from MP4/MKV sample format
95 to full AV1 low overhead format.
97 AV1 ISOBMFF Mapping 2.4
98 https://aomediacodec.github.io/av1-isobmff/#sampleformat
99 Matroska/WebM
100 https://github.com/Matroska-Org/matroska-specification/blob/master/codec/av1.md
102 static inline block_t * AV1_Unpack_Sample(block_t *p_block)
104 /* Restore last size field if missing */
105 p_block = AV1_Unpack_Sample_ExpandSize(p_block);
106 /* Reinsert removed TU: See av1-isobmff 2.4 */
107 if(p_block &&
108 (p_block->p_buffer[0] & 0x81) == 0 && /* reserved flags */
109 (p_block->p_buffer[0] & 0x7A) != 0x12) /* no TEMPORAL_DELIMITER */
111 p_block = block_Realloc(p_block, 2, p_block->i_buffer);
112 if(p_block)
114 p_block->p_buffer[0] = 0x12;
115 p_block->p_buffer[1] = 0x00;
118 return p_block;
121 #endif