FFmpeg
Loading...
Searching...
No Matches
evc_frame_merge.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 James Almer <jamrial@gmail.com>
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#include "libavutil/mem.h"
21
22#include "libavcodec/get_bits.h"
23#include "libavcodec/bsf.h"
25#include "libavcodec/evc.h"
27#include "libavcodec/evc_ps.h"
28
29// Access unit data
30typedef struct AccessUnitBuffer {
31 uint8_t *data; // the data buffer
32 size_t data_size; // size of data in bytes
33 unsigned capacity; // buffer capacity
35
42
44 const EVCParserPoc *poc, enum EVCNALUnitType nalu_type)
45{
47 EVCParserSPS *sps = ps->sps[pps->pps_seq_parameter_set_id];
48
49 av_assert0(sps && pps);
50
51 if (sps->profile_idc == 0) { // BASELINE profile
52 if (nalu_type == EVC_NOIDR_NUT || nalu_type == EVC_IDR_NUT)
53 return 1;
54 } else { // MAIN profile
55 if (nalu_type == EVC_NOIDR_NUT) {
56 if (poc->PicOrderCntVal != poc->prevPicOrderCntVal)
57 return 1;
58 } else if (nalu_type == EVC_IDR_NUT)
59 return 1;
60 }
61 return 0;
62}
63
65{
67
68 ff_evc_ps_free(&ctx->ps);
70 av_packet_unref(ctx->buffer_pkt);
71 ctx->au_buffer.data_size = 0;
72}
73
74static int parse_nal_unit(AVBSFContext *bsf, const uint8_t *buf, int buf_size)
75{
78 enum EVCNALUnitType nalu_type;
79 int tid, err;
80
81 err = init_get_bits8(&gb, buf, buf_size);
82 if (err < 0)
83 return err;
84
85 // @see ISO_IEC_23094-1_2020, 7.4.2.2 NAL unit header semantic (Table 4 - NAL unit type codes and NAL unit type classes)
86 // @see enum EVCNALUnitType in evc.h
87 if (get_bits1(&gb)) {// forbidden_zero_bit
88 av_log(bsf, AV_LOG_ERROR, "Invalid NAL unit header\n");
90 }
91
92 nalu_type = get_bits(&gb, 6) - 1;
93 if (nalu_type < EVC_NOIDR_NUT || nalu_type > EVC_UNSPEC_NUT62) {
94 av_log(bsf, AV_LOG_ERROR, "Invalid NAL unit type: (%d)\n", nalu_type);
96 }
97
98 tid = get_bits(&gb, 3);
99 skip_bits(&gb, 5); // nuh_reserved_zero_5bits
100 skip_bits1(&gb); // nuh_extension_flag
101
102 switch (nalu_type) {
103 case EVC_SPS_NUT:
104 err = ff_evc_parse_sps(&gb, &ctx->ps);
105 if (err < 0) {
106 av_log(bsf, AV_LOG_ERROR, "SPS parsing error\n");
107 return err;
108 }
109 break;
110 case EVC_PPS_NUT:
111 err = ff_evc_parse_pps(&gb, &ctx->ps);
112 if (err < 0) {
113 av_log(bsf, AV_LOG_ERROR, "PPS parsing error\n");
114 return err;
115 }
116 break;
117 case EVC_IDR_NUT: // Coded slice of a IDR or non-IDR picture
118 case EVC_NOIDR_NUT: {
120
121 err = ff_evc_parse_slice_header(&gb, &sh, &ctx->ps, nalu_type);
122 if (err < 0) {
123 av_log(bsf, AV_LOG_ERROR, "Slice header parsing error\n");
124 return err;
125 }
126
127 // POC (picture order count of the current picture) derivation
128 // @see ISO/IEC 23094-1:2020(E) 8.3.1 Decoding process for picture order count
129 err = ff_evc_derive_poc(&ctx->ps, &sh, &ctx->poc, nalu_type, tid);
130 if (err < 0)
131 return err;
132
133 return end_of_access_unit_found(&ctx->ps, &sh, &ctx->poc, nalu_type);
134
135 break;
136 }
137 case EVC_SEI_NUT: // Supplemental Enhancement Information
138 case EVC_APS_NUT: // Adaptation parameter set
139 case EVC_FD_NUT: // Filler data
140 default:
141 break;
142 }
143
144 return 0;
145}
146
148{
150 AVPacket *in = ctx->in, *buffer_pkt = ctx->buffer_pkt;
151 size_t data_size;
152 int au_end_found = 0, err;
153
154 while (!au_end_found) {
155 uint8_t *buffer;
156 uint32_t nalu_size;
157
158 if (!in->size) {
159 av_packet_unref(in);
160 err = ff_bsf_get_packet_ref(bsf, in);
161 if (err < 0) {
162 if (err == AVERROR_EOF && ctx->au_buffer.data_size > 0)
163 break;
164 return err;
165 }
166 /* Buffer packets with timestamps (there should be at most one per AU)
167 * or any packet if buffer_pkt is empty. The latter is needed to
168 * passthrough positions in case there are no timestamps like with
169 * the raw EVC demuxer. */
170 if (!buffer_pkt->data ||
171 in->pts != AV_NOPTS_VALUE && buffer_pkt->pts == AV_NOPTS_VALUE) {
172 err = av_packet_ref(buffer_pkt, in);
173 if (err < 0)
174 goto end;
175 }
176 }
177
178 // Buffer size is not enough for buffer to store NAL unit 4-bytes prefix (length)
180 return AVERROR_INVALIDDATA;
181
183 if (!nalu_size || nalu_size > INT_MAX) {
184 av_log(bsf, AV_LOG_ERROR, "Invalid NAL unit size: (%u)\n", nalu_size);
186 goto end;
187 }
188
189 if (in->size < nalu_size + EVC_NALU_LENGTH_PREFIX_SIZE) {
191 goto end;
192 }
193
194 err = parse_nal_unit(bsf, in->data + EVC_NALU_LENGTH_PREFIX_SIZE, nalu_size);
195 if (err < 0) {
196 av_log(bsf, AV_LOG_ERROR, "Parsing of NAL unit failed\n");
197 goto end;
198 }
199 au_end_found = err;
200
201 nalu_size += EVC_NALU_LENGTH_PREFIX_SIZE;
202
203 data_size = ctx->au_buffer.data_size + nalu_size;
204 if (data_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
205 av_log(bsf, AV_LOG_ERROR, "Assembled packet is too big\n");
206 err = AVERROR(ERANGE);
207 goto end;
208 }
209
210 buffer = av_fast_realloc(ctx->au_buffer.data, &ctx->au_buffer.capacity,
211 data_size);
212 if (!buffer) {
213 av_freep(&ctx->au_buffer.data);
215 goto end;
216 }
217
218 ctx->au_buffer.data = buffer;
219 memcpy(ctx->au_buffer.data + ctx->au_buffer.data_size, in->data, nalu_size);
220
221 ctx->au_buffer.data_size = data_size;
222
223 in->data += nalu_size;
224 in->size -= nalu_size;
225 }
226
227 av_packet_unref(in);
228 data_size = ctx->au_buffer.data_size;
229
230 ctx->au_buffer.data_size = 0;
231 // drop the data in buffer_pkt, if any, but keep the props
232 av_buffer_unref(&buffer_pkt->buf);
233 err = av_buffer_realloc(&buffer_pkt->buf, data_size + AV_INPUT_BUFFER_PADDING_SIZE);
234 if (err < 0)
235 goto end;
236
237 buffer_pkt->data = buffer_pkt->buf->data;
238 buffer_pkt->size = data_size;
239 av_packet_move_ref(out, buffer_pkt);
240 memcpy(out->data, ctx->au_buffer.data, data_size);
241 memset(out->data + data_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
242
243 err = 0;
244end:
245 if (err < 0) {
246 av_packet_unref(in);
247 av_packet_unref(buffer_pkt);
248 ctx->au_buffer.data_size = 0;
249 }
250 return err;
251}
252
254{
256
257 ctx->in = av_packet_alloc();
258 ctx->buffer_pkt = av_packet_alloc();
259 if (!ctx->in || !ctx->buffer_pkt)
260 return AVERROR(ENOMEM);
261
262 return 0;
263}
264
266{
268
269 av_packet_free(&ctx->in);
270 av_packet_free(&ctx->buffer_pkt);
271 ff_evc_ps_free(&ctx->ps);
272
273 ctx->au_buffer.capacity = 0;
274 av_freep(&ctx->au_buffer.data);
275 ctx->au_buffer.data_size = 0;
276}
277
281
283 .p.name = "evc_frame_merge",
284 .p.codec_ids = evc_frame_merge_codec_ids,
285 .priv_data_size = sizeof(EVCFMergeContext),
290};
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
const FFBitStreamFilter ff_evc_frame_merge_bsf
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition bsf.c:254
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
uint64_t pps
Definition dovi_rpuenc.c:36
void(* flush)(AVBSFContext *ctx)
Definition dts2pts.c:610
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static enum AVCodecID evc_frame_merge_codec_ids[]
static void evc_frame_merge_close(AVBSFContext *bsf)
static int evc_frame_merge_init(AVBSFContext *bsf)
static void evc_frame_merge_flush(AVBSFContext *bsf)
static int parse_nal_unit(AVBSFContext *bsf, const uint8_t *buf, int buf_size)
static int end_of_access_unit_found(const EVCParamSets *ps, const EVCParserSliceHeader *sh, const EVCParserPoc *poc, enum EVCNALUnitType nalu_type)
static int evc_frame_merge_filter(AVBSFContext *bsf, AVPacket *out)
int ff_evc_parse_slice_header(GetBitContext *gb, EVCParserSliceHeader *sh, const EVCParamSets *ps, enum EVCNALUnitType nalu_type)
Definition evc_parse.c:24
int ff_evc_derive_poc(const EVCParamSets *ps, const EVCParserSliceHeader *sh, EVCParserPoc *poc, enum EVCNALUnitType nalu_type, int tid)
Definition evc_parse.c:140
EVC decoder/parser shared code.
static uint32_t evc_read_nal_unit_length(const uint8_t *bits, int bits_size, void *logctx)
Definition evc_parse.h:83
int ff_evc_parse_pps(GetBitContext *gb, EVCParamSets *ps)
Definition evc_ps.c:352
void ff_evc_ps_free(EVCParamSets *ps)
Definition evc_ps.c:437
int ff_evc_parse_sps(GetBitContext *gb, EVCParamSets *ps)
Definition evc_ps.c:152
EVC decoder/parser shared code.
bitstream reader API header.
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 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
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_EVC
Definition codec_id.h:316
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition packet.c:74
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition packet.c:491
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition packet.c:63
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition packet.c:442
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
int av_buffer_realloc(AVBufferRef **pbuf, size_t size)
Reallocate a given buffer.
Definition buffer.c:183
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
EVCNALUnitType
Definition evc.h:33
@ EVC_UNSPEC_NUT62
Definition evc.h:96
@ EVC_SPS_NUT
Definition evc.h:58
@ EVC_APS_NUT
Definition evc.h:60
@ EVC_SEI_NUT
Definition evc.h:62
@ EVC_PPS_NUT
Definition evc.h:59
@ EVC_IDR_NUT
Definition evc.h:35
@ EVC_FD_NUT
Definition evc.h:61
@ EVC_NOIDR_NUT
Definition evc.h:34
#define EVC_NALU_LENGTH_PREFIX_SIZE
Definition evc.h:26
Memory handling functions.
The bitstream filter state.
Definition bsf.h:68
void * priv_data
Opaque filter-specific private data.
Definition bsf.h:83
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
uint8_t * data
Definition packet.h:603
AVPacket * buffer_pkt
AccessUnitBuffer au_buffer
EVCParserPPS * pps[EVC_MAX_PPS_COUNT]
Definition evc_ps.h:213
EVCParserSPS * sps[EVC_MAX_SPS_COUNT]
Definition evc_ps.h:212
int PicOrderCntVal
Definition evc_parse.h:78
int prevPicOrderCntVal
Definition evc_parse.h:79
uint8_t slice_pic_parameter_set_id
Definition evc_parse.h:43
#define av_freep(p)
#define av_log(a,...)
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
Definition h263dsp.c:29
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
static char buffer[20]
Definition seek.c:32