FFmpeg
Loading...
Searching...
No Matches
lcevc.c
Go to the documentation of this file.
1/*
2 * LCEVC helper functions for muxers
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "libavutil/error.h"
23#include "libavutil/mem.h"
26#include "libavcodec/lcevc.h"
27#include "libavcodec/lcevctab.h"
29#include "avio.h"
30#include "avio_internal.h"
31#include "lcevc.h"
32
33/**
34 * Rewrite the NALu stripping the unneeded blocks.
35 * Given that length fields coded inside the NALu are not aware of any emulation_3bytes
36 * present in the bitstream, we need to keep track of the raw buffer as we navigate
37 * the stripped buffer in order to write proper NALu sizes.
38 */
40 const H2645NAL *nal)
41{
42 GetByteContext gbc, raw_gbc;
43 int64_t start = avio_tell(pb), end;
44 int sc = 0, gc = 0;
45 int skipped_byte_pos = 0, nalu_length = 3;
46
47 bytestream2_init(&gbc, nal->data, nal->size);
48 bytestream2_init(&raw_gbc, nal->raw_data, nal->raw_size);
49 avio_wb16(pb, 0); // size placeholder
50 avio_wb16(pb, bytestream2_get_be16(&gbc)); // nal_unit_header
51 bytestream2_skip(&raw_gbc, 2);
52
53 while (bytestream2_get_bytes_left(&gbc) > 1 && (!sc || !gc)) {
55 uint64_t payload_size;
56 int payload_size_type, payload_type;
57 int block_size, raw_block_size, block_end;
58
60
61 payload_size_type = get_bits(&gb, 3);
62 payload_type = get_bits(&gb, 5);
63 payload_size = payload_size_type;
64 if (payload_size_type == 6)
66 if (payload_size_type == 7)
67 payload_size = get_mb(&gb);
68
69 if (payload_size > INT_MAX - (get_bits_count(&gb) >> 3))
71
72 block_size = raw_block_size = payload_size + (get_bits_count(&gb) >> 3);
73 if (block_size >= bytestream2_get_bytes_left(&gbc))
75
76 block_end = bytestream2_tell(&gbc) + block_size;
77 // Take into account removed emulation 3bytes, as payload_size in
78 // the bitstream is not aware of them.
79 for (; skipped_byte_pos < nal->skipped_bytes; skipped_byte_pos++) {
80 if (nal->skipped_bytes_pos[skipped_byte_pos] >= block_end)
81 break;
82 raw_block_size++;
83 }
84
85 switch (payload_type) {
86 case 0:
87 if (sc)
88 break;
89
90 lvcc->profile_idc = get_bits(&gb, 4);
91 lvcc->level_idc = get_bits(&gb, 4);
92
93 avio_write(pb, raw_gbc.buffer, raw_block_size);
94 nalu_length += raw_block_size;
95 sc = 1;
96 break;
97 case 1: {
98 int resolution_type, bit_depth;
99 int processed_planes_type_flag;
100
101 if (gc)
102 break;
103
104 processed_planes_type_flag = get_bits1(&gb);
105 resolution_type = get_bits(&gb, 6);
106
107 skip_bits1(&gb);
108 lvcc->chroma_format_idc = get_bits(&gb, 2);
109
110 skip_bits(&gb, 2);
111 bit_depth = get_bits(&gb, 2) * 2; // enhancement_depth_type
114
115 if (resolution_type < 63) {
116 lvcc->pic_width_in_luma_samples = ff_lcevc_resolution_type[resolution_type].width;
117 lvcc->pic_height_in_luma_samples = ff_lcevc_resolution_type[resolution_type].height;
118 } else {
119 int upsample_type, tile_dimensions_type;
120 int temporal_step_width_modifier_signalled_flag, level1_filtering_signalled_flag;
121 // Skip syntax elements until we get to the custom dimension ones
122 temporal_step_width_modifier_signalled_flag = get_bits1(&gb);
123 skip_bits(&gb, 3);
124 upsample_type = get_bits(&gb, 3);
125 level1_filtering_signalled_flag = get_bits1(&gb);
126 skip_bits(&gb, 4);
127 tile_dimensions_type = get_bits(&gb, 2);
128 skip_bits(&gb, 4);
129 if (processed_planes_type_flag)
130 skip_bits(&gb, 4);
131 if (temporal_step_width_modifier_signalled_flag)
132 skip_bits(&gb, 8);
133 if (upsample_type)
134 skip_bits_long(&gb, 64);
135 if (level1_filtering_signalled_flag)
136 skip_bits(&gb, 8);
137 if (tile_dimensions_type) {
138 if (tile_dimensions_type == 3)
139 skip_bits_long(&gb, 32);
140 skip_bits(&gb, 8);
141 }
142
143 lvcc->pic_width_in_luma_samples = get_bits(&gb, 16);
144 lvcc->pic_height_in_luma_samples = get_bits(&gb, 16);
145 }
146
148 break;
149
150 avio_write(pb, raw_gbc.buffer, raw_block_size);
151 nalu_length += raw_block_size;
152 gc = 1;
153 break;
154 }
155 case 5:
156 avio_write(pb, raw_gbc.buffer, raw_block_size);
157 nalu_length += raw_block_size;
158 break;
159 default:
160 break;
161 }
162
163 bytestream2_skip(&gbc, block_size);
164 bytestream2_skip(&raw_gbc, raw_block_size);
165 }
166
167 if (!sc || !gc)
168 return AVERROR_INVALIDDATA;
169
170 avio_w8(pb, 0x80); // rbsp_alignment bits
171
172 end = avio_tell(pb);
173 avio_seek(pb, start, SEEK_SET);
174 avio_wb16(pb, nalu_length);
175 avio_seek(pb, end, SEEK_SET);
176
177 return 0;
178}
179
181 const uint8_t *buf, int size, void *logctx)
182{
183 H2645Packet h2645_pkt = { 0 };
184 AVIOContext *pb;
185 int ret;
186 int found;
187
188 if (size <= 0)
189 return AVERROR_INVALIDDATA;
190
191 if (buf[0] == 1) {
192 GetBitContext gb;
193
194 if (size < 13)
195 return AVERROR_INVALIDDATA;
196
197 ret = init_get_bits8(&gb, buf, 13);
198 if (ret < 0)
199 return ret;
200
201 memset(lvcc, 0, sizeof(*lvcc));
202
203 skip_bits(&gb, 8);
204 lvcc->profile_idc = get_bits(&gb, 8);
205 lvcc->level_idc = get_bits(&gb, 8);
206 lvcc->chroma_format_idc = get_bits(&gb, 2);
207 lvcc->bit_depth_luma_minus8 = get_bits(&gb, 3);
208 lvcc->bit_depth_chroma_minus8 = get_bits(&gb, 3);
209 skip_bits(&gb, 8);
212
213 return 0;
214 }
215
216 ret = ffio_open_null_buf(&pb);
217 if (ret < 0)
218 return ret;
219
220 ret = ff_h2645_packet_split(&h2645_pkt, buf, size, logctx, 0, AV_CODEC_ID_LCEVC, 0);
221 if (ret < 0)
222 goto fail;
223
224 /* look for IDR or NON_IDR */
225 found = 0;
226 for (int i = 0; i < h2645_pkt.nb_nals; i++) {
227 const H2645NAL *nal = &h2645_pkt.nals[i];
228
229 if (nal->type == LCEVC_IDR_NUT ||
230 nal->type == LCEVC_NON_IDR_NUT) {
231 ret = write_nalu(lvcc, pb, nal);
232 if (ret < 0)
233 goto fail;
234 found = 1;
235 }
236 }
237
238 if (!found) {
240 goto fail;
241 }
242
243 ret = 0;
244fail:
246 ff_h2645_packet_uninit(&h2645_pkt);
247
248 return ret;
249}
250
251int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len, void *logctx)
252{
254 AVIOContext *idr_pb = NULL, *nidr_pb = NULL;
255 H2645Packet h2645_pkt = { 0 };
256 uint8_t *idr, *nidr;
257 uint32_t idr_size = 0, nidr_size = 0;
258 int ret, nb_idr = 0, nb_nidr = 0;
259
260 if (len <= 6)
261 return AVERROR_INVALIDDATA;
262
263 /* check for start code */
264 if (AV_RB32(data) != 0x00000001 &&
265 AV_RB24(data) != 0x000001) {
266 avio_write(pb, data, len);
267 return 0;
268 }
269
270 ret = ff_h2645_packet_split(&h2645_pkt, data, len, logctx, 0, AV_CODEC_ID_LCEVC, 0);
271 if (ret < 0)
272 return ret;
273
274 ret = avio_open_dyn_buf(&idr_pb);
275 if (ret < 0)
276 goto fail;
277 ret = avio_open_dyn_buf(&nidr_pb);
278 if (ret < 0)
279 goto fail;
280
281 /* look for IDR or NON_IDR */
282 for (int i = 0; i < h2645_pkt.nb_nals; i++) {
283 const H2645NAL *nal = &h2645_pkt.nals[i];
284
285 if (nal->type == LCEVC_IDR_NUT) {
286 nb_idr++;
287
288 ret = write_nalu(&lvcc, idr_pb, nal);
289 if (ret < 0)
290 goto fail;
291 } else if (nal->type == LCEVC_NON_IDR_NUT) {
292 nb_nidr++;
293
294 ret = write_nalu(&lvcc, nidr_pb, nal);
295 if (ret < 0)
296 goto fail;
297 }
298 }
299 idr_size = avio_get_dyn_buf(idr_pb, &idr);
300 nidr_size = avio_get_dyn_buf(nidr_pb, &nidr);
301
302 if (!idr_size && !nidr_size) {
304 goto fail;
305 }
306
307 avio_w8(pb, 1); /* version */
308 avio_w8(pb, lvcc.profile_idc);
309 avio_w8(pb, lvcc.level_idc);
310 avio_w8(pb, (lvcc.chroma_format_idc << 6) |
311 (lvcc.bit_depth_luma_minus8 << 3) |
313 avio_w8(pb, 0xff); /* 2 bits nal size length - 1 (11) + 6 bits reserved (111111)*/
316 avio_w8(pb, 0xff);
317
318 int nb_arrays = !!nb_idr + !!nb_nidr;
319 avio_w8(pb, nb_arrays);
320
321 if (nb_idr) {
323 avio_wb16(pb, nb_idr);
324 avio_write(pb, idr, idr_size);
325 }
326 if (nb_nidr) {
328 avio_wb16(pb, nb_nidr);
329 avio_write(pb, nidr, nidr_size);
330 }
331
332 ret = 0;
333fail:
334 ffio_free_dyn_buf(&idr_pb);
335 ffio_free_dyn_buf(&nidr_pb);
336 ff_h2645_packet_uninit(&h2645_pkt);
337
338 return ret;
339}
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
Definition af_astats.c:246
Buffered I/O operations.
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
void avio_w8(AVIOContext *s, int b)
Definition aviobuf.c:184
void avio_wb32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:368
void avio_wb16(AVIOContext *s, unsigned int val)
Definition aviobuf.c:446
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition aviobuf.c:1365
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1377
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition aviobuf.c:1438
int ffio_open_null_buf(AVIOContext **s)
Open a write-only fake memory stream.
Definition aviobuf.c:1462
int ffio_close_null_buf(AVIOContext *s)
Close a null buffer.
Definition aviobuf.c:1472
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition bytestream.h:168
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition bytestream.h:192
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
static int FUNC nal(CodedBitstreamContext *ctx, RWContext *rw, LCEVCRawNAL *current, int nal_unit_type)
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
error code definitions
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static unsigned int get_bits1(GetBitContext *s)
Definition get_bits.h:391
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
static int get_bits_count(const GetBitContext *s)
Definition get_bits.h:254
static void skip_bits1(GetBitContext *s)
Definition get_bits.h:416
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
#define fail
Definition test.h:479
@ AV_CODEC_ID_LCEVC
Definition codec_id.h:609
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AV_RB32(p)
#define AV_RB24(x)
int ff_lcvec_parse_config_record(LCEVCDecoderConfigurationRecord *lvcc, const uint8_t *buf, int size, void *logctx)
Definition lcevc.c:180
static int write_nalu(LCEVCDecoderConfigurationRecord *lvcc, AVIOContext *pb, const H2645NAL *nal)
Rewrite the NALu stripping the unneeded blocks.
Definition lcevc.c:39
int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len, void *logctx)
Definition lcevc.c:251
static uint64_t get_mb(GetBitContext *s)
Definition lcevc_parse.h:26
void ff_h2645_packet_uninit(H2645Packet *pkt)
Free all the allocated memory in the packet.
int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, void *logctx, int nal_length_size, enum AVCodecID codec_id, int flags)
Split an input packet into NAL units.
static void idr(H264Context *h)
instantaneous decoder refresh.
Definition h264dec.c:438
LCEVC common definitions.
@ LCEVC_NON_IDR_NUT
Definition lcevc.h:60
@ LCEVC_IDR_NUT
Definition lcevc.h:61
const struct FFLCEVCDim ff_lcevc_resolution_type[63]
Definition lcevctab.c:22
Memory handling functions.
const char data[16]
Definition mxf.c:149
Bytestream IO Context.
Definition avio.h:160
const uint8_t * buffer
Definition bytestream.h:34
H2645NAL * nals
Definition h2645_parse.h:83
uint32_t pic_height_in_luma_samples
Definition lcevc.h:34
int size
int len