FFmpeg
filter_units_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 <stdlib.h>
20 
21 #include "libavutil/common.h"
22 #include "libavutil/opt.h"
23 
24 #include "bsf.h"
25 #include "cbs.h"
26 
27 
28 typedef struct FilterUnitsContext {
29  const AVClass *class;
30 
33 
34  const char *pass_types;
35  const char *remove_types;
36 
37  enum {
41  } mode;
43  int nb_types;
45 
46 
47 static int filter_units_make_type_list(const char *list_string,
48  CodedBitstreamUnitType **type_list,
49  int *nb_types)
50 {
52  int pass, count;
53 
54  for (pass = 1; pass <= 2; pass++) {
55  long value, range_start, range_end;
56  const char *str;
57  char *value_end;
58 
59  count = 0;
60  for (str = list_string; *str;) {
61  value = strtol(str, &value_end, 0);
62  if (str == value_end)
63  goto invalid;
64  str = (const char *)value_end;
65  if (*str == '-') {
66  ++str;
67  range_start = value;
68  range_end = strtol(str, &value_end, 0);
69  if (str == value_end)
70  goto invalid;
71 
72  for (value = range_start; value < range_end; value++) {
73  if (pass == 2)
74  list[count] = value;
75  ++count;
76  }
77  } else {
78  if (pass == 2)
79  list[count] = value;
80  ++count;
81  }
82  if (*str == '|')
83  ++str;
84  }
85  if (pass == 1) {
86  list = av_malloc_array(count, sizeof(*list));
87  if (!list)
88  return AVERROR(ENOMEM);
89  }
90  }
91 
92  *type_list = list;
93  *nb_types = count;
94  return 0;
95 
96 invalid:
97  av_freep(&list);
98  return AVERROR(EINVAL);
99 }
100 
102 {
104  CodedBitstreamFragment *frag = &ctx->fragment;
105  int err, i, j;
106 
107  err = ff_bsf_get_packet_ref(bsf, pkt);
108  if (err < 0)
109  return err;
110 
111  if (ctx->mode == NOOP)
112  return 0;
113 
114  err = ff_cbs_read_packet(ctx->cbc, frag, pkt);
115  if (err < 0) {
116  av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
117  goto fail;
118  }
119 
120  for (i = frag->nb_units - 1; i >= 0; i--) {
121  for (j = 0; j < ctx->nb_types; j++) {
122  if (frag->units[i].type == ctx->type_list[j])
123  break;
124  }
125  if (ctx->mode == REMOVE ? j < ctx->nb_types
126  : j >= ctx->nb_types)
127  ff_cbs_delete_unit(ctx->cbc, frag, i);
128  }
129 
130  if (frag->nb_units == 0) {
131  // Don't return packets with nothing in them.
132  err = AVERROR(EAGAIN);
133  goto fail;
134  }
135 
136  err = ff_cbs_write_packet(ctx->cbc, pkt, frag);
137  if (err < 0) {
138  av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
139  goto fail;
140  }
141 
142 fail:
143  if (err < 0)
145  ff_cbs_fragment_reset(ctx->cbc, frag);
146 
147  return err;
148 }
149 
151 {
153  int err;
154 
155  if (ctx->pass_types && ctx->remove_types) {
156  av_log(bsf, AV_LOG_ERROR, "Exactly one of pass_types or "
157  "remove_types is required.\n");
158  return AVERROR(EINVAL);
159  }
160 
161  if (ctx->pass_types) {
162  ctx->mode = PASS;
163  err = filter_units_make_type_list(ctx->pass_types,
164  &ctx->type_list, &ctx->nb_types);
165  if (err < 0) {
166  av_log(bsf, AV_LOG_ERROR, "Failed to parse pass_types.\n");
167  return err;
168  }
169  } else if (ctx->remove_types) {
170  ctx->mode = REMOVE;
171  err = filter_units_make_type_list(ctx->remove_types,
172  &ctx->type_list, &ctx->nb_types);
173  if (err < 0) {
174  av_log(bsf, AV_LOG_ERROR, "Failed to parse remove_types.\n");
175  return err;
176  }
177  } else {
178  return 0;
179  }
180 
181  err = ff_cbs_init(&ctx->cbc, bsf->par_in->codec_id, bsf);
182  if (err < 0)
183  return err;
184 
185  // Don't actually decompose anything, we only want the unit data.
186  ctx->cbc->decompose_unit_types = ctx->type_list;
187  ctx->cbc->nb_decompose_unit_types = 0;
188 
189  if (bsf->par_in->extradata) {
190  CodedBitstreamFragment *frag = &ctx->fragment;
191 
192  err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in);
193  if (err < 0) {
194  av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
195  } else {
196  err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag);
197  if (err < 0)
198  av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
199  }
200 
201  ff_cbs_fragment_reset(ctx->cbc, frag);
202  }
203 
204  return err;
205 }
206 
208 {
210 
211  av_freep(&ctx->type_list);
212 
213  ff_cbs_fragment_free(ctx->cbc, &ctx->fragment);
214  ff_cbs_close(&ctx->cbc);
215 }
216 
217 #define OFFSET(x) offsetof(FilterUnitsContext, x)
218 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
219 static const AVOption filter_units_options[] = {
220  { "pass_types", "List of unit types to pass through the filter.",
221  OFFSET(pass_types), AV_OPT_TYPE_STRING,
222  { .str = NULL }, .flags = FLAGS },
223  { "remove_types", "List of unit types to remove in the filter.",
224  OFFSET(remove_types), AV_OPT_TYPE_STRING,
225  { .str = NULL }, .flags = FLAGS },
226 
227  { NULL }
228 };
229 
230 static const AVClass filter_units_class = {
231  .class_name = "filter_units",
232  .item_name = av_default_item_name,
233  .option = filter_units_options,
234  .version = LIBAVUTIL_VERSION_INT,
235 };
236 
238  .name = "filter_units",
239  .priv_data_size = sizeof(FilterUnitsContext),
240  .priv_class = &filter_units_class,
242  .close = &filter_units_close,
245 };
filter_units_filter
static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt)
Definition: filter_units_bsf.c:101
filter_units_close
static void filter_units_close(AVBSFContext *bsf)
Definition: filter_units_bsf.c:207
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:599
AVBSFContext::par_in
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5791
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3971
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
FilterUnitsContext::pass_types
const char * pass_types
Definition: filter_units_bsf.c:34
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
ff_cbs_read_extradata
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
AVBitStreamFilter::name
const char * name
Definition: avcodec.h:5813
FilterUnitsContext::cbc
CodedBitstreamContext * cbc
Definition: filter_units_bsf.c:31
count
void INT64 INT64 count
Definition: avisynth_c.h:767
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:168
ff_cbs_close
void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:115
AVOption
AVOption.
Definition: opt.h:246
ff_cbs_fragment_free
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
ff_filter_units_bsf
const AVBitStreamFilter ff_filter_units_bsf
Definition: filter_units_bsf.c:237
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:68
cbs.h
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
FilterUnitsContext::remove_types
const char * remove_types
Definition: filter_units_bsf.c:35
AVBSFContext
The bitstream filter state.
Definition: avcodec.h:5763
FilterUnitsContext::NOOP
@ NOOP
Definition: filter_units_bsf.c:38
bsf.h
FilterUnitsContext::mode
enum FilterUnitsContext::@80 mode
fail
#define fail()
Definition: checkasm.h:120
ff_cbs_write_extradata
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
AVBSFContext::par_out
AVCodecParameters * par_out
Parameters of the output stream.
Definition: avcodec.h:5797
FilterUnitsContext::nb_types
int nb_types
Definition: filter_units_bsf.c:43
CodedBitstreamFragment::units
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:162
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:116
ff_cbs_write_packet
int ff_cbs_write_packet(CodedBitstreamContext *ctx, AVPacket *pkt, CodedBitstreamFragment *frag)
Write the bitstream of a fragment to a packet.
Definition: cbs.c:401
FLAGS
#define FLAGS
Definition: filter_units_bsf.c:218
FilterUnitsContext
Definition: filter_units_bsf.c:28
ctx
AVFormatContext * ctx
Definition: movenc.c:48
ff_cbs_delete_unit
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:796
OFFSET
#define OFFSET(x)
Definition: filter_units_bsf.c:217
pass
#define pass
Definition: fft_template.c:619
filter_units_options
static const AVOption filter_units_options[]
Definition: filter_units_bsf.c:219
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
filter_units_make_type_list
static int filter_units_make_type_list(const char *list_string, CodedBitstreamUnitType **type_list, int *nb_types)
Definition: filter_units_bsf.c:47
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
FilterUnitsContext::type_list
CodedBitstreamUnitType * type_list
Definition: filter_units_bsf.c:42
ff_cbs_all_codec_ids
enum AVCodecID ff_cbs_all_codec_ids[]
Table of all supported codec IDs.
Definition: cbs.c:52
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
REMOVE
@ REMOVE
Definition: av1_metadata_bsf.c:29
PASS
#define PASS(name)
Definition: fft_template.c:528
filter_units_class
static const AVClass filter_units_class
Definition: filter_units_bsf.c:230
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
FilterUnitsContext::REMOVE
@ REMOVE
Definition: filter_units_bsf.c:40
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
common.h
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
AVBSFContext::priv_data
void * priv_data
Opaque filter-specific private data.
Definition: avcodec.h:5784
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:72
ff_cbs_init
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
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
CodedBitstreamUnitType
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
Definition: cbs.h:43
AVBitStreamFilter
Definition: avcodec.h:5812
ff_cbs_fragment_reset
void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
Free the units contained in a fragment as well as the fragment's own data buffer, but not the units a...
Definition: cbs.c:142
ff_cbs_read_packet
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
FilterUnitsContext::PASS
@ PASS
Definition: filter_units_bsf.c:39
codec_ids
static enum AVCodecID codec_ids[]
Definition: aac_adtstoasc_bsf.c:148
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3957
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
filter_units_init
static int filter_units_init(AVBSFContext *bsf)
Definition: filter_units_bsf.c:150
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ff_bsf_get_packet_ref
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
Called by bitstream filters to get packet for filtering.
Definition: bsf.c:239
FilterUnitsContext::fragment
CodedBitstreamFragment fragment
Definition: filter_units_bsf.c:32
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:227
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:147