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 "bsf_internal.h"
26 #include "cbs.h"
27 
28 
29 typedef struct FilterUnitsContext {
30  const AVClass *class;
31 
34 
35  const char *pass_types;
36  const char *remove_types;
37 
38  enum {
42  } mode;
44  int nb_types;
46 
47 
48 static int filter_units_make_type_list(const char *list_string,
49  CodedBitstreamUnitType **type_list,
50  int *nb_types)
51 {
53  int pass, count;
54 
55  for (pass = 1; pass <= 2; pass++) {
56  long value, range_start, range_end;
57  const char *str;
58  char *value_end;
59 
60  count = 0;
61  for (str = list_string; *str;) {
62  value = strtol(str, &value_end, 0);
63  if (str == value_end)
64  goto invalid;
65  str = (const char *)value_end;
66  if (*str == '-') {
67  ++str;
68  range_start = value;
69  range_end = strtol(str, &value_end, 0);
70  if (str == value_end)
71  goto invalid;
72 
73  for (value = range_start; value < range_end; value++) {
74  if (pass == 2)
75  list[count] = value;
76  ++count;
77  }
78  } else {
79  if (pass == 2)
80  list[count] = value;
81  ++count;
82  }
83  if (*str == '|')
84  ++str;
85  }
86  if (pass == 1) {
87  list = av_malloc_array(count, sizeof(*list));
88  if (!list)
89  return AVERROR(ENOMEM);
90  }
91  }
92 
93  *type_list = list;
94  *nb_types = count;
95  return 0;
96 
97 invalid:
98  av_freep(&list);
99  return AVERROR(EINVAL);
100 }
101 
103 {
105  CodedBitstreamFragment *frag = &ctx->fragment;
106  int err, i, j;
107 
108  err = ff_bsf_get_packet_ref(bsf, pkt);
109  if (err < 0)
110  return err;
111 
112  if (ctx->mode == NOOP)
113  return 0;
114 
115  err = ff_cbs_read_packet(ctx->cbc, frag, pkt);
116  if (err < 0) {
117  av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
118  goto fail;
119  }
120 
121  for (i = frag->nb_units - 1; i >= 0; i--) {
122  for (j = 0; j < ctx->nb_types; j++) {
123  if (frag->units[i].type == ctx->type_list[j])
124  break;
125  }
126  if (ctx->mode == REMOVE ? j < ctx->nb_types
127  : j >= ctx->nb_types)
128  ff_cbs_delete_unit(frag, i);
129  }
130 
131  if (frag->nb_units == 0) {
132  // Don't return packets with nothing in them.
133  err = AVERROR(EAGAIN);
134  goto fail;
135  }
136 
137  err = ff_cbs_write_packet(ctx->cbc, pkt, frag);
138  if (err < 0) {
139  av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
140  goto fail;
141  }
142 
143 fail:
144  if (err < 0)
146  ff_cbs_fragment_reset(frag);
147 
148  return err;
149 }
150 
152 {
154  int err;
155 
156  if (ctx->pass_types && ctx->remove_types) {
157  av_log(bsf, AV_LOG_ERROR, "Exactly one of pass_types or "
158  "remove_types is required.\n");
159  return AVERROR(EINVAL);
160  }
161 
162  if (ctx->pass_types) {
163  ctx->mode = PASS;
164  err = filter_units_make_type_list(ctx->pass_types,
165  &ctx->type_list, &ctx->nb_types);
166  if (err < 0) {
167  av_log(bsf, AV_LOG_ERROR, "Failed to parse pass_types.\n");
168  return err;
169  }
170  } else if (ctx->remove_types) {
171  ctx->mode = REMOVE;
172  err = filter_units_make_type_list(ctx->remove_types,
173  &ctx->type_list, &ctx->nb_types);
174  if (err < 0) {
175  av_log(bsf, AV_LOG_ERROR, "Failed to parse remove_types.\n");
176  return err;
177  }
178  } else {
179  return 0;
180  }
181 
182  err = ff_cbs_init(&ctx->cbc, bsf->par_in->codec_id, bsf);
183  if (err < 0)
184  return err;
185 
186  // Don't actually decompose anything, we only want the unit data.
187  ctx->cbc->decompose_unit_types = ctx->type_list;
188  ctx->cbc->nb_decompose_unit_types = 0;
189 
190  if (bsf->par_in->extradata) {
191  CodedBitstreamFragment *frag = &ctx->fragment;
192 
193  err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in);
194  if (err < 0) {
195  av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
196  } else {
197  err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, frag);
198  if (err < 0)
199  av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
200  }
201 
202  ff_cbs_fragment_reset(frag);
203  }
204 
205  return err;
206 }
207 
209 {
211 
212  av_freep(&ctx->type_list);
213 
214  ff_cbs_fragment_free(&ctx->fragment);
215  ff_cbs_close(&ctx->cbc);
216 }
217 
218 #define OFFSET(x) offsetof(FilterUnitsContext, x)
219 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM)
220 static const AVOption filter_units_options[] = {
221  { "pass_types", "List of unit types to pass through the filter.",
222  OFFSET(pass_types), AV_OPT_TYPE_STRING,
223  { .str = NULL }, .flags = FLAGS },
224  { "remove_types", "List of unit types to remove in the filter.",
225  OFFSET(remove_types), AV_OPT_TYPE_STRING,
226  { .str = NULL }, .flags = FLAGS },
227 
228  { NULL }
229 };
230 
231 static const AVClass filter_units_class = {
232  .class_name = "filter_units",
233  .item_name = av_default_item_name,
234  .option = filter_units_options,
235  .version = LIBAVUTIL_VERSION_INT,
236 };
237 
239  .p.name = "filter_units",
240  .p.codec_ids = ff_cbs_all_codec_ids,
241  .p.priv_class = &filter_units_class,
242  .priv_data_size = sizeof(FilterUnitsContext),
244  .close = &filter_units_close,
246 };
filter_units_filter
static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt)
Definition: filter_units_bsf.c:102
filter_units_close
static void filter_units_close(AVBSFContext *bsf)
Definition: filter_units_bsf.c:208
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:422
AVBSFContext::par_in
AVCodecParameters * par_in
Parameters of the input stream.
Definition: bsf.h:90
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:75
FilterUnitsContext::pass_types
const char * pass_types
Definition: filter_units_bsf.c:35
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
bsf_internal.h
opt.h
ff_cbs_fragment_free
av_cold void ff_cbs_fragment_free(CodedBitstreamFragment *frag)
Free the units array of a fragment in addition to what ff_cbs_fragment_reset does.
Definition: cbs.c:171
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:271
AVBitStreamFilter::name
const char * name
Definition: bsf.h:112
FilterUnitsContext::cbc
CodedBitstreamContext * cbc
Definition: filter_units_bsf.c:32
ff_cbs_fragment_reset
void ff_cbs_fragment_reset(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:157
CodedBitstreamContext
Context structure for coded bitstream operations.
Definition: cbs.h:173
AVOption
AVOption.
Definition: opt.h:251
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:73
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:36
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
ff_cbs_close
av_cold void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:127
init
static int init
Definition: av_tx.c:47
bsf.h
fail
#define fail()
Definition: checkasm.h:131
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:430
AVBSFContext::par_out
AVCodecParameters * par_out
Parameters of the output stream.
Definition: bsf.h:96
FilterUnitsContext::nb_types
int nb_types
Definition: filter_units_bsf.c:44
CodedBitstreamFragment::units
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:167
pkt
AVPacket * pkt
Definition: movenc.c:59
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:121
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:455
ff_filter_units_bsf
const FFBitStreamFilter ff_filter_units_bsf
Definition: filter_units_bsf.c:238
FLAGS
#define FLAGS
Definition: filter_units_bsf.c:219
FilterUnitsContext::mode
enum FilterUnitsContext::@58 mode
FilterUnitsContext
Definition: filter_units_bsf.c:29
FilterUnitsContext::NOOP
@ NOOP
Definition: filter_units_bsf.c:39
ctx
AVFormatContext * ctx
Definition: movenc.c:48
OFFSET
#define OFFSET(x)
Definition: filter_units_bsf.c:218
pass
#define pass
Definition: fft_template.c:608
filter_units_options
static const AVOption filter_units_options[]
Definition: filter_units_bsf.c:220
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:48
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
FilterUnitsContext::type_list
CodedBitstreamUnitType * type_list
Definition: filter_units_bsf.c:43
FFBitStreamFilter
Definition: bsf_internal.h:27
ff_cbs_all_codec_ids
enum AVCodecID ff_cbs_all_codec_ids[]
Table of all supported codec IDs.
Definition: cbs.c:54
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
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
FFBitStreamFilter::p
AVBitStreamFilter p
The public AVBitStreamFilter.
Definition: bsf_internal.h:31
FilterUnitsContext::PASS
@ PASS
Definition: filter_units_bsf.c:40
FilterUnitsContext::REMOVE
@ REMOVE
Definition: filter_units_bsf.c:41
PASS
#define PASS(name)
Definition: fft_template.c:517
filter_units_class
static const AVClass filter_units_class
Definition: filter_units_bsf.c:231
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
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: bsf.h:83
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
CodedBitstreamUnitType
uint32_t CodedBitstreamUnitType
The codec-specific type of a bitstream unit.
Definition: cbs.h:46
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:289
ff_cbs_init
av_cold 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:76
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:61
AVPacket
This structure stores compressed data.
Definition: packet.h:351
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
filter_units_init
static int filter_units_init(AVBSFContext *bsf)
Definition: filter_units_bsf.c:151
convert_header.str
string str
Definition: convert_header.py:20
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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:257
FilterUnitsContext::fragment
CodedBitstreamFragment fragment
Definition: filter_units_bsf.c:33
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:152
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:839