FFmpeg
h266_metadata.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_bsf.h"
26 #include "cbs_h266.h"
27 #include "vvc.h"
28 
29 #define IS_H266_SLICE(nut) (nut <= VVC_RASL_NUT || (nut >= VVC_IDR_W_RADL && nut <= VVC_GDR_NUT))
30 
31 typedef struct H266MetadataContext {
33 
35 
36  int aud;
38 
41 {
43  int err, i;
44 
45  // If an AUD is present, it must be the first NAL unit.
46  if (pu->nb_units && pu->units[0].type == VVC_AUD_NUT) {
47  if (ctx->aud == BSF_ELEMENT_REMOVE)
48  ff_cbs_delete_unit(pu, 0);
49  } else if ( pkt && ctx->aud == BSF_ELEMENT_INSERT) {
50  const H266RawSlice *first_slice = NULL;
51  const H266RawPictureHeader *ph = NULL;
52  H266RawAUD *aud = &ctx->aud_nal;
53  int pic_type = 0, temporal_id = 8, layer_id = 0;
54  for (i = 0; i < pu->nb_units; i++) {
55  const H266RawNALUnitHeader *nal = pu->units[i].content;
56  if (!nal)
57  continue;
58  if (nal->nuh_temporal_id_plus1 < temporal_id + 1)
59  temporal_id = nal->nuh_temporal_id_plus1 - 1;
60  if ( nal->nal_unit_type == VVC_PH_NUT ) {
61  const H266RawPH *header = pu->units[i].content;
62  ph = &header->ph_picture_header;
63  } else if (IS_H266_SLICE(nal->nal_unit_type)) {
64  const H266RawSlice *slice = pu->units[i].content;
65  layer_id = nal->nuh_layer_id;
66  if (slice->header.sh_slice_type == VVC_SLICE_TYPE_B &&
67  pic_type < 2)
68  pic_type = 2;
69  if (slice->header.sh_slice_type == VVC_SLICE_TYPE_P &&
70  pic_type < 1)
71  pic_type = 1;
72  if (!first_slice) {
73  first_slice = slice;
74  if (first_slice->header.
75  sh_picture_header_in_slice_header_flag)
76  ph = &first_slice->header.sh_picture_header;
77  else if (!ph)
78  break;
79  }
80  }
81  }
82  if (!ph) {
83  av_log(bsf, AV_LOG_ERROR, "no avaliable picture header");
84  return AVERROR_INVALIDDATA;
85  }
86 
87  aud->nal_unit_header = (H266RawNALUnitHeader) {
88  .nal_unit_type = VVC_AUD_NUT,
89  .nuh_layer_id = layer_id,
90  .nuh_temporal_id_plus1 = temporal_id + 1,
91  };
92  aud->aud_pic_type = pic_type;
93  aud->aud_irap_or_gdr_flag = ph->ph_gdr_or_irap_pic_flag;
94 
96  if (err < 0) {
97  av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n");
98  return err;
99  }
100  }
101 
102  /* TODO: implement more metadata parsing, like VUI, Levels etc. */
103  //for (i = 0; i < pu->nb_units; i++) {
104  // if (pu->units[i].type == VVC_SPS_NUT) {
105  // }
106  //}
107  return 0;
108 }
109 
112  .fragment_name = "access unit",
113  .unit_name = "NAL unit",
114  .update_fragment = &h266_metadata_update_fragment,
115 };
116 
118 {
120 }
121 
122 #define OFFSET(x) offsetof(H266MetadataContext, x)
123 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
124 static const AVOption h266_metadata_options[] = {
125  BSF_ELEMENT_OPTIONS_PIR("aud", "Access Unit Delimiter NAL units",
126  aud, FLAGS),
127 
128  { NULL }
129 };
130 
131 static const AVClass h266_metadata_class = {
132  .class_name = "h266_metadata_bsf",
133  .item_name = av_default_item_name,
134  .option = h266_metadata_options,
135  .version = LIBAVUTIL_VERSION_INT,
136 };
137 
138 static const enum AVCodecID h266_metadata_codec_ids[] = {
140 };
141 
143  .p.name = "vvc_metadata",
144  .p.codec_ids = h266_metadata_codec_ids,
145  .p.priv_class = &h266_metadata_class,
146  .priv_data_size = sizeof(H266MetadataContext),
148  .close = &ff_cbs_bsf_generic_close,
150 };
cbs_h266.h
ff_cbs_bsf_generic_init
int ff_cbs_bsf_generic_init(AVBSFContext *bsf, const CBSBSFType *type)
Initialise generic CBS BSF setup.
Definition: cbs_bsf.c:110
bsf_internal.h
opt.h
CBSBSFType::codec_id
enum AVCodecID codec_id
Definition: cbs_bsf.h:32
CodedBitstreamUnit::content
void * content
Pointer to the decomposed form of this unit.
Definition: cbs.h:107
AVBitStreamFilter::name
const char * name
Definition: bsf.h:112
ff_cbs_insert_unit_content
int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, void *content_ref)
Insert a new unit into a fragment with the given content.
Definition: cbs.c:783
H266MetadataContext::common
CBSBSFContext common
Definition: h266_metadata.c:32
ph
static int FUNC() ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
Definition: cbs_h266_syntax_template.c:3003
AVOption
AVOption.
Definition: opt.h:346
CBSBSFContext
Definition: cbs_bsf.h:53
FLAGS
#define FLAGS
Definition: h266_metadata.c:123
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:74
cbs.h
H266RawNALUnitHeader::nuh_layer_id
uint8_t nuh_layer_id
Definition: cbs_h266.h:30
h266_metadata_type
static const CBSBSFType h266_metadata_type
Definition: h266_metadata.c:110
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
H266RawNALUnitHeader::nal_unit_type
uint8_t nal_unit_type
Definition: cbs_h266.h:31
VVC_AUD_NUT
@ VVC_AUD_NUT
Definition: vvc.h:49
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
BSF_ELEMENT_INSERT
@ BSF_ELEMENT_INSERT
Definition: cbs_bsf.h:104
H266RawAUD
Definition: cbs_h266.h:644
bsf.h
cbs_bsf.h
BSF_ELEMENT_REMOVE
@ BSF_ELEMENT_REMOVE
Definition: cbs_bsf.h:106
h266_metadata_update_fragment
static int h266_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, CodedBitstreamFragment *pu)
Definition: h266_metadata.c:39
CodedBitstreamFragment::units
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:168
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:122
H266MetadataContext::aud
int aud
Definition: h266_metadata.c:36
h266_metadata_class
static const AVClass h266_metadata_class
Definition: h266_metadata.c:131
H266RawNALUnitHeader::nuh_temporal_id_plus1
uint8_t nuh_temporal_id_plus1
Definition: cbs_h266.h:32
ctx
AVFormatContext * ctx
Definition: movenc.c:49
VVC_SLICE_TYPE_P
@ VVC_SLICE_TYPE_P
Definition: vvc.h:65
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
H266RawPictureHeader
Definition: cbs_h266.h:674
FFBitStreamFilter
Definition: bsf_internal.h:27
VVC_SLICE_TYPE_B
@ VVC_SLICE_TYPE_B
Definition: vvc.h:64
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
VVC_PH_NUT
@ VVC_PH_NUT
Definition: vvc.h:48
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:31
aud
static int FUNC() aud(CodedBitstreamContext *ctx, RWContext *rw, H264RawAUD *current)
Definition: cbs_h264_syntax_template.c:841
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:366
H266RawSliceHeader::sh_picture_header
H266RawPictureHeader sh_picture_header
Definition: cbs_h266.h:772
CBSBSFType
Definition: cbs_bsf.h:31
ff_cbs_bsf_generic_close
void ff_cbs_bsf_generic_close(AVBSFContext *bsf)
Close a generic CBS BSF instance.
Definition: cbs_bsf.c:155
H266MetadataContext
Definition: h266_metadata.c:31
header
static const uint8_t header[24]
Definition: sdr2.c:68
AV_CODEC_ID_VVC
@ AV_CODEC_ID_VVC
Definition: codec_id.h:250
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_vvc_metadata_bsf
const FFBitStreamFilter ff_vvc_metadata_bsf
Definition: h266_metadata.c:142
h266_metadata_codec_ids
static enum AVCodecID h266_metadata_codec_ids[]
Definition: h266_metadata.c:138
common.h
AVBSFContext::priv_data
void * priv_data
Opaque filter-specific private data.
Definition: bsf.h:83
ff_cbs_bsf_generic_filter
int ff_cbs_bsf_generic_filter(AVBSFContext *bsf, AVPacket *pkt)
Filter operation for CBS BSF.
Definition: cbs_bsf.c:61
AVClass::class_name
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:71
H266RawSliceHeader::sh_slice_type
uint8_t sh_slice_type
Definition: cbs_h266.h:778
h266_metadata_options
static const AVOption h266_metadata_options[]
Definition: h266_metadata.c:124
BSF_ELEMENT_OPTIONS_PIR
#define BSF_ELEMENT_OPTIONS_PIR(name, help, field, opt_flags)
Definition: cbs_bsf.h:112
H266RawSlice::header
H266RawSliceHeader header
Definition: cbs_h266.h:842
H266MetadataContext::aud_nal
H266RawAUD aud_nal
Definition: h266_metadata.c:34
H266RawPH
Definition: cbs_h266.h:764
IS_H266_SLICE
#define IS_H266_SLICE(nut)
Definition: h266_metadata.c:29
h266_metadata_init
static int h266_metadata_init(AVBSFContext *bsf)
Definition: h266_metadata.c:117
AVPacket
This structure stores compressed data.
Definition: packet.h:501
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
H266RawNALUnitHeader
Definition: cbs_h266.h:29
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:153
ff_cbs_delete_unit
void ff_cbs_delete_unit(CodedBitstreamFragment *frag, int position)
Delete a unit from a fragment and free all memory it uses.
Definition: cbs.c:860
H266RawSlice
Definition: cbs_h266.h:841