Also adds some extra fields to the main context structure that may be needed by a hwaccel decoder.
Unified · Split
| @@ -64,16 +64,30 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref) · 63 unmodified lines | ||
| 64 | 64 | if ((ret = ff_thread_get_buffer(s->avctx, &f->tf, |
| 65 | 65 | ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) |
| 66 | 66 | 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 | + } | |
| 70 | 77 | } |
| 71 | 78 | 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); | |
| 72 | 84 | } |
| 73 | 85 | |
| 74 | 86 | static void vp8_release_frame(VP8Context *s, VP8Frame *f) |
| 75 | 87 | { |
| 76 | 88 | av_buffer_unref(&f->seg_map); |
| 89 | + av_buffer_unref(&f->hwaccel_priv_buf); | |
| 90 | + f->hwaccel_picture_private = NULL; | |
| 77 | 91 | ff_thread_release_buffer(s->avctx, &f->tf); |
| 78 | 92 | } |
| 79 | 93 | |
| @@ -91,6 +105,12 @@ static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src) · 11 unmodified lines | ||
| 91 | 105 | vp8_release_frame(s, dst); |
| 92 | 106 | return AVERROR(ENOMEM); |
| 93 | 107 | } |
| 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 | + } | |
| 94 | 114 | |
| 95 | 115 | return 0; |
| 96 | 116 | } |
| @@ -132,7 +152,7 @@ static VP8Frame *vp8_find_free_buffer(VP8Context *s) · 35 unmodified lines | ||
| 132 | 152 | av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n"); |
| 133 | 153 | abort(); |
| 134 | 154 | } |
| 135 | − if (frame->tf.f->data[0]) | |
| 155 | + if (frame->tf.f->buf[0]) | |
| 136 | 156 | vp8_release_frame(s, frame); |
| 137 | 157 | |
| 138 | 158 | return frame; |
| @@ -209,8 +229,9 @@ static void parse_segment_info(VP8Context *s) · 70 unmodified lines | ||
| 209 | 229 | int i; |
| 210 | 230 | |
| 211 | 231 | s->segmentation.update_map = vp8_rac_get(c); |
| 232 | + s->segmentation.update_feature_data = vp8_rac_get(c); | |
| 212 | 233 | |
| 213 | − if (vp8_rac_get(c)) { // update segment feature data | |
| 234 | + if (s->segmentation.update_feature_data) { | |
| 214 | 235 | s->segmentation.absolute_vals = vp8_rac_get(c); |
| 215 | 236 | |
| 216 | 237 | 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 | ||
| 264 | 285 | int size = AV_RL24(sizes + 3 * i); |
| 265 | 286 | if (buf_size - size < 0) |
| 266 | 287 | return -1; |
| 288 | + s->coeff_partition_size[i] = size; | |
| 267 | 289 | |
| 268 | 290 | ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); |
| 269 | 291 | buf += size; |
| 270 | 292 | buf_size -= size; |
| 271 | 293 | } |
| 294 | + | |
| 295 | + s->coeff_partition_size[i] = buf_size; | |
| 272 | 296 | ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); |
| 273 | 297 | |
| 274 | 298 | return 0; |
| @@ -298,28 +322,28 @@ static void get_quants(VP8Context *s) · 23 unmodified lines | ||
| 298 | 322 | VP56RangeCoder *c = &s->c; |
| 299 | 323 | int i, base_qi; |
| 300 | 324 | |
| 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); | |
| 307 | 331 | |
| 308 | 332 | for (i = 0; i < 4; i++) { |
| 309 | 333 | if (s->segmentation.enabled) { |
| 310 | 334 | base_qi = s->segmentation.base_quant[i]; |
| 311 | 335 | if (!s->segmentation.absolute_vals) |
| 312 | − base_qi += yac_qi; | |
| 336 | + base_qi += s->quant.yac_qi; | |
| 313 | 337 | } else |
| 314 | − base_qi = yac_qi; | |
| 338 | + base_qi = s->quant.yac_qi; | |
| 315 | 339 | |
| 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)]; | |
| 317 | 341 | 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; | |
| 319 | 343 | /* 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)]; | |
| 323 | 347 | |
| 324 | 348 | s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8); |
| 325 | 349 | 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 | ||
| 637 | 661 | buf += 3; |
| 638 | 662 | buf_size -= 3; |
| 639 | 663 | |
| 664 | + s->header_partition_size = header_size; | |
| 665 | + | |
| 640 | 666 | if (s->profile > 3) |
| 641 | 667 | av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile); |
| 642 | 668 | |
| @@ -700,9 +726,11 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si · 57 unmodified lines | ||
| 700 | 726 | s->filter.level = vp8_rac_get_uint(c, 6); |
| 701 | 727 | s->filter.sharpness = vp8_rac_get_uint(c, 3); |
| 702 | 728 | |
| 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) | |
| 705 | 732 | update_lf_deltas(s); |
| 733 | + } | |
| 706 | 734 | |
| 707 | 735 | if (setup_partitions(s, buf, buf_size)) { |
| 708 | 736 | 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 | ||
| 741 | 769 | vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP8_MVC_SIZE); |
| 742 | 770 | } |
| 743 | 771 | |
| 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 | + | |
| 744 | 779 | return 0; |
| 745 | 780 | } |
| 746 | 781 | |
| @@ -2462,7 +2497,6 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, · 1715 unmodified lines | ||
| 2462 | 2497 | return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP8); |
| 2463 | 2498 | } |
| 2464 | 2499 | |
| 2465 | − | |
| 2466 | 2500 | static av_always_inline |
| 2467 | 2501 | int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
| 2468 | 2502 | AVPacket *avpkt, int is_vp7) |
| @@ -2480,6 +2514,20 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, · 11 unmodified lines | ||
| 2480 | 2514 | if (ret < 0) |
| 2481 | 2515 | goto err; |
| 2482 | 2516 | |
| 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 | + | |
| 2483 | 2531 | prev_frame = s->framep[VP56_FRAME_CURRENT]; |
| 2484 | 2532 | |
| 2485 | 2533 | 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 | ||
| 2555 | 2603 | |
| 2556 | 2604 | ff_thread_finish_setup(avctx); |
| 2557 | 2605 | |
| 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; | |
| 2560 | 2610 | |
| 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; | |
| 2569 | 2614 | |
| 2570 | − memset(s->ref_count, 0, sizeof(s->ref_count)); | |
| 2615 | + ret = avctx->hwaccel->end_frame(avctx); | |
| 2616 | + if (ret < 0) | |
| 2617 | + goto err; | |
| 2571 | 2618 | |
| 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; | |
| 2580 | 2648 | 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 | + } | |
| 2583 | 2659 | |
| 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); | |
| 2596 | 2666 | } |
| 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); | |
| 2603 | 2667 | |
| 2604 | 2668 | ff_thread_report_progress(&curframe->tf, INT_MAX, 0); |
| 2605 | 2669 | 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 | ||
| 2666 | 2730 | int ret; |
| 2667 | 2731 | |
| 2668 | 2732 | s->avctx = avctx; |
| 2733 | + s->pix_fmt = AV_PIX_FMT_NONE; | |
| 2669 | 2734 | avctx->pix_fmt = AV_PIX_FMT_YUV420P; |
| 2670 | 2735 | avctx->internal->allocate_progress = 1; |
| 2671 | 2736 | |
| @@ -130,12 +130,17 @@ typedef struct VP8ThreadData { · 129 unmodified lines | ||
| 130 | 130 | typedef struct VP8Frame { |
| 131 | 131 | ThreadFrame tf; |
| 132 | 132 | AVBufferRef *seg_map; |
| 133 | + | |
| 134 | + AVBufferRef *hwaccel_priv_buf; | |
| 135 | + void *hwaccel_picture_private; | |
| 133 | 136 | } VP8Frame; |
| 134 | 137 | |
| 135 | 138 | #define MAX_THREADS 8 |
| 136 | 139 | typedef struct VP8Context { |
| 137 | 140 | VP8ThreadData *thread_data; |
| 138 | 141 | AVCodecContext *avctx; |
| 142 | + enum AVPixelFormat pix_fmt; | |
| 143 | + | |
| 139 | 144 | VP8Frame *framep[4]; |
| 140 | 145 | VP8Frame *next_framep[4]; |
| 141 | 146 | VP8Frame *curframe; |
| @@ -165,6 +170,7 @@ typedef struct VP8Context { · 23 unmodified lines | ||
| 165 | 170 | uint8_t enabled; |
| 166 | 171 | uint8_t absolute_vals; |
| 167 | 172 | uint8_t update_map; |
| 173 | + uint8_t update_feature_data; | |
| 168 | 174 | int8_t base_quant[4]; |
| 169 | 175 | int8_t filter_level[4]; ///< base loop filter level |
| 170 | 176 | } segmentation; |
| @@ -192,8 +198,19 @@ typedef struct VP8Context { · 21 unmodified lines | ||
| 192 | 198 | int16_t chroma_qmul[2]; |
| 193 | 199 | } qmat[4]; |
| 194 | 200 | |
| 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 | + | |
| 195 | 211 | struct { |
| 196 | 212 | uint8_t enabled; ///< whether each mb can have a different strength based on mode/ref |
| 213 | + uint8_t update; | |
| 197 | 214 | |
| 198 | 215 | /** |
| 199 | 216 | * filter strength adjustment for the following macroblock modes: |
| @@ -221,6 +238,20 @@ typedef struct VP8Context { · 21 unmodified lines | ||
| 221 | 238 | |
| 222 | 239 | VP56RangeCoder c; ///< header context, includes mb modes and motion vectors |
| 223 | 240 | |
| 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 | + | |
| 224 | 255 | /** |
| 225 | 256 | * These are all of the updatable probabilities for binary decisions. |
| 226 | 257 | * They are only implicitly reset on keyframes, making it quite likely |
| @@ -258,6 +289,7 @@ typedef struct VP8Context { · 31 unmodified lines | ||
| 258 | 289 | */ |
| 259 | 290 | int num_coeff_partitions; |
| 260 | 291 | VP56RangeCoder coeff_partition[8]; |
| 292 | + int coeff_partition_size[8]; | |
| 261 | 293 | VideoDSPContext vdsp; |
| 262 | 294 | VP8DSPContext vp8dsp; |
| 263 | 295 | H264PredContext hpc; |