Message ID | 20191202161513.1693-1-jamrial@gmail.com |
---|---|
State | Superseded |
Headers | show |
On Mon, 02. Dec 13:15, James Almer wrote: > Signed-off-by: James Almer <jamrial@gmail.com> > --- > Untested. > > The BSF can be set the same way a decoder can in target_dec_fuzzer. The > codec_id will be randomly chosen from the supported list, if any. > > tools/Makefile | 3 + > tools/target_bsf_fuzzer.c | 166 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 169 insertions(+) > create mode 100644 tools/target_bsf_fuzzer.c > > diff --git a/tools/Makefile b/tools/Makefile > index 370ee35416..001093105b 100644 > --- a/tools/Makefile > +++ b/tools/Makefile > @@ -5,6 +5,9 @@ TOOLS-$(CONFIG_ZLIB) += cws2fws > tools/target_dec_%_fuzzer.o: tools/target_dec_fuzzer.c > $(COMPILE_C) -DFFMPEG_DECODER=$* > > +tools/target_bsf_%_fuzzer.o: tools/target_bsf_fuzzer.c > + $(COMPILE_C) -DFFMPEG_BSF=$* > + > tools/target_dem_fuzzer.o: tools/target_dem_fuzzer.c > $(COMPILE_C) > > diff --git a/tools/target_bsf_fuzzer.c b/tools/target_bsf_fuzzer.c > new file mode 100644 > index 0000000000..6849aaed0d > --- /dev/null > +++ b/tools/target_bsf_fuzzer.c > @@ -0,0 +1,166 @@ > +/* > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include "config.h" > +#include "libavutil/imgutils.h" > + > +#include "libavcodec/avcodec.h" > +#include "libavcodec/bsf.h" > +#include "libavcodec/bytestream.h" > +#include "libavcodec/internal.h" > + > +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); > + > +static void error(const char *err) > +{ > + fprintf(stderr, "%s", err); > + exit(1); > +} > + > +static AVBitStreamFilter *f = NULL; > + > +static const uint64_t FUZZ_TAG = 0x4741542D5A5A5546ULL; > + > +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { > + const uint64_t fuzz_tag = FUZZ_TAG; > + const uint8_t *last = data; > + const uint8_t *end = data + size; > + AVBSFContext *bsf = NULL; > + AVPacket in, out; > + uint64_t keyframes = 0; > + int res; > + > + if (!f) { > +#ifdef FFMPEG_BSF > +#define BSF_SYMBOL0(BSF) ff_##BSF##_bsf > +#define BSF_SYMBOL(BSF) BSF_SYMBOL0(BSF) > + extern AVBitStreamFilter BSF_SYMBOL(FFMPEG_BSF); > + f = &BSF_SYMBOL(FFMPEG_BSF); > +#else > + extern AVBitStreamFilter ff_null_bsf; > + f = &ff_null_bsf; > +#endif > + av_log_set_level(AV_LOG_PANIC); > + } > + > + res = av_bsf_alloc(f, &bsf); > + if (res < 0) > + error("Failed memory allocation"); > + > + if (size > 1024) { > + GetByteContext gbc; > + int extradata_size; > + size -= 1024; > + bytestream2_init(&gbc, data + size, 1024); > + bsf->par_in->width = bytestream2_get_le32(&gbc); > + bsf->par_in->height = bytestream2_get_le32(&gbc); > + bsf->par_in->bit_rate = bytestream2_get_le64(&gbc); > + bsf->par_in->bits_per_coded_sample = bytestream2_get_le32(&gbc); > + > + if (f->codec_ids) { > + int i, j, idx = bytestream2_get_byte(&gbc); Can you just read a bigger number instead of checking ++j == 8 below? Maybe bytestream2_get_be24()? > + int id = AV_CODEC_ID_NONE; > + for (i = 0, j = 0; f->codec_ids[i] != AV_CODEC_ID_NONE; i++) { > + // Iterate through all supported codec ids and get a random one > + if (idx & (1 << j)) { > + // There's at least one bsf that reports supporting more than eight codecs > + if (++j == 8) { > + idx = bytestream2_get_byte(&gbc); > + j = 0; > + } > + continue; > + } > + id = f->codec_ids[i]; > + break; > + } The selection of the codecs doesn't seem uniform. The probability of each codec is more like (1/2)^n, where n is codec index. I'm not sure if the fuzzer will eventually learn this. It may be better to use: id = idx % num_supported_codecs. But of course num_supported_codecs would have to be evaluated first. > + // Force using a codec if all were skipped > + if (id == AV_CODEC_ID_NONE) > + id = f->codec_ids[0]; > + bsf->par_in->codec_id = id; > + bsf->par_in->codec_tag = bytestream2_get_le32(&gbc); > + } > + > + extradata_size = bytestream2_get_le32(&gbc); > + > + bsf->par_in->sample_rate = bytestream2_get_le32(&gbc); > + bsf->par_in->channels = (unsigned)bytestream2_get_le32(&gbc) % FF_SANE_NB_CHANNELS; > + bsf->par_in->block_align = bytestream2_get_le32(&gbc); > + keyframes = bytestream2_get_le64(&gbc); > + > + if (extradata_size < size) { > + bsf->par_in->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); > + if (bsf->par_in->extradata) { > + bsf->par_in->extradata_size = extradata_size; > + size -= bsf->par_in->extradata_size; > + memcpy(bsf->par_in->extradata, data + size, bsf->par_in->extradata_size); > + } > + } > + if (av_image_check_size(bsf->par_in->width, bsf->par_in->height, 0, bsf)) > + bsf->par_in->width = bsf->par_in->height = 0; > + } > + > + res = av_bsf_init(bsf); > + if (res < 0) { > + av_bsf_free(&bsf); > + return 0; // Failure of av_bsf_init() does not imply that a issue was found > + } > + > + av_init_packet(&in); > + av_init_packet(&out); I think you also need to add: out.data = NULL; out.size = 0; Otherwise a random packet size is used in av_bsf_receive_packet(). > + while (data < end) { > + // Search for the TAG > + while (data + sizeof(fuzz_tag) < end) { > + if (data[0] == (fuzz_tag & 0xFF) && AV_RN64(data) == fuzz_tag) > + break; > + data++; > + } Is the idea here to add "FUZZ_TAG" via the -dict option when running the fuzzer? > + if (data + sizeof(fuzz_tag) > end) > + data = end; > + > + res = av_new_packet(&in, data - last); > + if (res < 0) > + error("Failed memory allocation"); > + memcpy(in.data, last, data - last); > + in.flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY; > + keyframes = (keyframes >> 2) + (keyframes<<62); > + data += sizeof(fuzz_tag); > + last = data; > + > + while (in.size) { > + res = av_bsf_send_packet(bsf, &in); > + if (res < 0 && res != AVERROR(EAGAIN)) > + break; > + res = av_bsf_receive_packet(bsf, &out); > + if (res < 0) > + break; > + av_packet_unref(&out); > + } > + av_packet_unref(&in); > + } > + > + res = av_bsf_send_packet(bsf, NULL); > + while (!res) { > + res = av_bsf_receive_packet(bsf, &out); > + if (res < 0) > + break; > + av_packet_unref(&out); > + } > + > + av_bsf_free(&bsf); > + return 0; > +}
On 12/3/2019 4:31 PM, Andriy Gelman wrote: > On Mon, 02. Dec 13:15, James Almer wrote: >> Signed-off-by: James Almer <jamrial@gmail.com> >> --- >> Untested. >> >> The BSF can be set the same way a decoder can in target_dec_fuzzer. The >> codec_id will be randomly chosen from the supported list, if any. >> >> tools/Makefile | 3 + >> tools/target_bsf_fuzzer.c | 166 ++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 169 insertions(+) >> create mode 100644 tools/target_bsf_fuzzer.c >> >> diff --git a/tools/Makefile b/tools/Makefile >> index 370ee35416..001093105b 100644 >> --- a/tools/Makefile >> +++ b/tools/Makefile >> @@ -5,6 +5,9 @@ TOOLS-$(CONFIG_ZLIB) += cws2fws >> tools/target_dec_%_fuzzer.o: tools/target_dec_fuzzer.c >> $(COMPILE_C) -DFFMPEG_DECODER=$* >> >> +tools/target_bsf_%_fuzzer.o: tools/target_bsf_fuzzer.c >> + $(COMPILE_C) -DFFMPEG_BSF=$* >> + >> tools/target_dem_fuzzer.o: tools/target_dem_fuzzer.c >> $(COMPILE_C) >> >> diff --git a/tools/target_bsf_fuzzer.c b/tools/target_bsf_fuzzer.c >> new file mode 100644 >> index 0000000000..6849aaed0d >> --- /dev/null >> +++ b/tools/target_bsf_fuzzer.c >> @@ -0,0 +1,166 @@ >> +/* >> + * This file is part of FFmpeg. >> + * >> + * FFmpeg is free software; you can redistribute it and/or >> + * modify it under the terms of the GNU Lesser General Public >> + * License as published by the Free Software Foundation; either >> + * version 2.1 of the License, or (at your option) any later version. >> + * >> + * FFmpeg is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + * Lesser General Public License for more details. >> + * >> + * You should have received a copy of the GNU Lesser General Public >> + * License along with FFmpeg; if not, write to the Free Software >> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA >> + */ >> + >> +#include "config.h" >> +#include "libavutil/imgutils.h" >> + >> +#include "libavcodec/avcodec.h" >> +#include "libavcodec/bsf.h" >> +#include "libavcodec/bytestream.h" >> +#include "libavcodec/internal.h" >> + >> +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); >> + >> +static void error(const char *err) >> +{ >> + fprintf(stderr, "%s", err); >> + exit(1); >> +} >> + >> +static AVBitStreamFilter *f = NULL; >> + >> +static const uint64_t FUZZ_TAG = 0x4741542D5A5A5546ULL; >> + >> +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { >> + const uint64_t fuzz_tag = FUZZ_TAG; >> + const uint8_t *last = data; >> + const uint8_t *end = data + size; >> + AVBSFContext *bsf = NULL; >> + AVPacket in, out; >> + uint64_t keyframes = 0; >> + int res; >> + >> + if (!f) { >> +#ifdef FFMPEG_BSF >> +#define BSF_SYMBOL0(BSF) ff_##BSF##_bsf >> +#define BSF_SYMBOL(BSF) BSF_SYMBOL0(BSF) >> + extern AVBitStreamFilter BSF_SYMBOL(FFMPEG_BSF); >> + f = &BSF_SYMBOL(FFMPEG_BSF); >> +#else >> + extern AVBitStreamFilter ff_null_bsf; >> + f = &ff_null_bsf; >> +#endif >> + av_log_set_level(AV_LOG_PANIC); >> + } >> + >> + res = av_bsf_alloc(f, &bsf); >> + if (res < 0) >> + error("Failed memory allocation"); >> + >> + if (size > 1024) { >> + GetByteContext gbc; >> + int extradata_size; >> + size -= 1024; >> + bytestream2_init(&gbc, data + size, 1024); >> + bsf->par_in->width = bytestream2_get_le32(&gbc); >> + bsf->par_in->height = bytestream2_get_le32(&gbc); >> + bsf->par_in->bit_rate = bytestream2_get_le64(&gbc); >> + bsf->par_in->bits_per_coded_sample = bytestream2_get_le32(&gbc); >> + > >> + if (f->codec_ids) { > >> + int i, j, idx = bytestream2_get_byte(&gbc); > > Can you just read a bigger number instead of checking ++j == 8 below? > Maybe bytestream2_get_be24()? The idea was read bytes until one bit was a 0 to signal to stop the loop. It would in theory work even with a bsf that supports INT_MAX amount of codecs, and eventually stop anyway since the GetByteContext would run out of data and start returning zeroes. > >> + int id = AV_CODEC_ID_NONE; >> + for (i = 0, j = 0; f->codec_ids[i] != AV_CODEC_ID_NONE; i++) { >> + // Iterate through all supported codec ids and get a random one >> + if (idx & (1 << j)) { >> + // There's at least one bsf that reports supporting more than eight codecs > >> + if (++j == 8) { >> + idx = bytestream2_get_byte(&gbc); >> + j = 0; >> + } >> + continue; >> + } >> + id = f->codec_ids[i]; >> + break; >> + } > > The selection of the codecs doesn't seem uniform. > The probability of each codec is more like (1/2)^n, where n is codec index. I'm > not sure if the fuzzer will eventually learn this. > > It may be better to use: id = idx % num_supported_codecs. But of course > num_supported_codecs would have to be evaluated first. Sure. With this even more reasons to just read one byte of random data. > >> + // Force using a codec if all were skipped >> + if (id == AV_CODEC_ID_NONE) >> + id = f->codec_ids[0]; >> + bsf->par_in->codec_id = id; >> + bsf->par_in->codec_tag = bytestream2_get_le32(&gbc); >> + } >> + >> + extradata_size = bytestream2_get_le32(&gbc); >> + >> + bsf->par_in->sample_rate = bytestream2_get_le32(&gbc); >> + bsf->par_in->channels = (unsigned)bytestream2_get_le32(&gbc) % FF_SANE_NB_CHANNELS; >> + bsf->par_in->block_align = bytestream2_get_le32(&gbc); >> + keyframes = bytestream2_get_le64(&gbc); >> + >> + if (extradata_size < size) { >> + bsf->par_in->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); >> + if (bsf->par_in->extradata) { >> + bsf->par_in->extradata_size = extradata_size; >> + size -= bsf->par_in->extradata_size; >> + memcpy(bsf->par_in->extradata, data + size, bsf->par_in->extradata_size); >> + } >> + } >> + if (av_image_check_size(bsf->par_in->width, bsf->par_in->height, 0, bsf)) >> + bsf->par_in->width = bsf->par_in->height = 0; >> + } >> + >> + res = av_bsf_init(bsf); >> + if (res < 0) { >> + av_bsf_free(&bsf); >> + return 0; // Failure of av_bsf_init() does not imply that a issue was found >> + } >> + >> + av_init_packet(&in); >> + av_init_packet(&out); > > I think you also need to add: > > out.data = NULL; > out.size = 0; > > Otherwise a random packet size is used in av_bsf_receive_packet(). Ah, for the data >= end case. Sure, will add an av_packet_unref() call before the flush code below for good measure instead. > > >> + while (data < end) { > >> + // Search for the TAG >> + while (data + sizeof(fuzz_tag) < end) { >> + if (data[0] == (fuzz_tag & 0xFF) && AV_RN64(data) == fuzz_tag) >> + break; >> + data++; >> + } > > Is the idea here to add "FUZZ_TAG" via the -dict option when running the > fuzzer? I don't know, but Michael might. > >> + if (data + sizeof(fuzz_tag) > end) >> + data = end; >> + >> + res = av_new_packet(&in, data - last); >> + if (res < 0) >> + error("Failed memory allocation"); >> + memcpy(in.data, last, data - last); >> + in.flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY; >> + keyframes = (keyframes >> 2) + (keyframes<<62); >> + data += sizeof(fuzz_tag); >> + last = data; >> + >> + while (in.size) { >> + res = av_bsf_send_packet(bsf, &in); >> + if (res < 0 && res != AVERROR(EAGAIN)) >> + break; >> + res = av_bsf_receive_packet(bsf, &out); >> + if (res < 0) >> + break; >> + av_packet_unref(&out); >> + } >> + av_packet_unref(&in); >> + } >> + >> + res = av_bsf_send_packet(bsf, NULL); >> + while (!res) { >> + res = av_bsf_receive_packet(bsf, &out); >> + if (res < 0) >> + break; >> + av_packet_unref(&out); >> + } >> + >> + av_bsf_free(&bsf); >> + return 0; >> +} >
On Tue, Dec 03, 2019 at 04:59:26PM -0300, James Almer wrote: > On 12/3/2019 4:31 PM, Andriy Gelman wrote: > > On Mon, 02. Dec 13:15, James Almer wrote: > >> Signed-off-by: James Almer <jamrial@gmail.com> > >> --- > >> Untested. > >> > >> The BSF can be set the same way a decoder can in target_dec_fuzzer. The > >> codec_id will be randomly chosen from the supported list, if any. > >> > >> tools/Makefile | 3 + > >> tools/target_bsf_fuzzer.c | 166 ++++++++++++++++++++++++++++++++++++++ > >> 2 files changed, 169 insertions(+) > >> create mode 100644 tools/target_bsf_fuzzer.c [...] > > > > > >> + while (data < end) { > > > >> + // Search for the TAG > >> + while (data + sizeof(fuzz_tag) < end) { > >> + if (data[0] == (fuzz_tag & 0xFF) && AV_RN64(data) == fuzz_tag) > >> + break; > >> + data++; > >> + } > > > > Is the idea here to add "FUZZ_TAG" via the -dict option when running the > > fuzzer? > > I don't know, but Michael might. I dont know how or if FUZZ_TAG "connects" back into the fuzzer. But the same issue also exist for every chunk, slice, packet header the fuzzer has to generate valid data thx [...]
diff --git a/tools/Makefile b/tools/Makefile index 370ee35416..001093105b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -5,6 +5,9 @@ TOOLS-$(CONFIG_ZLIB) += cws2fws tools/target_dec_%_fuzzer.o: tools/target_dec_fuzzer.c $(COMPILE_C) -DFFMPEG_DECODER=$* +tools/target_bsf_%_fuzzer.o: tools/target_bsf_fuzzer.c + $(COMPILE_C) -DFFMPEG_BSF=$* + tools/target_dem_fuzzer.o: tools/target_dem_fuzzer.c $(COMPILE_C) diff --git a/tools/target_bsf_fuzzer.c b/tools/target_bsf_fuzzer.c new file mode 100644 index 0000000000..6849aaed0d --- /dev/null +++ b/tools/target_bsf_fuzzer.c @@ -0,0 +1,166 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/imgutils.h" + +#include "libavcodec/avcodec.h" +#include "libavcodec/bsf.h" +#include "libavcodec/bytestream.h" +#include "libavcodec/internal.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +static void error(const char *err) +{ + fprintf(stderr, "%s", err); + exit(1); +} + +static AVBitStreamFilter *f = NULL; + +static const uint64_t FUZZ_TAG = 0x4741542D5A5A5546ULL; + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + const uint64_t fuzz_tag = FUZZ_TAG; + const uint8_t *last = data; + const uint8_t *end = data + size; + AVBSFContext *bsf = NULL; + AVPacket in, out; + uint64_t keyframes = 0; + int res; + + if (!f) { +#ifdef FFMPEG_BSF +#define BSF_SYMBOL0(BSF) ff_##BSF##_bsf +#define BSF_SYMBOL(BSF) BSF_SYMBOL0(BSF) + extern AVBitStreamFilter BSF_SYMBOL(FFMPEG_BSF); + f = &BSF_SYMBOL(FFMPEG_BSF); +#else + extern AVBitStreamFilter ff_null_bsf; + f = &ff_null_bsf; +#endif + av_log_set_level(AV_LOG_PANIC); + } + + res = av_bsf_alloc(f, &bsf); + if (res < 0) + error("Failed memory allocation"); + + if (size > 1024) { + GetByteContext gbc; + int extradata_size; + size -= 1024; + bytestream2_init(&gbc, data + size, 1024); + bsf->par_in->width = bytestream2_get_le32(&gbc); + bsf->par_in->height = bytestream2_get_le32(&gbc); + bsf->par_in->bit_rate = bytestream2_get_le64(&gbc); + bsf->par_in->bits_per_coded_sample = bytestream2_get_le32(&gbc); + + if (f->codec_ids) { + int i, j, idx = bytestream2_get_byte(&gbc); + int id = AV_CODEC_ID_NONE; + for (i = 0, j = 0; f->codec_ids[i] != AV_CODEC_ID_NONE; i++) { + // Iterate through all supported codec ids and get a random one + if (idx & (1 << j)) { + // There's at least one bsf that reports supporting more than eight codecs + if (++j == 8) { + idx = bytestream2_get_byte(&gbc); + j = 0; + } + continue; + } + id = f->codec_ids[i]; + break; + } + // Force using a codec if all were skipped + if (id == AV_CODEC_ID_NONE) + id = f->codec_ids[0]; + bsf->par_in->codec_id = id; + bsf->par_in->codec_tag = bytestream2_get_le32(&gbc); + } + + extradata_size = bytestream2_get_le32(&gbc); + + bsf->par_in->sample_rate = bytestream2_get_le32(&gbc); + bsf->par_in->channels = (unsigned)bytestream2_get_le32(&gbc) % FF_SANE_NB_CHANNELS; + bsf->par_in->block_align = bytestream2_get_le32(&gbc); + keyframes = bytestream2_get_le64(&gbc); + + if (extradata_size < size) { + bsf->par_in->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (bsf->par_in->extradata) { + bsf->par_in->extradata_size = extradata_size; + size -= bsf->par_in->extradata_size; + memcpy(bsf->par_in->extradata, data + size, bsf->par_in->extradata_size); + } + } + if (av_image_check_size(bsf->par_in->width, bsf->par_in->height, 0, bsf)) + bsf->par_in->width = bsf->par_in->height = 0; + } + + res = av_bsf_init(bsf); + if (res < 0) { + av_bsf_free(&bsf); + return 0; // Failure of av_bsf_init() does not imply that a issue was found + } + + av_init_packet(&in); + av_init_packet(&out); + while (data < end) { + // Search for the TAG + while (data + sizeof(fuzz_tag) < end) { + if (data[0] == (fuzz_tag & 0xFF) && AV_RN64(data) == fuzz_tag) + break; + data++; + } + if (data + sizeof(fuzz_tag) > end) + data = end; + + res = av_new_packet(&in, data - last); + if (res < 0) + error("Failed memory allocation"); + memcpy(in.data, last, data - last); + in.flags = (keyframes & 1) * AV_PKT_FLAG_DISCARD + (!!(keyframes & 2)) * AV_PKT_FLAG_KEY; + keyframes = (keyframes >> 2) + (keyframes<<62); + data += sizeof(fuzz_tag); + last = data; + + while (in.size) { + res = av_bsf_send_packet(bsf, &in); + if (res < 0 && res != AVERROR(EAGAIN)) + break; + res = av_bsf_receive_packet(bsf, &out); + if (res < 0) + break; + av_packet_unref(&out); + } + av_packet_unref(&in); + } + + res = av_bsf_send_packet(bsf, NULL); + while (!res) { + res = av_bsf_receive_packet(bsf, &out); + if (res < 0) + break; + av_packet_unref(&out); + } + + av_bsf_free(&bsf); + return 0; +}
Signed-off-by: James Almer <jamrial@gmail.com> --- Untested. The BSF can be set the same way a decoder can in target_dec_fuzzer. The codec_id will be randomly chosen from the supported list, if any. tools/Makefile | 3 + tools/target_bsf_fuzzer.c | 166 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 tools/target_bsf_fuzzer.c