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 lvcc->sublevel_idc = get_bits(&gb, 2);
93
94 avio_write(pb, raw_gbc.buffer, raw_block_size);
95 nalu_length += raw_block_size;
96 sc = 1;
97 break;
98 case 1: {
99 int resolution_type, bit_depth;
100
101 if (gc)
102 break;
103
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);
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 2: {
156 int no_enhancement_bit_flag = get_bits1(&gb);
157
158 skip_bits(&gb, 4);
159 lvcc->picture_type_bit_flag = get_bits1(&gb);
160 skip_bits(&gb, 2);
161
162 if (!no_enhancement_bit_flag)
163 skip_bits(&gb, 16);
164
165 lvcc->field_type_bit_flag = lvcc->picture_type_bit_flag ? get_bits1(&gb) : 0;
166 break;
167 }
168 case 5:
169 avio_write(pb, raw_gbc.buffer, raw_block_size);
170 nalu_length += raw_block_size;
171 break;
172 default:
173 break;
174 }
175
176 bytestream2_skip(&gbc, block_size);
177 bytestream2_skip(&raw_gbc, raw_block_size);
178 }
179
180 if (!sc || !gc)
181 return AVERROR_INVALIDDATA;
182
183 avio_w8(pb, 0x80); // rbsp_alignment bits
184
185 end = avio_tell(pb);
186 avio_seek(pb, start, SEEK_SET);
187 avio_wb16(pb, nalu_length);
188 avio_seek(pb, end, SEEK_SET);
189
190 return 0;
191}
192
194 const uint8_t *buf, int size, void *logctx)
195{
196 H2645Packet h2645_pkt = { 0 };
197 AVIOContext *pb;
198 int ret;
199 int found;
200
201 if (size <= 0)
202 return AVERROR_INVALIDDATA;
203
204 if (buf[0] == 1) {
205 GetBitContext gb;
206
207 if (size < 13)
208 return AVERROR_INVALIDDATA;
209
210 ret = init_get_bits8(&gb, buf, 13);
211 if (ret < 0)
212 return ret;
213
214 memset(lvcc, 0, sizeof(*lvcc));
215
216 skip_bits(&gb, 8);
217 lvcc->profile_idc = get_bits(&gb, 8);
218 lvcc->level_idc = get_bits(&gb, 8);
219 lvcc->chroma_format_idc = get_bits(&gb, 2);
220 lvcc->bit_depth_luma_minus8 = get_bits(&gb, 3);
221 lvcc->bit_depth_chroma_minus8 = get_bits(&gb, 3);
222 skip_bits(&gb, 8);
225
226 return 0;
227 }
228
229 ret = ffio_open_null_buf(&pb);
230 if (ret < 0)
231 return ret;
232
233 ret = ff_h2645_packet_split(&h2645_pkt, buf, size, logctx, 0, AV_CODEC_ID_LCEVC, 0);
234 if (ret < 0)
235 goto fail;
236
237 /* look for IDR or NON_IDR */
238 found = 0;
239 for (int i = 0; i < h2645_pkt.nb_nals; i++) {
240 const H2645NAL *nal = &h2645_pkt.nals[i];
241
242 if (nal->type == LCEVC_IDR_NUT ||
243 nal->type == LCEVC_NON_IDR_NUT) {
244 ret = write_nalu(lvcc, pb, nal);
245 if (ret < 0)
246 goto fail;
247 found = 1;
248 }
249 }
250
251 if (!found) {
253 goto fail;
254 }
255
256 ret = 0;
257fail:
259 ff_h2645_packet_uninit(&h2645_pkt);
260
261 return ret;
262}
263
264int ff_isom_write_lvcc(AVIOContext *pb, const uint8_t *data, int len, void *logctx)
265{
267 AVIOContext *idr_pb = NULL, *nidr_pb = NULL;
268 H2645Packet h2645_pkt = { 0 };
269 uint8_t *idr, *nidr;
270 uint32_t idr_size = 0, nidr_size = 0;
271 int ret, nb_idr = 0, nb_nidr = 0;
272
273 if (len <= 6)
274 return AVERROR_INVALIDDATA;
275
276 /* check for start code */
277 if (AV_RB32(data) != 0x00000001 &&
278 AV_RB24(data) != 0x000001) {
279 avio_write(pb, data, len);
280 return 0;
281 }
282
283 ret = ff_h2645_packet_split(&h2645_pkt, data, len, logctx, 0, AV_CODEC_ID_LCEVC, 0);
284 if (ret < 0)
285 return ret;
286
287 ret = avio_open_dyn_buf(&idr_pb);
288 if (ret < 0)
289 goto fail;
290 ret = avio_open_dyn_buf(&nidr_pb);
291 if (ret < 0)
292 goto fail;
293
294 /* look for IDR or NON_IDR */
295 for (int i = 0; i < h2645_pkt.nb_nals; i++) {
296 const H2645NAL *nal = &h2645_pkt.nals[i];
297
298 if (nal->type == LCEVC_IDR_NUT) {
299 nb_idr++;
300
301 ret = write_nalu(&lvcc, idr_pb, nal);
302 if (ret < 0)
303 goto fail;
304 } else if (nal->type == LCEVC_NON_IDR_NUT) {
305 nb_nidr++;
306
307 ret = write_nalu(&lvcc, nidr_pb, nal);
308 if (ret < 0)
309 goto fail;
310 }
311 }
312 idr_size = avio_get_dyn_buf(idr_pb, &idr);
313 nidr_size = avio_get_dyn_buf(nidr_pb, &nidr);
314
315 if (!idr_size && !nidr_size) {
317 goto fail;
318 }
319
320 avio_w8(pb, 1); /* version */
321 avio_w8(pb, lvcc.profile_idc);
322 avio_w8(pb, lvcc.level_idc);
323 avio_w8(pb, (lvcc.chroma_format_idc << 6) |
324 (lvcc.bit_depth_luma_minus8 << 3) |
326 avio_w8(pb, 0xff); /* 2 bits nal size length - 1 (11) + 6 bits reserved (111111)*/
329 avio_w8(pb, 0xff);
330
331 int nb_arrays = !!nb_idr + !!nb_nidr;
332 avio_w8(pb, nb_arrays);
333
334 if (nb_idr) {
336 avio_wb16(pb, nb_idr);
337 avio_write(pb, idr, idr_size);
338 }
339 if (nb_nidr) {
341 avio_wb16(pb, nb_nidr);
342 avio_write(pb, nidr, nidr_size);
343 }
344
345 ret = 0;
346fail:
347 ffio_free_dyn_buf(&idr_pb);
348 ffio_free_dyn_buf(&nidr_pb);
349 ff_h2645_packet_uninit(&h2645_pkt);
350
351 return ret;
352}
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:507
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:1333
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1345
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition aviobuf.c:1406
int ffio_open_null_buf(AVIOContext **s)
Open a write-only fake memory stream.
Definition aviobuf.c:1430
int ffio_close_null_buf(AVIOContext *s)
Close a null buffer.
Definition aviobuf.c:1440
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
int ret
Definition ffplay.c:391
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:615
#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:193
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:264
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:436
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:35
int size
int len