diff options
author | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2016-04-17 18:47:25 +0100 |
---|---|---|
committer | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2016-04-17 18:47:40 +0100 |
commit | af9cac1be1750ecc0e12c6788a3aeed1f1a778be (patch) | |
tree | 2e34226dbd4010774f6ffef448aab4b7d4f88544 /libavcodec/vp9_superframe_bsf.c | |
parent | 6d160afab2fa8d3bfb216fee96d3537ffc9e86e8 (diff) | |
parent | 33d18982fa03feb061c8f744a4f0a9175c1f63ab (diff) | |
download | ffmpeg-af9cac1be1750ecc0e12c6788a3aeed1f1a778be.tar.gz |
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.c | 120 |
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, }; |