FFmpeg  4.3.7
av1_metadata_bsf.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/common.h"
20 #include "libavutil/opt.h"
21 
22 #include "bsf.h"
23 #include "bsf_internal.h"
24 #include "cbs.h"
25 #include "cbs_av1.h"
26 
27 enum {
31 };
32 
33 typedef struct AV1MetadataContext {
34  const AVClass *class;
35 
38 
39  int td;
40 
44 
47 
50 
53 
54 
57 {
59  AV1RawColorConfig *clc = &seq->color_config;
60  AV1RawTimingInfo *tim = &seq->timing_info;
61 
62  if (ctx->color_primaries >= 0 ||
63  ctx->transfer_characteristics >= 0 ||
64  ctx->matrix_coefficients >= 0) {
66 
67  if (ctx->color_primaries >= 0)
68  clc->color_primaries = ctx->color_primaries;
69  if (ctx->transfer_characteristics >= 0)
71  if (ctx->matrix_coefficients >= 0)
73  }
74 
75  if (ctx->color_range >= 0) {
76  if (clc->color_primaries == AVCOL_PRI_BT709 &&
79  av_log(bsf, AV_LOG_WARNING, "Warning: color_range cannot be set "
80  "on RGB streams encoded in BT.709 sRGB.\n");
81  } else {
82  clc->color_range = ctx->color_range;
83  }
84  }
85 
86  if (ctx->chroma_sample_position >= 0) {
87  if (clc->mono_chrome || !clc->subsampling_x || !clc->subsampling_y) {
88  av_log(bsf, AV_LOG_WARNING, "Warning: chroma_sample_position "
89  "can only be set for 4:2:0 streams.\n");
90  } else {
92  }
93  }
94 
95  if (ctx->tick_rate.num && ctx->tick_rate.den) {
96  int num, den;
97 
98  av_reduce(&num, &den, ctx->tick_rate.num, ctx->tick_rate.den,
99  UINT32_MAX > INT_MAX ? UINT32_MAX : INT_MAX);
100 
101  tim->time_scale = num;
102  tim->num_units_in_display_tick = den;
103  seq->timing_info_present_flag = 1;
104 
105  if (ctx->num_ticks_per_picture > 0) {
106  tim->equal_picture_interval = 1;
108  ctx->num_ticks_per_picture - 1;
109  }
110  }
111 
112  return 0;
113 }
114 
116 {
118  CodedBitstreamFragment *frag = &ctx->access_unit;
119  uint8_t *side_data;
120  int side_data_size;
121  int err, i;
122 
124  &side_data_size);
125  if (!side_data_size)
126  return 0;
127 
128  err = ff_cbs_read(ctx->cbc, frag, side_data, side_data_size);
129  if (err < 0) {
130  av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n");
131  return err;
132  }
133 
134  for (i = 0; i < frag->nb_units; i++) {
135  if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) {
136  AV1RawOBU *obu = frag->units[i].content;
138  if (err < 0)
139  return err;
140  }
141  }
142 
143  err = ff_cbs_write_fragment_data(ctx->cbc, frag);
144  if (err < 0) {
145  av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n");
146  return err;
147  }
148 
150  if (!side_data)
151  return AVERROR(ENOMEM);
152  memcpy(side_data, frag->data, frag->data_size);
153 
154  ff_cbs_fragment_reset(ctx->cbc, frag);
155 
156  return 0;
157 }
158 
160 {
162  CodedBitstreamFragment *frag = &ctx->access_unit;
163  AV1RawOBU td, *obu;
164  int err, i;
165 
166  err = ff_bsf_get_packet_ref(bsf, pkt);
167  if (err < 0)
168  return err;
169 
170  err = av1_metadata_update_side_data(bsf, pkt);
171  if (err < 0)
172  goto fail;
173 
174  err = ff_cbs_read_packet(ctx->cbc, frag, pkt);
175  if (err < 0) {
176  av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
177  goto fail;
178  }
179 
180  if (frag->nb_units == 0) {
181  av_log(bsf, AV_LOG_ERROR, "No OBU in packet.\n");
182  err = AVERROR_INVALIDDATA;
183  goto fail;
184  }
185 
186  for (i = 0; i < frag->nb_units; i++) {
187  if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) {
188  obu = frag->units[i].content;
190  if (err < 0)
191  goto fail;
192  }
193  }
194 
195  // If a Temporal Delimiter is present, it must be the first OBU.
196  if (frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) {
197  if (ctx->td == REMOVE)
198  ff_cbs_delete_unit(ctx->cbc, frag, 0);
199  } else if (ctx->td == INSERT) {
200  td = (AV1RawOBU) {
202  };
203 
205  &td, NULL);
206  if (err < 0) {
207  av_log(bsf, AV_LOG_ERROR, "Failed to insert Temporal Delimiter.\n");
208  goto fail;
209  }
210  }
211 
212  if (ctx->delete_padding) {
213  for (i = frag->nb_units - 1; i >= 0; i--) {
214  if (frag->units[i].type == AV1_OBU_PADDING)
215  ff_cbs_delete_unit(ctx->cbc, frag, i);
216  }
217  }
218 
219  err = ff_cbs_write_packet(ctx->cbc, pkt, frag);
220  if (err < 0) {
221  av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
222  goto fail;
223  }
224 
225  err = 0;
226 fail:
227  ff_cbs_fragment_reset(ctx->cbc, frag);
228 
229  if (err < 0)
230  av_packet_unref(pkt);
231 
232  return err;
233 }
234 
236 {
238  CodedBitstreamFragment *frag = &ctx->access_unit;
239  AV1RawOBU *obu;
240  int err, i;
241 
242  err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_AV1, bsf);
243  if (err < 0)
244  return err;
245 
246  if (bsf->par_in->extradata) {
247  err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in);
248  if (err < 0) {
249  av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
250  goto fail;
251  }
252 
253  for (i = 0; i < frag->nb_units; i++) {
254  if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) {
255  obu = frag->units[i].content;
257  if (err < 0)
258  goto fail;
259  }
260  }
261 
262  err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag);
263  if (err < 0) {
264  av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
265  goto fail;
266  }
267  }
268 
269  err = 0;
270 fail:
271  ff_cbs_fragment_reset(ctx->cbc, frag);
272  return err;
273 }
274 
276 {
278 
279  ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit);
280  ff_cbs_close(&ctx->cbc);
281 }
282 
283 #define OFFSET(x) offsetof(AV1MetadataContext, x)
284 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
285 static const AVOption av1_metadata_options[] = {
286  { "td", "Temporal Delimiter OBU",
288  { .i64 = PASS }, PASS, REMOVE, FLAGS, "td" },
289  { "pass", NULL, 0, AV_OPT_TYPE_CONST,
290  { .i64 = PASS }, .flags = FLAGS, .unit = "td" },
291  { "insert", NULL, 0, AV_OPT_TYPE_CONST,
292  { .i64 = INSERT }, .flags = FLAGS, .unit = "td" },
293  { "remove", NULL, 0, AV_OPT_TYPE_CONST,
294  { .i64 = REMOVE }, .flags = FLAGS, .unit = "td" },
295 
296  { "color_primaries", "Set color primaries (section 6.4.2)",
298  { .i64 = -1 }, -1, 255, FLAGS },
299  { "transfer_characteristics", "Set transfer characteristics (section 6.4.2)",
301  { .i64 = -1 }, -1, 255, FLAGS },
302  { "matrix_coefficients", "Set matrix coefficients (section 6.4.2)",
304  { .i64 = -1 }, -1, 255, FLAGS },
305 
306  { "color_range", "Set color range flag (section 6.4.2)",
308  { .i64 = -1 }, -1, 1, FLAGS, "cr" },
309  { "tv", "TV (limited) range", 0, AV_OPT_TYPE_CONST,
310  { .i64 = 0 }, .flags = FLAGS, .unit = "cr" },
311  { "pc", "PC (full) range", 0, AV_OPT_TYPE_CONST,
312  { .i64 = 1 }, .flags = FLAGS, .unit = "cr" },
313 
314  { "chroma_sample_position", "Set chroma sample position (section 6.4.2)",
316  { .i64 = -1 }, -1, 3, FLAGS, "csp" },
317  { "unknown", "Unknown chroma sample position", 0, AV_OPT_TYPE_CONST,
318  { .i64 = AV1_CSP_UNKNOWN }, .flags = FLAGS, .unit = "csp" },
319  { "vertical", "Left chroma sample position", 0, AV_OPT_TYPE_CONST,
320  { .i64 = AV1_CSP_VERTICAL }, .flags = FLAGS, .unit = "csp" },
321  { "colocated", "Top-left chroma sample position", 0, AV_OPT_TYPE_CONST,
322  { .i64 = AV1_CSP_COLOCATED }, .flags = FLAGS, .unit = "csp" },
323 
324  { "tick_rate", "Set display tick rate (num_units_in_display_tick / time_scale)",
326  { .dbl = 0.0 }, 0, UINT_MAX, FLAGS },
327  { "num_ticks_per_picture", "Set display ticks per picture for CFR streams",
329  { .i64 = -1 }, -1, INT_MAX, FLAGS },
330 
331  { "delete_padding", "Delete all Padding OBUs",
333  { .i64 = 0 }, 0, 1, FLAGS},
334 
335  { NULL }
336 };
337 
338 static const AVClass av1_metadata_class = {
339  .class_name = "av1_metadata_bsf",
340  .item_name = av_default_item_name,
341  .option = av1_metadata_options,
342  .version = LIBAVUTIL_VERSION_INT,
343 };
344 
345 static const enum AVCodecID av1_metadata_codec_ids[] = {
347 };
348 
350  .name = "av1_metadata",
351  .priv_data_size = sizeof(AV1MetadataContext),
352  .priv_class = &av1_metadata_class,
354  .close = &av1_metadata_close,
357 };
#define NULL
Definition: coverity.c:32
int nb_units
Number of units in this fragment.
Definition: cbs.h:147
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
AVCodecParameters * par_out
Parameters of the output stream.
Definition: bsf.h:83
AVOption.
Definition: opt.h:246
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
uint32_t time_scale
Definition: cbs_av1.h:60
int ff_cbs_write_packet(CodedBitstreamContext *ctx, AVPacket *pkt, CodedBitstreamFragment *frag)
Write the bitstream of a fragment to a packet.
Definition: cbs.c:401
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
uint8_t mono_chrome
Definition: cbs_av1.h:44
int ff_cbs_init(CodedBitstreamContext **ctx_ptr, enum AVCodecID codec_id, void *log_ctx)
Create and initialise a new context for the given codec.
Definition: cbs.c:74
void ff_cbs_delete_unit(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int position)
Delete a unit from a fragment and free all memory it uses.
Definition: cbs.c:799
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:68
int num
Numerator.
Definition: rational.h:59
The bitstream filter state.
Definition: bsf.h:49
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, AVBufferRef *content_buf)
Insert a new unit into a fragment with the given content.
Definition: cbs.c:722
color_range
uint8_t timing_info_present_flag
Definition: cbs_av1.h:78
uint32_t num_units_in_display_tick
Definition: cbs_av1.h:59
static AVPacket pkt
uint8_t color_range
Definition: cbs_av1.h:51
static const AVClass av1_metadata_class
void * priv_data
Opaque filter-specific private data.
Definition: bsf.h:70
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
Definition: pixfmt.h:510
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
static void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride, int16_t *high, ptrdiff_t high_stride, int len, int clip)
Definition: cfhd.c:196
uint8_t matrix_coefficients
Definition: cbs_av1.h:49
uint8_t
AVOptions.
static enum AVCodecID av1_metadata_codec_ids[]
const AVBitStreamFilter ff_av1_metadata_bsf
int ff_cbs_read_packet(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVPacket *pkt)
Read the data bitstream from a packet into a fragment, then split into units and decompose.
Definition: cbs.c:242
const char * name
Definition: bsf.h:99
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:101
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:162
#define av_log(a,...)
size_t data_size
The number of bytes in the bitstream.
Definition: cbs.h:129
void ff_cbs_fragment_free(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Free the units array of a fragment in addition to what ff_cbs_fragment_reset does.
Definition: cbs.c:157
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
CodedBitstreamContext * cbc
#define AVERROR(e)
Definition: error.h:43
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size)
Get side information from packet.
Definition: avpacket.c:353
static int av1_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
Definition: pixfmt.h:457
union AV1RawOBU::@25 obu
#define fail()
Definition: checkasm.h:123
#define FLAGS
AV1RawColorConfig color_config
Definition: cbs_av1.h:128
int ff_cbs_write_extradata(CodedBitstreamContext *ctx, AVCodecParameters *par, CodedBitstreamFragment *frag)
Write the bitstream of a fragment to the extradata in codec parameters.
Definition: cbs.c:376
static const AVOption av1_metadata_options[]
AV1RawOBUHeader header
Definition: cbs_av1.h:388
AVFormatContext * ctx
Definition: movenc.c:48
static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
uint8_t color_primaries
Definition: cbs_av1.h:47
static int av1_metadata_update_sequence_header(AVBSFContext *bsf, AV1RawSequenceHeader *seq)
static int av1_metadata_init(AVBSFContext *bsf)
uint8_t * data
Pointer to the bitstream form of this fragment.
Definition: cbs.h:122
int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Write the content of the fragment to its own internal buffer.
Definition: cbs.c:340
uint8_t subsampling_y
Definition: cbs_av1.h:53
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:55
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:116
uint8_t subsampling_x
Definition: cbs_av1.h:52
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:605
Describe the class of an AVClass context structure.
Definition: log.h:67
void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Free the units contained in a fragment as well as the fragment&#39;s own data buffer, but not the units a...
Definition: cbs.c:142
Context structure for coded bitstream operations.
Definition: cbs.h:168
Rational number (pair of numerator and denominator).
Definition: rational.h:58
uint8_t color_description_present_flag
Definition: cbs_av1.h:46
#define OFFSET(x)
void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:115
uint8_t obu_type
Definition: cbs_av1.h:31
int ff_cbs_read_extradata(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVCodecParameters *par)
Read the extradata bitstream found in codec parameters into a fragment, then split into units and dec...
Definition: cbs.c:224
uint32_t num_ticks_per_picture_minus_1
Definition: cbs_av1.h:63
AV1RawSequenceHeader sequence_header
Definition: cbs_av1.h:393
uint8_t equal_picture_interval
Definition: cbs_av1.h:62
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:494
common internal and external API header
static enum AVCodecID codec_ids[]
int den
Denominator.
Definition: rational.h:60
CodedBitstreamFragment access_unit
static void av1_metadata_close(AVBSFContext *bsf)
uint8_t chroma_sample_position
Definition: cbs_av1.h:54
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:74
AV1RawTimingInfo timing_info
Definition: cbs_av1.h:83
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
Definition: avpacket.c:332
int ff_cbs_read(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const uint8_t *data, size_t size)
Read a bitstream from a memory region into a fragment, then split into units and decompose.
Definition: cbs.c:269
This structure stores compressed data.
Definition: packet.h:332
AVCodecParameters * par_in
Parameters of the input stream.
Definition: bsf.h:77
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:249
uint8_t transfer_characteristics
Definition: cbs_av1.h:48