summaryrefslogtreecommitdiff
path: root/libavcodec/vp9_superframe_bsf.c
diff options
context:
space:
mode:
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>2016-04-17 18:47:25 +0100
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>2016-04-17 18:47:40 +0100
commitaf9cac1be1750ecc0e12c6788a3aeed1f1a778be (patch)
tree2e34226dbd4010774f6ffef448aab4b7d4f88544 /libavcodec/vp9_superframe_bsf.c
parent6d160afab2fa8d3bfb216fee96d3537ffc9e86e8 (diff)
parent33d18982fa03feb061c8f744a4f0a9175c1f63ab (diff)
Merge commit '33d18982fa03feb061c8f744a4f0a9175c1f63ab'
* commit '33d18982fa03feb061c8f744a4f0a9175c1f63ab': lavc: add a new bitstream filtering API Conversions-by: Hendrik Leppkes <h.leppkes@gmail.com> Conversions-by: Derek Buitenguis <derek.buitenhuis@gmail.com> Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
Diffstat (limited to 'libavcodec/vp9_superframe_bsf.c')
-rw-r--r--libavcodec/vp9_superframe_bsf.c120
1 files changed, 68 insertions, 52 deletions
diff --git a/libavcodec/vp9_superframe_bsf.c b/libavcodec/vp9_superframe_bsf.c
index d4a61eea04..b686adbe16 100644
--- a/libavcodec/vp9_superframe_bsf.c
+++ b/libavcodec/vp9_superframe_bsf.c
@@ -21,6 +21,7 @@
#include "libavutil/avassert.h"
#include "avcodec.h"
+#include "bsf.h"
#include "get_bits.h"
#define MAX_CACHE 8
@@ -50,20 +51,20 @@ static void stats(const struct CachedBuf *in, int n_in,
*_sum = sum;
}
-static int merge_superframe(const struct CachedBuf *in, int n_in,
- uint8_t **poutbuf, int *poutbuf_size)
+static int merge_superframe(const struct CachedBuf *in, int n_in, AVPacket *out)
{
unsigned max, sum, mag, marker, n, sz;
uint8_t *ptr;
+ int res;
stats(in, n_in, &max, &sum);
mag = av_log2(max) >> 3;
marker = 0xC0 + (mag << 3) + (n_in - 1);
- sz = *poutbuf_size = sum + 2 + (mag + 1) * n_in;
- ptr = *poutbuf = av_malloc(sz);
- if (!ptr)
- return AVERROR(ENOMEM);
-
+ sz = sum + 2 + (mag + 1) * n_in;
+ res = av_new_packet(out, sz);
+ if (res < 0)
+ return res;
+ ptr = out->data;
for (n = 0; n < n_in; n++) {
memcpy(ptr, in[n].data, in[n].size);
ptr += in[n].size;
@@ -92,31 +93,32 @@ static int merge_superframe(const struct CachedBuf *in, int n_in,
break;
}
*ptr++ = marker;
- av_assert0(ptr == &(*poutbuf)[*poutbuf_size]);
+ av_assert0(ptr == &out->data[out->size]);
return 0;
}
-static int vp9_superframe_filter(AVBitStreamFilterContext *bsfc,
- AVCodecContext *avctx, const char *args,
- uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size,
- int keyframe)
+static int vp9_superframe_filter(AVBSFContext *ctx, AVPacket *out)
{
GetBitContext gb;
- VP9BSFContext *ctx = bsfc->priv_data;
+ VP9BSFContext *s = ctx->priv_data;
+ AVPacket *in;
int res, invisible, profile, marker, uses_superframe_syntax = 0, n;
- marker = buf[buf_size - 1];
+ res = ff_bsf_get_packet(ctx, &in);
+ if (res < 0)
+ return res;
+
+ marker = in->data[in->size - 1];
if ((marker & 0xe0) == 0xc0) {
int nbytes = 1 + ((marker >> 3) & 0x3);
int n_frames = 1 + (marker & 0x7), idx_sz = 2 + n_frames * nbytes;
- uses_superframe_syntax = buf_size >= idx_sz && buf[buf_size - idx_sz] == marker;
+ uses_superframe_syntax = in->size >= idx_sz && in->data[in->size - idx_sz] == marker;
}
- if ((res = init_get_bits8(&gb, buf, buf_size)) < 0)
- return res;
+ if ((res = init_get_bits8(&gb, in->data, in->size)) < 0)
+ goto done;
get_bits(&gb, 2); // frame marker
profile = get_bits1(&gb);
@@ -130,60 +132,74 @@ static int vp9_superframe_filter(AVBitStreamFilterContext *bsfc,
invisible = !get_bits1(&gb);
}
- if (uses_superframe_syntax && ctx->n_cache > 0) {
- av_log(avctx, AV_LOG_ERROR,
+ if (uses_superframe_syntax && s->n_cache > 0) {
+ av_log(ctx, AV_LOG_ERROR,
"Mixing of superframe syntax and naked VP9 frames not supported");
- return AVERROR_INVALIDDATA;
- } else if ((!invisible || uses_superframe_syntax) && !ctx->n_cache) {
+ res = AVERROR_INVALIDDATA;
+ goto done;
+ } else if ((!invisible || uses_superframe_syntax) && !s->n_cache) {
// passthrough
- *poutbuf = (uint8_t *) buf;
- *poutbuf_size = buf_size;
- return 0;
- } else if (ctx->n_cache + 1 >= MAX_CACHE) {
- av_log(avctx, AV_LOG_ERROR,
+ av_packet_move_ref(out, in);
+ goto done;
+ } else if (s->n_cache + 1 >= MAX_CACHE) {
+ av_log(ctx, AV_LOG_ERROR,
"Too many invisible frames");
- return AVERROR_INVALIDDATA;
+ res = AVERROR_INVALIDDATA;
+ goto done;
}
- ctx->cache[ctx->n_cache].size = buf_size;
+ s->cache[s->n_cache].size = in->size;
if (invisible && !uses_superframe_syntax) {
- ctx->cache[ctx->n_cache].data = av_malloc(buf_size);
- if (!ctx->cache[ctx->n_cache].data)
- return AVERROR(ENOMEM);
- memcpy(ctx->cache[ctx->n_cache++].data, buf, buf_size);
- *poutbuf = NULL;
- *poutbuf_size = 0;
- return 0;
+ s->cache[s->n_cache].data = av_malloc(in->size);
+ if (!s->cache[s->n_cache].data) {
+ res = AVERROR(ENOMEM);
+ goto done;
+ }
+ memcpy(s->cache[s->n_cache++].data, in->data, in->size);
+ res = AVERROR(EAGAIN);
+ goto done;
}
- av_assert0(ctx->n_cache > 0);
+ av_assert0(s->n_cache > 0);
- ctx->cache[ctx->n_cache].data = (uint8_t *) buf;
+ s->cache[s->n_cache].data = in->data;
// build superframe
- if ((res = merge_superframe(ctx->cache, ctx->n_cache + 1,
- poutbuf, poutbuf_size)) < 0)
- return res;
-
- for (n = 0; n < ctx->n_cache; n++)
- av_freep(&ctx->cache[n].data);
- ctx->n_cache = 0;
-
- return 0;
+ if ((res = merge_superframe(s->cache, s->n_cache + 1, out)) < 0)
+ goto done;
+
+ for (n = 0; n < s->n_cache; n++)
+ av_freep(&s->cache[n].data);
+ s->n_cache = 0;
+
+ res = av_packet_copy_props(out, in);
+ if (res < 0)
+ goto done;
+
+done:
+ if (res < 0)
+ av_packet_unref(out);
+ av_packet_free(&in);
+ return res;
}
-static void vp9_superframe_close(AVBitStreamFilterContext *bsfc)
+static void vp9_superframe_close(AVBSFContext *ctx)
{
- VP9BSFContext *ctx = bsfc->priv_data;
+ VP9BSFContext *s = ctx->priv_data;
int n;
// free cached data
- for (n = 0; n < ctx->n_cache; n++)
- av_freep(&ctx->cache[n].data);
+ for (n = 0; n < s->n_cache; n++)
+ av_freep(&s->cache[n].data);
}
-AVBitStreamFilter ff_vp9_superframe_bsf = {
+static const enum AVCodecID codec_ids[] = {
+ AV_CODEC_ID_VP9, AV_CODEC_ID_NONE,
+};
+
+const AVBitStreamFilter ff_vp9_superframe_bsf = {
.name = "vp9_superframe",
.priv_data_size = sizeof(VP9BSFContext),
.filter = vp9_superframe_filter,
.close = vp9_superframe_close,
+ .codec_ids = codec_ids,
};