[FFmpeg-cvslog] vp8: Add hwaccel hooks

2017-11-26 Thread Mark Thompson
ffmpeg | branch: master | Mark Thompson  | Sat Nov 18 17:55:18 
2017 +| [9f00fa536938130e3c7ad2640a61795770d419a1] | committer: Mark 
Thompson

vp8: Add hwaccel hooks

Also adds some extra fields to the main context structure that may
be needed by a hwaccel decoder.

The current behaviour of the WebP decoder is maintained by adding an
additional field to the VP8 decoder private context to indicate that
it is actually being used as WebP (no hwaccel is supported for that
case).

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9f00fa536938130e3c7ad2640a61795770d419a1
---

 libavcodec/vp8.c  | 206 --
 libavcodec/vp8.h  |  33 +
 libavcodec/webp.c |   1 +
 3 files changed, 172 insertions(+), 68 deletions(-)

diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 7841a9d964..31cd6a0d81 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -27,6 +27,7 @@
 #include "libavutil/imgutils.h"
 
 #include "avcodec.h"
+#include "hwaccel.h"
 #include "internal.h"
 #include "mathops.h"
 #include "rectangle.h"
@@ -72,16 +73,30 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int 
ref)
 if ((ret = ff_thread_get_buffer(s->avctx, >tf,
 ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
 return ret;
-if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) {
-ff_thread_release_buffer(s->avctx, >tf);
-return AVERROR(ENOMEM);
+if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height)))
+goto fail;
+if (s->avctx->hwaccel) {
+const AVHWAccel *hwaccel = s->avctx->hwaccel;
+if (hwaccel->frame_priv_data_size) {
+f->hwaccel_priv_buf = 
av_buffer_allocz(hwaccel->frame_priv_data_size);
+if (!f->hwaccel_priv_buf)
+goto fail;
+f->hwaccel_picture_private = f->hwaccel_priv_buf->data;
+}
 }
 return 0;
+
+fail:
+av_buffer_unref(>seg_map);
+ff_thread_release_buffer(s->avctx, >tf);
+return AVERROR(ENOMEM);
 }
 
 static void vp8_release_frame(VP8Context *s, VP8Frame *f)
 {
 av_buffer_unref(>seg_map);
+av_buffer_unref(>hwaccel_priv_buf);
+f->hwaccel_picture_private = NULL;
 ff_thread_release_buffer(s->avctx, >tf);
 }
 
@@ -99,6 +114,12 @@ static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, 
VP8Frame *src)
 vp8_release_frame(s, dst);
 return AVERROR(ENOMEM);
 }
+if (src->hwaccel_picture_private) {
+dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
+if (!dst->hwaccel_priv_buf)
+return AVERROR(ENOMEM);
+dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
+}
 
 return 0;
 }
@@ -140,7 +161,7 @@ static VP8Frame *vp8_find_free_buffer(VP8Context *s)
 av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
 abort();
 }
-if (frame->tf.f->data[0])
+if (frame->tf.f->buf[0])
 vp8_release_frame(s, frame);
 
 return frame;
@@ -218,8 +239,9 @@ static void parse_segment_info(VP8Context *s)
 int i;
 
 s->segmentation.update_map = vp8_rac_get(c);
+s->segmentation.update_feature_data = vp8_rac_get(c);
 
-if (vp8_rac_get(c)) { // update segment feature data
+if (s->segmentation.update_feature_data) {
 s->segmentation.absolute_vals = vp8_rac_get(c);
 
 for (i = 0; i < 4; i++)
@@ -274,6 +296,7 @@ static int setup_partitions(VP8Context *s, const uint8_t 
*buf, int buf_size)
 int size = AV_RL24(sizes + 3 * i);
 if (buf_size - size < 0)
 return -1;
+s->coeff_partition_size[i] = size;
 
 ret = ff_vp56_init_range_decoder(>coeff_partition[i], buf, size);
 if (ret < 0)
@@ -281,7 +304,11 @@ static int setup_partitions(VP8Context *s, const uint8_t 
*buf, int buf_size)
 buf  += size;
 buf_size -= size;
 }
-return ff_vp56_init_range_decoder(>coeff_partition[i], buf, buf_size);
+
+s->coeff_partition_size[i] = buf_size;
+ff_vp56_init_range_decoder(>coeff_partition[i], buf, buf_size);
+
+return 0;
 }
 
 static void vp7_get_quants(VP8Context *s)
@@ -308,28 +335,28 @@ static void vp8_get_quants(VP8Context *s)
 VP56RangeCoder *c = >c;
 int i, base_qi;
 
-int yac_qi = vp8_rac_get_uint(c, 7);
-int ydc_delta  = vp8_rac_get_sint(c, 4);
-int y2dc_delta = vp8_rac_get_sint(c, 4);
-int y2ac_delta = vp8_rac_get_sint(c, 4);
-int uvdc_delta = vp8_rac_get_sint(c, 4);
-int uvac_delta = vp8_rac_get_sint(c, 4);
+s->quant.yac_qi = vp8_rac_get_uint(c, 7);
+s->quant.ydc_delta  = vp8_rac_get_sint(c, 4);
+s->quant.y2dc_delta = vp8_rac_get_sint(c, 4);
+s->quant.y2ac_delta = vp8_rac_get_sint(c, 4);
+s->quant.uvdc_delta = vp8_rac_get_sint(c, 4);
+s->quant.uvac_delta = vp8_rac_get_sint(c, 4);
 
 for (i = 0; i < 4; i++) {
 if (s->segmentation.enabled) {
 base_qi = 

[FFmpeg-cvslog] vp8: Add hwaccel hooks

2017-03-20 Thread Mark Thompson
ffmpeg | branch: master | Mark Thompson  | Sun Sep  4 13:26:37 
2016 +0100| [4e528206bc4d968706401206cf54471739250ec7] | committer: Mark 
Thompson

vp8: Add hwaccel hooks

Also adds some extra fields to the main context structure that may
be needed by a hwaccel decoder.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4e528206bc4d968706401206cf54471739250ec7
---

 libavcodec/vp8.c | 185 +--
 libavcodec/vp8.h |  32 ++
 2 files changed, 157 insertions(+), 60 deletions(-)

diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 546124c..ced4979 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -64,16 +64,30 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int 
ref)
 if ((ret = ff_thread_get_buffer(s->avctx, >tf,
 ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
 return ret;
-if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) {
-ff_thread_release_buffer(s->avctx, >tf);
-return AVERROR(ENOMEM);
+if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height)))
+goto fail;
+if (s->avctx->hwaccel) {
+const AVHWAccel *hwaccel = s->avctx->hwaccel;
+if (hwaccel->frame_priv_data_size) {
+f->hwaccel_priv_buf = 
av_buffer_allocz(hwaccel->frame_priv_data_size);
+if (!f->hwaccel_priv_buf)
+goto fail;
+f->hwaccel_picture_private = f->hwaccel_priv_buf->data;
+}
 }
 return 0;
+
+fail:
+av_buffer_unref(>seg_map);
+ff_thread_release_buffer(s->avctx, >tf);
+return AVERROR(ENOMEM);
 }
 
 static void vp8_release_frame(VP8Context *s, VP8Frame *f)
 {
 av_buffer_unref(>seg_map);
+av_buffer_unref(>hwaccel_priv_buf);
+f->hwaccel_picture_private = NULL;
 ff_thread_release_buffer(s->avctx, >tf);
 }
 
@@ -91,6 +105,12 @@ static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, 
VP8Frame *src)
 vp8_release_frame(s, dst);
 return AVERROR(ENOMEM);
 }
+if (src->hwaccel_picture_private) {
+dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
+if (!dst->hwaccel_priv_buf)
+return AVERROR(ENOMEM);
+dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
+}
 
 return 0;
 }
@@ -132,7 +152,7 @@ static VP8Frame *vp8_find_free_buffer(VP8Context *s)
 av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
 abort();
 }
-if (frame->tf.f->data[0])
+if (frame->tf.f->buf[0])
 vp8_release_frame(s, frame);
 
 return frame;
@@ -209,8 +229,9 @@ static void parse_segment_info(VP8Context *s)
 int i;
 
 s->segmentation.update_map = vp8_rac_get(c);
+s->segmentation.update_feature_data = vp8_rac_get(c);
 
-if (vp8_rac_get(c)) { // update segment feature data
+if (s->segmentation.update_feature_data) {
 s->segmentation.absolute_vals = vp8_rac_get(c);
 
 for (i = 0; i < 4; i++)
@@ -264,11 +285,14 @@ static int setup_partitions(VP8Context *s, const uint8_t 
*buf, int buf_size)
 int size = AV_RL24(sizes + 3 * i);
 if (buf_size - size < 0)
 return -1;
+s->coeff_partition_size[i] = size;
 
 ff_vp56_init_range_decoder(>coeff_partition[i], buf, size);
 buf  += size;
 buf_size -= size;
 }
+
+s->coeff_partition_size[i] = buf_size;
 ff_vp56_init_range_decoder(>coeff_partition[i], buf, buf_size);
 
 return 0;
@@ -298,28 +322,28 @@ static void get_quants(VP8Context *s)
 VP56RangeCoder *c = >c;
 int i, base_qi;
 
-int yac_qi = vp8_rac_get_uint(c, 7);
-int ydc_delta  = vp8_rac_get_sint(c, 4);
-int y2dc_delta = vp8_rac_get_sint(c, 4);
-int y2ac_delta = vp8_rac_get_sint(c, 4);
-int uvdc_delta = vp8_rac_get_sint(c, 4);
-int uvac_delta = vp8_rac_get_sint(c, 4);
+s->quant.yac_qi = vp8_rac_get_uint(c, 7);
+s->quant.ydc_delta  = vp8_rac_get_sint(c, 4);
+s->quant.y2dc_delta = vp8_rac_get_sint(c, 4);
+s->quant.y2ac_delta = vp8_rac_get_sint(c, 4);
+s->quant.uvdc_delta = vp8_rac_get_sint(c, 4);
+s->quant.uvac_delta = vp8_rac_get_sint(c, 4);
 
 for (i = 0; i < 4; i++) {
 if (s->segmentation.enabled) {
 base_qi = s->segmentation.base_quant[i];
 if (!s->segmentation.absolute_vals)
-base_qi += yac_qi;
+base_qi += s->quant.yac_qi;
 } else
-base_qi = yac_qi;
+base_qi = s->quant.yac_qi;
 
-s->qmat[i].luma_qmul[0]= vp8_dc_qlookup[av_clip_uintp2(base_qi + 
ydc_delta,  7)];
+s->qmat[i].luma_qmul[0]= vp8_dc_qlookup[av_clip_uintp2(base_qi + 
s->quant.ydc_delta,  7)];
 s->qmat[i].luma_qmul[1]= vp8_ac_qlookup[av_clip_uintp2(base_qi,
  7)];
-s->qmat[i].luma_dc_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + 
y2dc_delta, 7)] * 2;
+