diff options
author | Rodger Combs <rodger.combs@gmail.com> | 2015-10-07 21:23:11 -0500 |
---|---|---|
committer | Rodger Combs <rodger.combs@gmail.com> | 2015-12-28 08:34:30 -0600 |
commit | 4caa3e1c6cf452154e811fea3685b2dea50d3a7a (patch) | |
tree | 356a73dae7ec00d9e104e7d94f987633bd0e39d7 /libavformat/utils.c | |
parent | 397774603690b2f24222aded19b5f8a41d830fc1 (diff) | |
download | ffmpeg-4caa3e1c6cf452154e811fea3685b2dea50d3a7a.tar.gz |
lavf: add API to apply a list of bsfs to a packet
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r-- | libavformat/utils.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c index 2f864c682a..7e101a4fd3 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -4650,3 +4650,52 @@ uint8_t *av_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type, sd->size = size; return data; } + +int av_apply_bitstream_filters(AVCodecContext *codec, AVPacket *pkt, + AVBitStreamFilterContext *bsfc) +{ + int ret = 0; + while (bsfc) { + AVPacket new_pkt = *pkt; + int a = av_bitstream_filter_filter(bsfc, codec, NULL, + &new_pkt.data, &new_pkt.size, + pkt->data, pkt->size, + pkt->flags & AV_PKT_FLAG_KEY); + if(a == 0 && new_pkt.data != pkt->data) { + uint8_t *t = av_malloc(new_pkt.size + AV_INPUT_BUFFER_PADDING_SIZE); //the new should be a subset of the old so cannot overflow + if (t) { + memcpy(t, new_pkt.data, new_pkt.size); + memset(t + new_pkt.size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + new_pkt.data = t; + new_pkt.buf = NULL; + a = 1; + } else { + a = AVERROR(ENOMEM); + } + } + if (a > 0) { + new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size, + av_buffer_default_free, NULL, 0); + if (new_pkt.buf) { + pkt->side_data = NULL; + pkt->side_data_elems = 0; + av_packet_unref(pkt); + } else { + av_freep(&new_pkt.data); + a = AVERROR(ENOMEM); + } + } + if (a < 0) { + av_log(codec, AV_LOG_ERROR, + "Failed to open bitstream filter %s for stream %d with codec %s", + bsfc->filter->name, pkt->stream_index, + codec->codec ? codec->codec->name : "copy"); + ret = a; + break; + } + *pkt = new_pkt; + + bsfc = bsfc->next; + } + return ret; +} |