summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodger Combs <rodger.combs@gmail.com>2015-10-07 21:23:11 -0500
committerRodger Combs <rodger.combs@gmail.com>2015-12-28 08:34:30 -0600
commit4caa3e1c6cf452154e811fea3685b2dea50d3a7a (patch)
tree356a73dae7ec00d9e104e7d94f987633bd0e39d7
parent397774603690b2f24222aded19b5f8a41d830fc1 (diff)
lavf: add API to apply a list of bsfs to a packet
-rw-r--r--libavformat/avformat.h11
-rw-r--r--libavformat/utils.c49
2 files changed, 60 insertions, 0 deletions
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 32bed018ef..39aedb5c6d 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2764,6 +2764,17 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
int avformat_queue_attached_pictures(AVFormatContext *s);
+/**
+ * Apply a list of bitstream filters to a packet.
+ *
+ * @param codec AVCodecContext, usually from an AVStream
+ * @param pkt the packet to apply filters to
+ * @param bsfc a NULL-terminated list of filters to apply
+ * @return >=0 on success;
+ * AVERROR code on failure
+ */
+int av_apply_bitstream_filters(AVCodecContext *codec, AVPacket *pkt,
+ AVBitStreamFilterContext *bsfc);
/**
* @}
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;
+}