History

vp8: make mv_min/max thread-local if using partition threading.

Fixes tsan warnings like this in fate-vp8-test-vector-007:

Ronald S. Bultje committed 9 years ago

Commit fed92ad1 parent 9a54c6f2 files · +40 −32Browse files

Unified · Split

2 files
  1. libavcodec/vp8.c +28 −25
  2. libavcodec/vp8.h +12 −7
libavcodec/vp8.c+28−25
@@ -772,7 +772,7 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si · 771 unmodified lines
772}772}
773 773
774static av_always_inline774static av_always_inline
775void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src)775void clamp_mv(VP8mvbounds *s, VP56mv *dst, const VP56mv *src)
776{776{
777 dst->x = av_clip(src->x, av_clip(s->mv_min.x, INT16_MIN, INT16_MAX),777 dst->x = av_clip(src->x, av_clip(s->mv_min.x, INT16_MIN, INT16_MAX),
778 av_clip(s->mv_max.x, INT16_MIN, INT16_MAX));778 av_clip(s->mv_max.x, INT16_MIN, INT16_MAX));
@@ -1031,7 +1031,7 @@ void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb, · 252 unmodified lines
1031}1031}
1032 1032
1033static av_always_inline1033static av_always_inline
1034void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb,1034void vp8_decode_mvs(VP8Context *s, VP8mvbounds *mv_bounds, VP8Macroblock *mb,
1035 int mb_x, int mb_y, int layout)1035 int mb_x, int mb_y, int layout)
1036{1036{
1037 VP8Macroblock *mb_edge[3] = { 0 /* top */,1037 VP8Macroblock *mb_edge[3] = { 0 /* top */,
@@ -1102,7 +1102,7 @@ void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb, · 64 unmodified lines
1102 if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) {1102 if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) {
1103 if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) {1103 if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) {
1104 /* Choose the best mv out of 0,0 and the nearest mv */1104 /* Choose the best mv out of 0,0 and the nearest mv */
1105 clamp_mv(s, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);1105 clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
1106 cnt[CNT_SPLITMV] = ((mb_edge[VP8_EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) +1106 cnt[CNT_SPLITMV] = ((mb_edge[VP8_EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) +
1107 (mb_edge[VP8_EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 +1107 (mb_edge[VP8_EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 +
1108 (mb_edge[VP8_EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);1108 (mb_edge[VP8_EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);
@@ -1116,11 +1116,11 @@ void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb, · 7 unmodified lines
1116 mb->bmv[0] = mb->mv;1116 mb->bmv[0] = mb->mv;
1117 }1117 }
1118 } else {1118 } else {
1119 clamp_mv(s, &mb->mv, &near_mv[CNT_NEAR]);1119 clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAR]);
1120 mb->bmv[0] = mb->mv;1120 mb->bmv[0] = mb->mv;
1121 }1121 }
1122 } else {1122 } else {
1123 clamp_mv(s, &mb->mv, &near_mv[CNT_NEAREST]);1123 clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAREST]);
1124 mb->bmv[0] = mb->mv;1124 mb->bmv[0] = mb->mv;
1125 }1125 }
1126 } else {1126 } else {
@@ -1166,7 +1166,8 @@ void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb, · 39 unmodified lines
1166}1166}
1167 1167
1168static av_always_inline1168static av_always_inline
1169void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,1169void decode_mb_mode(VP8Context *s, VP8mvbounds *mv_bounds,
1170 VP8Macroblock *mb, int mb_x, int mb_y,
1170 uint8_t *segment, uint8_t *ref, int layout, int is_vp7)1171 uint8_t *segment, uint8_t *ref, int layout, int is_vp7)
1171{1172{
1172 VP56RangeCoder *c = &s->c;1173 VP56RangeCoder *c = &s->c;
@@ -1230,7 +1231,7 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, · 57 unmodified lines
1230 if (is_vp7)1231 if (is_vp7)
1231 vp7_decode_mvs(s, mb, mb_x, mb_y, layout);1232 vp7_decode_mvs(s, mb, mb_x, mb_y, layout);
1232 else1233 else
1233 vp8_decode_mvs(s, mb, mb_x, mb_y, layout);1234 vp8_decode_mvs(s, mv_bounds, mb, mb_x, mb_y, layout);
1234 } else {1235 } else {
1235 // intra MB, 16.11236 // intra MB, 16.1
1236 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);1237 mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);
@@ -2205,8 +2206,8 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, · 968 unmodified lines
2205 VP8Context *s = avctx->priv_data;2206 VP8Context *s = avctx->priv_data;
2206 int mb_x, mb_y;2207 int mb_x, mb_y;
2207 2208
2208 s->mv_min.y = -MARGIN;2209 s->mv_bounds.mv_min.y = -MARGIN;
2209 s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;2210 s->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
2210 for (mb_y = 0; mb_y < s->mb_height; mb_y++) {2211 for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
2211 VP8Macroblock *mb = s->macroblocks_base +2212 VP8Macroblock *mb = s->macroblocks_base +
2212 ((s->mb_width + 1) * (mb_y + 1) + 1);2213 ((s->mb_width + 1) * (mb_y + 1) + 1);
@@ -2214,20 +2215,20 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, · 1 unmodified line
2214 2215
2215 AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);2216 AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);
2216 2217
2217 s->mv_min.x = -MARGIN;2218 s->mv_bounds.mv_min.x = -MARGIN;
2218 s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;2219 s->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
2219 for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {2220 for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
2220 if (mb_y == 0)2221 if (mb_y == 0)
2221 AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top,2222 AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top,
2222 DC_PRED * 0x01010101);2223 DC_PRED * 0x01010101);
2223 decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,2224 decode_mb_mode(s, &s->mv_bounds, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
2224 prev_frame && prev_frame->seg_map ?2225 prev_frame && prev_frame->seg_map ?
2225 prev_frame->seg_map->data + mb_xy : NULL, 1, is_vp7);2226 prev_frame->seg_map->data + mb_xy : NULL, 1, is_vp7);
2226 s->mv_min.x -= 64;2227 s->mv_bounds.mv_min.x -= 64;
2227 s->mv_max.x -= 64;2228 s->mv_bounds.mv_max.x -= 64;
2228 }2229 }
2229 s->mv_min.y -= 64;2230 s->mv_bounds.mv_min.y -= 64;
2230 s->mv_max.y -= 64;2231 s->mv_bounds.mv_max.y -= 64;
2231 }2232 }
2232}2233}
2233 2234
@@ -2325,8 +2326,8 @@ static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void · 91 unmodified lines
2325 if (!is_vp7 || mb_y == 0)2326 if (!is_vp7 || mb_y == 0)
2326 memset(td->left_nnz, 0, sizeof(td->left_nnz));2327 memset(td->left_nnz, 0, sizeof(td->left_nnz));
2327 2328
2328 s->mv_min.x = -MARGIN;2329 td->mv_bounds.mv_min.x = -MARGIN;
2329 s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;2330 td->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
2330 2331
2331 for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {2332 for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
2332 if (c->end <= c->buffer && c->bits >= 0)2333 if (c->end <= c->buffer && c->bits >= 0)
@@ -2350,7 +2351,7 @@ static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void · 17 unmodified lines
2350 dst[2] - dst[1], 2);2351 dst[2] - dst[1], 2);
2351 2352
2352 if (!s->mb_layout)2353 if (!s->mb_layout)
2353 decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,2354 decode_mb_mode(s, &td->mv_bounds, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
2354 prev_frame && prev_frame->seg_map ?2355 prev_frame && prev_frame->seg_map ?
2355 prev_frame->seg_map->data + mb_xy : NULL, 0, is_vp7);2356 prev_frame->seg_map->data + mb_xy : NULL, 0, is_vp7);
2356 2357
@@ -2397,8 +2398,8 @@ static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void · 40 unmodified lines
2397 dst[0] += 16;2398 dst[0] += 16;
2398 dst[1] += 8;2399 dst[1] += 8;
2399 dst[2] += 8;2400 dst[2] += 8;
2400 s->mv_min.x -= 64;2401 td->mv_bounds.mv_min.x -= 64;
2401 s->mv_max.x -= 64;2402 td->mv_bounds.mv_max.x -= 64;
2402 2403
2403 if (mb_x == s->mb_width + 1) {2404 if (mb_x == s->mb_width + 1) {
2404 update_pos(td, mb_y, s->mb_width + 3);2405 update_pos(td, mb_y, s->mb_width + 3);
@@ -2504,6 +2505,8 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, · 99 unmodified lines
2504 int ret;2505 int ret;
2505 2506
2506 td->thread_nr = threadnr;2507 td->thread_nr = threadnr;
2508 td->mv_bounds.mv_min.y = -MARGIN - 64 * threadnr;
2509 td->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN - 64 * threadnr;
2507 for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {2510 for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
2508 atomic_store(&td->thread_mb_pos, mb_y << 16);2511 atomic_store(&td->thread_mb_pos, mb_y << 16);
2509 ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);2512 ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
@@ -2515,8 +2518,8 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, · 5 unmodified lines
2515 s->filter_mb_row(avctx, tdata, jobnr, threadnr);2518 s->filter_mb_row(avctx, tdata, jobnr, threadnr);
2516 update_pos(td, mb_y, INT_MAX & 0xFFFF);2519 update_pos(td, mb_y, INT_MAX & 0xFFFF);
2517 2520
2518 s->mv_min.y -= 64;2521 td->mv_bounds.mv_min.y -= 64 * num_jobs;
2519 s->mv_max.y -= 64;2522 td->mv_bounds.mv_max.y -= 64 * num_jobs;
2520 2523
2521 if (avctx->active_thread_type == FF_THREAD_FRAME)2524 if (avctx->active_thread_type == FF_THREAD_FRAME)
2522 ff_thread_report_progress(&curframe->tf, mb_y, 0);2525 ff_thread_report_progress(&curframe->tf, mb_y, 0);
@@ -2662,8 +2665,8 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, · 139 unmodified lines
2662 s->num_jobs = num_jobs;2665 s->num_jobs = num_jobs;
2663 s->curframe = curframe;2666 s->curframe = curframe;
2664 s->prev_frame = prev_frame;2667 s->prev_frame = prev_frame;
2665 s->mv_min.y = -MARGIN;2668 s->mv_bounds.mv_min.y = -MARGIN;
2666 s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;2669 s->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
2667 for (i = 0; i < MAX_THREADS; i++) {2670 for (i = 0; i < MAX_THREADS; i++) {
2668 VP8ThreadData *td = &s->thread_data[i];2671 VP8ThreadData *td = &s->thread_data[i];
2669 atomic_init(&td->thread_mb_pos, 0);2672 atomic_init(&td->thread_mb_pos, 0);
libavcodec/vp8.h+12−7
@@ -93,6 +93,16 @@ typedef struct VP8Macroblock { · 92 unmodified lines
93 VP56mv bmv[16];93 VP56mv bmv[16];
94} VP8Macroblock;94} VP8Macroblock;
95 95
96typedef struct VP8intmv {
97 int x;
98 int y;
99} VP8intmv;
100
101typedef struct VP8mvbounds {
102 VP8intmv mv_min;
103 VP8intmv mv_max;
104} VP8mvbounds;
105
96typedef struct VP8ThreadData {106typedef struct VP8ThreadData {
97 DECLARE_ALIGNED(16, int16_t, block)[6][4][16];107 DECLARE_ALIGNED(16, int16_t, block)[6][4][16];
98 DECLARE_ALIGNED(16, int16_t, block_dc)[16];108 DECLARE_ALIGNED(16, int16_t, block_dc)[16];
@@ -122,6 +132,7 @@ typedef struct VP8ThreadData { · 23 unmodified lines
122#define EDGE_EMU_LINESIZE 32132#define EDGE_EMU_LINESIZE 32
123 DECLARE_ALIGNED(16, uint8_t, edge_emu_buffer)[21 * EDGE_EMU_LINESIZE];133 DECLARE_ALIGNED(16, uint8_t, edge_emu_buffer)[21 * EDGE_EMU_LINESIZE];
124 VP8FilterStrength *filter_strength;134 VP8FilterStrength *filter_strength;
135 VP8mvbounds mv_bounds;
125} VP8ThreadData;136} VP8ThreadData;
126 137
127typedef struct VP8Frame {138typedef struct VP8Frame {
@@ -129,11 +140,6 @@ typedef struct VP8Frame { · 1 unmodified line
129 AVBufferRef *seg_map;140 AVBufferRef *seg_map;
130} VP8Frame;141} VP8Frame;
131 142
132typedef struct VP8intmv {
133 int x;
134 int y;
135} VP8intmv;
136
137#define MAX_THREADS 8143#define MAX_THREADS 8
138typedef struct VP8Context {144typedef struct VP8Context {
139 VP8ThreadData *thread_data;145 VP8ThreadData *thread_data;
@@ -152,8 +158,7 @@ typedef struct VP8Context { · 12 unmodified lines
152 uint8_t deblock_filter;158 uint8_t deblock_filter;
153 uint8_t mbskip_enabled;159 uint8_t mbskip_enabled;
154 uint8_t profile;160 uint8_t profile;
155 VP8intmv mv_min;161 VP8mvbounds mv_bounds;
156 VP8intmv mv_max;
157 162
158 int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type163 int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type
159 int ref_count[3];164 int ref_count[3];

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