History

vp8: Add hwaccel hooks

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

Mark Thompson committed 10 years ago

Commit 4e528201 parent 131a85a2 files · +157 −60Browse files

Unified · Split

2 files
  1. libavcodec/vp8.c +125 −60
  2. libavcodec/vp8.h +32 −0
libavcodec/vp8.c+125−60
@@ -64,16 +64,30 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref) · 63 unmodified lines
6464 if ((ret = ff_thread_get_buffer(s->avctx, &f->tf,
6565 ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
6666 return ret;
67− if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) {
68− ff_thread_release_buffer(s->avctx, &f->tf);
69− return AVERROR(ENOMEM);
67+ if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height)))
68+ goto fail;
69+ if (s->avctx->hwaccel) {
70+ const AVHWAccel *hwaccel = s->avctx->hwaccel;
71+ if (hwaccel->frame_priv_data_size) {
72+ f->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size);
73+ if (!f->hwaccel_priv_buf)
74+ goto fail;
75+ f->hwaccel_picture_private = f->hwaccel_priv_buf->data;
76+ }
7077 }
7178 return 0;
79+
80+fail:
81+ av_buffer_unref(&f->seg_map);
82+ ff_thread_release_buffer(s->avctx, &f->tf);
83+ return AVERROR(ENOMEM);
7284 }
7385
7486 static void vp8_release_frame(VP8Context *s, VP8Frame *f)
7587 {
7688 av_buffer_unref(&f->seg_map);
89+ av_buffer_unref(&f->hwaccel_priv_buf);
90+ f->hwaccel_picture_private = NULL;
7791 ff_thread_release_buffer(s->avctx, &f->tf);
7892 }
7993
@@ -91,6 +105,12 @@ static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src) · 11 unmodified lines
91105 vp8_release_frame(s, dst);
92106 return AVERROR(ENOMEM);
93107 }
108+ if (src->hwaccel_picture_private) {
109+ dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
110+ if (!dst->hwaccel_priv_buf)
111+ return AVERROR(ENOMEM);
112+ dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
113+ }
94114
95115 return 0;
96116 }
@@ -132,7 +152,7 @@ static VP8Frame *vp8_find_free_buffer(VP8Context *s) · 35 unmodified lines
132152 av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
133153 abort();
134154 }
135− if (frame->tf.f->data[0])
155+ if (frame->tf.f->buf[0])
136156 vp8_release_frame(s, frame);
137157
138158 return frame;
@@ -209,8 +229,9 @@ static void parse_segment_info(VP8Context *s) · 70 unmodified lines
209229 int i;
210230
211231 s->segmentation.update_map = vp8_rac_get(c);
232+ s->segmentation.update_feature_data = vp8_rac_get(c);
212233
213− if (vp8_rac_get(c)) { // update segment feature data
234+ if (s->segmentation.update_feature_data) {
214235 s->segmentation.absolute_vals = vp8_rac_get(c);
215236
216237 for (i = 0; i < 4; i++)
@@ -264,11 +285,14 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) · 47 unmodified lines
264285 int size = AV_RL24(sizes + 3 * i);
265286 if (buf_size - size < 0)
266287 return -1;
288+ s->coeff_partition_size[i] = size;
267289
268290 ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
269291 buf += size;
270292 buf_size -= size;
271293 }
294+
295+ s->coeff_partition_size[i] = buf_size;
272296 ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
273297
274298 return 0;
@@ -298,28 +322,28 @@ static void get_quants(VP8Context *s) · 23 unmodified lines
298322 VP56RangeCoder *c = &s->c;
299323 int i, base_qi;
300324
301− int yac_qi = vp8_rac_get_uint(c, 7);
302− int ydc_delta = vp8_rac_get_sint(c, 4);
303− int y2dc_delta = vp8_rac_get_sint(c, 4);
304− int y2ac_delta = vp8_rac_get_sint(c, 4);
305− int uvdc_delta = vp8_rac_get_sint(c, 4);
306− int uvac_delta = vp8_rac_get_sint(c, 4);
325+ s->quant.yac_qi = vp8_rac_get_uint(c, 7);
326+ s->quant.ydc_delta = vp8_rac_get_sint(c, 4);
327+ s->quant.y2dc_delta = vp8_rac_get_sint(c, 4);
328+ s->quant.y2ac_delta = vp8_rac_get_sint(c, 4);
329+ s->quant.uvdc_delta = vp8_rac_get_sint(c, 4);
330+ s->quant.uvac_delta = vp8_rac_get_sint(c, 4);
307331
308332 for (i = 0; i < 4; i++) {
309333 if (s->segmentation.enabled) {
310334 base_qi = s->segmentation.base_quant[i];
311335 if (!s->segmentation.absolute_vals)
312− base_qi += yac_qi;
336+ base_qi += s->quant.yac_qi;
313337 } else
314− base_qi = yac_qi;
338+ base_qi = s->quant.yac_qi;
315339
316− s->qmat[i].luma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + ydc_delta, 7)];
340+ s->qmat[i].luma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + s->quant.ydc_delta, 7)];
317341 s->qmat[i].luma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi, 7)];
318− s->qmat[i].luma_dc_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + y2dc_delta, 7)] * 2;
342+ s->qmat[i].luma_dc_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + s->quant.y2dc_delta, 7)] * 2;
319343 /* 101581>>16 is equivalent to 155/100 */
320− s->qmat[i].luma_dc_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + y2ac_delta, 7)] * 101581 >> 16;
321− s->qmat[i].chroma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + uvdc_delta, 7)];
322− s->qmat[i].chroma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + uvac_delta, 7)];
344+ s->qmat[i].luma_dc_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + s->quant.y2ac_delta, 7)] * 101581 >> 16;
345+ s->qmat[i].chroma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + s->quant.uvdc_delta, 7)];
346+ s->qmat[i].chroma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + s->quant.uvac_delta, 7)];
323347
324348 s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8);
325349 s->qmat[i].chroma_qmul[0] = FFMIN(s->qmat[i].chroma_qmul[0], 132);
@@ -637,6 +661,8 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si · 311 unmodified lines
637661 buf += 3;
638662 buf_size -= 3;
639663
664+ s->header_partition_size = header_size;
665+
640666 if (s->profile > 3)
641667 av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile);
642668
@@ -700,9 +726,11 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si · 57 unmodified lines
700726 s->filter.level = vp8_rac_get_uint(c, 6);
701727 s->filter.sharpness = vp8_rac_get_uint(c, 3);
702728
703− if ((s->lf_delta.enabled = vp8_rac_get(c)))
704− if (vp8_rac_get(c))
729+ if ((s->lf_delta.enabled = vp8_rac_get(c))) {
730+ s->lf_delta.update = vp8_rac_get(c);
731+ if (s->lf_delta.update)
705732 update_lf_deltas(s);
733+ }
706734
707735 if (setup_partitions(s, buf, buf_size)) {
708736 av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n");
@@ -741,6 +769,13 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si · 32 unmodified lines
741769 vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP8_MVC_SIZE);
742770 }
743771
772+ // Record the entropy coder state here so that hwaccels can use it.
773+ s->c.code_word = vp56_rac_renorm(&s->c);
774+ s->coder_state_at_header_end.input = s->c.buffer - (-s->c.bits / 8);
775+ s->coder_state_at_header_end.range = s->c.high;
776+ s->coder_state_at_header_end.value = s->c.code_word >> 16;
777+ s->coder_state_at_header_end.bit_count = -s->c.bits % 8;
778+
744779 return 0;
745780 }
746781
@@ -2462,7 +2497,6 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, · 1715 unmodified lines
24622497 return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP8);
24632498 }
24642499
2465−
24662500 static av_always_inline
24672501 int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
24682502 AVPacket *avpkt, int is_vp7)
@@ -2480,6 +2514,20 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, · 11 unmodified lines
24802514 if (ret < 0)
24812515 goto err;
24822516
2517+ if (!is_vp7 && s->pix_fmt == AV_PIX_FMT_NONE) {
2518+ enum AVPixelFormat pix_fmts[] = {
2519+ AV_PIX_FMT_YUV420P,
2520+ AV_PIX_FMT_NONE,
2521+ };
2522+
2523+ s->pix_fmt = ff_get_format(s->avctx, pix_fmts);
2524+ if (s->pix_fmt < 0) {
2525+ ret = AVERROR(EINVAL);
2526+ goto err;
2527+ }
2528+ avctx->pix_fmt = s->pix_fmt;
2529+ }
2530+
24832531 prev_frame = s->framep[VP56_FRAME_CURRENT];
24842532
24852533 referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT ||
@@ -2555,51 +2603,67 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, · 69 unmodified lines
25552603
25562604 ff_thread_finish_setup(avctx);
25572605
2558− s->linesize = curframe->tf.f->linesize[0];
2559− s->uvlinesize = curframe->tf.f->linesize[1];
2606+ if (avctx->hwaccel) {
2607+ ret = avctx->hwaccel->start_frame(avctx, avpkt->data, avpkt->size);
2608+ if (ret < 0)
2609+ goto err;
25602610
2561− memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz));
2562− /* Zero macroblock structures for top/top-left prediction
2563− * from outside the frame. */
2564− if (!s->mb_layout)
2565− memset(s->macroblocks + s->mb_height * 2 - 1, 0,
2566− (s->mb_width + 1) * sizeof(*s->macroblocks));
2567− if (!s->mb_layout && s->keyframe)
2568− memset(s->intra4x4_pred_mode_top, DC_PRED, s->mb_width * 4);
2611+ ret = avctx->hwaccel->decode_slice(avctx, avpkt->data, avpkt->size);
2612+ if (ret < 0)
2613+ goto err;
25692614
2570− memset(s->ref_count, 0, sizeof(s->ref_count));
2615+ ret = avctx->hwaccel->end_frame(avctx);
2616+ if (ret < 0)
2617+ goto err;
25712618
2572− if (s->mb_layout == 1) {
2573− // Make sure the previous frame has read its segmentation map,
2574− // if we re-use the same map.
2575− if (prev_frame && s->segmentation.enabled &&
2576− !s->segmentation.update_map)
2577− ff_thread_await_progress(&prev_frame->tf, 1, 0);
2578− if (is_vp7)
2579− vp7_decode_mv_mb_modes(avctx, curframe, prev_frame);
2619+ } else {
2620+ s->linesize = curframe->tf.f->linesize[0];
2621+ s->uvlinesize = curframe->tf.f->linesize[1];
2622+
2623+ memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz));
2624+ /* Zero macroblock structures for top/top-left prediction
2625+ * from outside the frame. */
2626+ if (!s->mb_layout)
2627+ memset(s->macroblocks + s->mb_height * 2 - 1, 0,
2628+ (s->mb_width + 1) * sizeof(*s->macroblocks));
2629+ if (!s->mb_layout && s->keyframe)
2630+ memset(s->intra4x4_pred_mode_top, DC_PRED, s->mb_width * 4);
2631+
2632+ memset(s->ref_count, 0, sizeof(s->ref_count));
2633+
2634+ if (s->mb_layout == 1) {
2635+ // Make sure the previous frame has read its segmentation map,
2636+ // if we re-use the same map.
2637+ if (prev_frame && s->segmentation.enabled &&
2638+ !s->segmentation.update_map)
2639+ ff_thread_await_progress(&prev_frame->tf, 1, 0);
2640+ if (is_vp7)
2641+ vp7_decode_mv_mb_modes(avctx, curframe, prev_frame);
2642+ else
2643+ vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
2644+ }
2645+
2646+ if (avctx->active_thread_type == FF_THREAD_FRAME)
2647+ num_jobs = 1;
25802648 else
2581− vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
2582− }
2649+ num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count);
2650+ s->num_jobs = num_jobs;
2651+ s->curframe = curframe;
2652+ s->prev_frame = prev_frame;
2653+ s->mv_min.y = -MARGIN;
2654+ s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
2655+ for (i = 0; i < MAX_THREADS; i++) {
2656+ s->thread_data[i].thread_mb_pos = 0;
2657+ s->thread_data[i].wait_mb_pos = INT_MAX;
2658+ }
25832659
2584− if (avctx->active_thread_type == FF_THREAD_FRAME)
2585− num_jobs = 1;
2586− else
2587− num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count);
2588− s->num_jobs = num_jobs;
2589− s->curframe = curframe;
2590− s->prev_frame = prev_frame;
2591− s->mv_min.y = -MARGIN;
2592− s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
2593− for (i = 0; i < MAX_THREADS; i++) {
2594− s->thread_data[i].thread_mb_pos = 0;
2595− s->thread_data[i].wait_mb_pos = INT_MAX;
2660+ if (is_vp7)
2661+ avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL,
2662+ num_jobs);
2663+ else
2664+ avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL,
2665+ num_jobs);
25962666 }
2597− if (is_vp7)
2598− avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL,
2599− num_jobs);
2600− else
2601− avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL,
2602− num_jobs);
26032667
26042668 ff_thread_report_progress(&curframe->tf, INT_MAX, 0);
26052669 memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
@@ -2666,6 +2730,7 @@ int vp78_decode_init(AVCodecContext *avctx, int is_vp7) · 60 unmodified lines
26662730 int ret;
26672731
26682732 s->avctx = avctx;
2733+ s->pix_fmt = AV_PIX_FMT_NONE;
26692734 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
26702735 avctx->internal->allocate_progress = 1;
26712736
libavcodec/vp8.h+32−0
@@ -130,12 +130,17 @@ typedef struct VP8ThreadData { · 129 unmodified lines
130130 typedef struct VP8Frame {
131131 ThreadFrame tf;
132132 AVBufferRef *seg_map;
133+
134+ AVBufferRef *hwaccel_priv_buf;
135+ void *hwaccel_picture_private;
133136 } VP8Frame;
134137
135138 #define MAX_THREADS 8
136139 typedef struct VP8Context {
137140 VP8ThreadData *thread_data;
138141 AVCodecContext *avctx;
142+ enum AVPixelFormat pix_fmt;
143+
139144 VP8Frame *framep[4];
140145 VP8Frame *next_framep[4];
141146 VP8Frame *curframe;
@@ -165,6 +170,7 @@ typedef struct VP8Context { · 23 unmodified lines
165170 uint8_t enabled;
166171 uint8_t absolute_vals;
167172 uint8_t update_map;
173+ uint8_t update_feature_data;
168174 int8_t base_quant[4];
169175 int8_t filter_level[4]; ///< base loop filter level
170176 } segmentation;
@@ -192,8 +198,19 @@ typedef struct VP8Context { · 21 unmodified lines
192198 int16_t chroma_qmul[2];
193199 } qmat[4];
194200
201+ // Raw quantisation values, which may be needed by hwaccel decode.
202+ struct {
203+ int yac_qi;
204+ int ydc_delta;
205+ int y2dc_delta;
206+ int y2ac_delta;
207+ int uvdc_delta;
208+ int uvac_delta;
209+ } quant;
210+
195211 struct {
196212 uint8_t enabled; ///< whether each mb can have a different strength based on mode/ref
213+ uint8_t update;
197214
198215 /**
199216 * filter strength adjustment for the following macroblock modes:
@@ -221,6 +238,20 @@ typedef struct VP8Context { · 21 unmodified lines
221238
222239 VP56RangeCoder c; ///< header context, includes mb modes and motion vectors
223240
241+ /* This contains the entropy coder state at the end of the header
242+ * block, in the form specified by the standard. For use by
243+ * hwaccels, so that a hardware decoder has the information to
244+ * start decoding at the macroblock layer.
245+ */
246+ struct {
247+ const uint8_t *input;
248+ uint32_t range;
249+ uint32_t value;
250+ int bit_count;
251+ } coder_state_at_header_end;
252+
253+ int header_partition_size;
254+
224255 /**
225256 * These are all of the updatable probabilities for binary decisions.
226257 * They are only implicitly reset on keyframes, making it quite likely
@@ -258,6 +289,7 @@ typedef struct VP8Context { · 31 unmodified lines
258289 */
259290 int num_coeff_partitions;
260291 VP56RangeCoder coeff_partition[8];
292+ int coeff_partition_size[8];
261293 VideoDSPContext vdsp;
262294 VP8DSPContext vp8dsp;
263295 H264PredContext hpc;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t