History

First modification of multi-thread decoder

This is the first modification of VP8 multi-thread decoder, which uses same threads to decode macroblocks and then do loopfiltering for each frame. Inspired by Rob Clark, synchronization was done on every 8 macroblocks instead of every macroblock to reduce lock contention. Comparing with the original code, this implementation gave about 15%- 20% performance gain while decoding my test clips on a Core2 Quad platform (Linux). The work is not done yet. Test on other platforms are needed.

Yunqing Wang committed 16 years ago

Commit ba2e1071 parent 618c7d24 files · +532 −241Browse files

Unified · Split

4 files
  1. vp8/decoder/decoderthreading.h +1 −0
  2. vp8/decoder/onyxd_if.c +31 −0
  3. vp8/decoder/onyxd_int.h +7 −5
  4. vp8/decoder/threading.c +493 −236
vp8/decoder/decoderthreading.h+1−0
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818
1919 extern void vp8_mtdecode_mb_rows(VP8D_COMP *pbi,
2020 MACROBLOCKD *xd);
21+extern void vp8_mt_loop_filter_frame(VP8D_COMP *pbi);
2122 extern void vp8_stop_lfthread(VP8D_COMP *pbi);
2223 extern void vp8_start_lfthread(VP8D_COMP *pbi);
2324 extern void vp8_decoder_remove_threads(VP8D_COMP *pbi);
vp8/decoder/onyxd_if.c+31−0
@@ -367,6 +367,7 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign · 366 unmodified lines
367367 return -1;
368368 }
369369
370+/*
370371 if (!pbi->b_multithreaded_lf)
371372 {
372373 struct vpx_usec_timer lpftimer;
@@ -378,12 +379,42 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign · 5 unmodified lines
378379
379380 vpx_usec_timer_mark(&lpftimer);
380381 pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
382+ }else{
383+ struct vpx_usec_timer lpftimer;
384+ vpx_usec_timer_start(&lpftimer);
385+ // Apply the loop filter if appropriate.
386+
387+ if (cm->filter_level > 0)
388+ vp8_mt_loop_filter_frame(cm, &pbi->mb, cm->filter_level);
389+
390+ vpx_usec_timer_mark(&lpftimer);
391+ pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
381392 }
382393 if (cm->filter_level > 0) {
383394 cm->last_frame_type = cm->frame_type;
384395 cm->last_filter_type = cm->filter_type;
385396 cm->last_sharpness_level = cm->sharpness_level;
386397 }
398+*/
399+
400+ if(pbi->common.filter_level)
401+ {
402+ struct vpx_usec_timer lpftimer;
403+ vpx_usec_timer_start(&lpftimer);
404+ // Apply the loop filter if appropriate.
405+
406+ if (pbi->b_multithreaded_lf && cm->multi_token_partition != ONE_PARTITION)
407+ vp8_mt_loop_filter_frame(pbi); //cm, &pbi->mb, cm->filter_level);
408+ else
409+ vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level);
410+
411+ vpx_usec_timer_mark(&lpftimer);
412+ pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
413+
414+ cm->last_frame_type = cm->frame_type;
415+ cm->last_filter_type = cm->filter_type;
416+ cm->last_sharpness_level = cm->sharpness_level;
417+ }
387418
388419 vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
389420
vp8/decoder/onyxd_int.h+7−5
@@ -95,20 +95,22 @@ typedef struct VP8Decompressor · 94 unmodified lines
9595 int current_mb_col_main;
9696 int decoding_thread_count;
9797 int allocated_decoding_thread_count;
98+ int *current_mb_col; //Each row remembers its already decoded column.
99+ int mt_baseline_filter_level[MAX_MB_SEGMENTS];
98100
99101 // variable for threading
100102 DECLARE_ALIGNED(16, MACROBLOCKD, lpfmb);
101103 #if CONFIG_MULTITHREAD
102− pthread_t h_thread_lpf; // thread for postprocessing
103− sem_t h_event_lpf; // Event for post_proc completed
104− sem_t h_event_start_lpf;
104+ //pthread_t h_thread_lpf; // thread for postprocessing
105+ sem_t h_event_end_lpf; // Event for post_proc completed
106+ sem_t *h_event_start_lpf;
105107 #endif
106108 MB_ROW_DEC *mb_row_di;
107109 DECODETHREAD_DATA *de_thread_data;
108110 #if CONFIG_MULTITHREAD
109111 pthread_t *h_decoding_thread;
110− sem_t *h_event_mbrdecoding;
111− sem_t h_event_main;
112+ sem_t *h_event_start_decoding;
113+ sem_t h_event_end_decoding;
112114 // end of threading data
113115 #endif
114116 vp8_reader *mbc;
vp8/decoder/threading.c+493−236
@@ -23,6 +23,8 @@ · 22 unmodified lines
2323 #include "extend.h"
2424 #include "vpx_ports/vpx_timer.h"
2525
26+#define MAX_ROWS 256
27+
2628 extern void vp8_decode_mb_row(VP8D_COMP *pbi,
2729 VP8_COMMON *pc,
2830 int mb_row,
@@ -31,11 +33,10 @@ extern void vp8_decode_mb_row(VP8D_COMP *pbi, · 2 unmodified lines
3133 extern void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel);
3234 extern void vp8_decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd);
3335
36+void vp8_thread_loop_filter(VP8D_COMP *pbi, MB_ROW_DEC *mbrd, int ithread);
37+
3438 void vp8_setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
3539 {
36−
37−
38−
3940 #if CONFIG_MULTITHREAD
4041 VP8_COMMON *const pc = & pbi->common;
4142 int i, j;
@@ -46,8 +47,6 @@ void vp8_setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC · 4 unmodified lines
4647 #if CONFIG_RUNTIME_CPU_DETECT
4748 mbd->rtcd = xd->rtcd;
4849 #endif
49−
50−
5150 mbd->subpixel_predict = xd->subpixel_predict;
5251 mbd->subpixel_predict8x4 = xd->subpixel_predict8x4;
5352 mbd->subpixel_predict8x8 = xd->subpixel_predict8x8;
@@ -82,6 +81,8 @@ void vp8_setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC · 28 unmodified lines
8281 }
8382 }
8483
84+ for (i=0; i< pc->mb_rows; i++)
85+ pbi->current_mb_col[i]=-1;
8586 #else
8687 (void) pbi;
8788 (void) xd;
@@ -90,6 +91,70 @@ void vp8_setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC · 2 unmodified lines
9091 #endif
9192 }
9293
94+void vp8_setup_loop_filter_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
95+{
96+#if CONFIG_MULTITHREAD
97+ VP8_COMMON *const pc = & pbi->common;
98+ int i, j;
99+
100+ for (i = 0; i < count; i++)
101+ {
102+ MACROBLOCKD *mbd = &mbrd[i].mbd;
103+//#if CONFIG_RUNTIME_CPU_DETECT
104+// mbd->rtcd = xd->rtcd;
105+//#endif
106+
107+ //mbd->subpixel_predict = xd->subpixel_predict;
108+ //mbd->subpixel_predict8x4 = xd->subpixel_predict8x4;
109+ //mbd->subpixel_predict8x8 = xd->subpixel_predict8x8;
110+ //mbd->subpixel_predict16x16 = xd->subpixel_predict16x16;
111+ //mbd->gf_active_ptr = xd->gf_active_ptr;
112+
113+ mbd->mode_info = pc->mi - 1;
114+ mbd->mode_info_context = pc->mi + pc->mode_info_stride * (i + 1);
115+ mbd->mode_info_stride = pc->mode_info_stride;
116+
117+ //mbd->frame_type = pc->frame_type;
118+ //mbd->frames_since_golden = pc->frames_since_golden;
119+ //mbd->frames_till_alt_ref_frame = pc->frames_till_alt_ref_frame;
120+
121+ //mbd->pre = pc->yv12_fb[pc->lst_fb_idx];
122+ //mbd->dst = pc->yv12_fb[pc->new_fb_idx];
123+
124+ //vp8_setup_block_dptrs(mbd);
125+ //vp8_build_block_doffsets(mbd);
126+ mbd->segmentation_enabled = xd->segmentation_enabled; //
127+ mbd->mb_segement_abs_delta = xd->mb_segement_abs_delta; //
128+ vpx_memcpy(mbd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data)); //
129+
130+ //signed char ref_lf_deltas[MAX_REF_LF_DELTAS];
131+ vpx_memcpy(mbd->ref_lf_deltas, xd->ref_lf_deltas, sizeof(xd->ref_lf_deltas));
132+ //signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];
133+ vpx_memcpy(mbd->mode_lf_deltas, xd->mode_lf_deltas, sizeof(xd->mode_lf_deltas));
134+ //unsigned char mode_ref_lf_delta_enabled;
135+ //unsigned char mode_ref_lf_delta_update;
136+ mbd->mode_ref_lf_delta_enabled = xd->mode_ref_lf_delta_enabled;
137+ mbd->mode_ref_lf_delta_update = xd->mode_ref_lf_delta_update;
138+
139+ //mbd->mbmi.mode = DC_PRED;
140+ //mbd->mbmi.uv_mode = DC_PRED;
141+ //mbd->current_bc = &pbi->bc2;
142+
143+ //for (j = 0; j < 25; j++)
144+ //{
145+ // mbd->block[j].dequant = xd->block[j].dequant;
146+ //}
147+ }
148+
149+ for (i=0; i< pc->mb_rows; i++)
150+ pbi->current_mb_col[i]=-1;
151+#else
152+ (void) pbi;
153+ (void) xd;
154+ (void) mbrd;
155+ (void) count;
156+#endif
157+}
93158
94159 THREAD_FUNCTION vp8_thread_decoding_proc(void *p_data)
95160 {
@@ -104,142 +169,145 @@ THREAD_FUNCTION vp8_thread_decoding_proc(void *p_data) · 8 unmodified lines
104169 if (pbi->b_multithreaded_rd == 0)
105170 break;
106171
107− //if(WaitForSingleObject(pbi->h_event_mbrdecoding[ithread], INFINITE) == WAIT_OBJECT_0)
108− if (sem_wait(&pbi->h_event_mbrdecoding[ithread]) == 0)
172+ //if(WaitForSingleObject(pbi->h_event_start_decoding[ithread], INFINITE) == WAIT_OBJECT_0)
173+ if (sem_wait(&pbi->h_event_start_decoding[ithread]) == 0)
109174 {
110175 if (pbi->b_multithreaded_rd == 0)
111176 break;
112177 else
113178 {
114179 VP8_COMMON *pc = &pbi->common;
115− int mb_row = mbrd->mb_row;
116180 MACROBLOCKD *xd = &mbrd->mbd;
117181
118− //printf("ithread:%d mb_row %d\n", ithread, mb_row);
119− int i;
120− int recon_yoffset, recon_uvoffset;
121− int mb_col;
122− int ref_fb_idx = pc->lst_fb_idx;
123− int dst_fb_idx = pc->new_fb_idx;
124− int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
125− int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
126−
182+ int mb_row;
183+ int num_part = 1 << pbi->common.multi_token_partition;
127184 volatile int *last_row_current_mb_col;
128185
129− if (ithread > 0)
130− last_row_current_mb_col = &pbi->mb_row_di[ithread-1].current_mb_col;
131− else
132− last_row_current_mb_col = &pbi->current_mb_col_main;
133−
134− recon_yoffset = mb_row * recon_y_stride * 16;
135− recon_uvoffset = mb_row * recon_uv_stride * 8;
136− // reset above block coeffs
137−
138− xd->above_context[Y1CONTEXT] = pc->above_context[Y1CONTEXT];
139− xd->above_context[UCONTEXT ] = pc->above_context[UCONTEXT];
140− xd->above_context[VCONTEXT ] = pc->above_context[VCONTEXT];
141− xd->above_context[Y2CONTEXT] = pc->above_context[Y2CONTEXT];
142− xd->left_context = mb_row_left_context;
143− vpx_memset(mb_row_left_context, 0, sizeof(mb_row_left_context));
144− xd->up_available = (mb_row != 0);
145−
146− xd->mb_to_top_edge = -((mb_row * 16)) << 3;
147− xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
148−
149− for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
186+ for (mb_row = ithread+1; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
150187 {
151−
152− while (mb_col > (*last_row_current_mb_col - 1) && *last_row_current_mb_col != pc->mb_cols - 1)
188+ int i;
189+ int recon_yoffset, recon_uvoffset;
190+ int mb_col;
191+ int ref_fb_idx = pc->lst_fb_idx;
192+ int dst_fb_idx = pc->new_fb_idx;
193+ int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
194+ int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
195+
196+ pbi->mb_row_di[ithread].mb_row = mb_row;
197+ pbi->mb_row_di[ithread].mbd.current_bc = &pbi->mbc[mb_row%num_part];
198+
199+ last_row_current_mb_col = &pbi->current_mb_col[mb_row -1];
200+
201+ recon_yoffset = mb_row * recon_y_stride * 16;
202+ recon_uvoffset = mb_row * recon_uv_stride * 8;
203+ // reset above block coeffs
204+
205+ xd->above_context[Y1CONTEXT] = pc->above_context[Y1CONTEXT];
206+ xd->above_context[UCONTEXT ] = pc->above_context[UCONTEXT];
207+ xd->above_context[VCONTEXT ] = pc->above_context[VCONTEXT];
208+ xd->above_context[Y2CONTEXT] = pc->above_context[Y2CONTEXT];
209+ xd->left_context = mb_row_left_context;
210+ vpx_memset(mb_row_left_context, 0, sizeof(mb_row_left_context));
211+ xd->up_available = (mb_row != 0);
212+
213+ xd->mb_to_top_edge = -((mb_row * 16)) << 3;
214+ xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
215+
216+ for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
153217 {
154− x86_pause_hint();
155− thread_sleep(0);
156− }
218+ if ((mb_col & 7) == 0)
219+ {
220+ while (mb_col > (*last_row_current_mb_col - 8) && *last_row_current_mb_col != pc->mb_cols - 1)
221+ {
222+ x86_pause_hint();
223+ thread_sleep(0);
224+ }
225+ }
157226
158− // Take a copy of the mode and Mv information for this macroblock into the xd->mbmi
159− // the partition_bmi array is unused in the decoder, so don't copy it.
160− vpx_memcpy(&xd->mbmi, &xd->mode_info_context->mbmi,
161− sizeof(MB_MODE_INFO) - sizeof(xd->mbmi.partition_bmi));
227+ // Take a copy of the mode and Mv information for this macroblock into the xd->mbmi
228+ // the partition_bmi array is unused in the decoder, so don't copy it.
229+ vpx_memcpy(&xd->mbmi, &xd->mode_info_context->mbmi,
230+ sizeof(MB_MODE_INFO) - sizeof(xd->mbmi.partition_bmi));
162231
163− if (xd->mbmi.mode == SPLITMV || xd->mbmi.mode == B_PRED)
164− {
165− for (i = 0; i < 16; i++)
232+ if (xd->mbmi.mode == SPLITMV || xd->mbmi.mode == B_PRED)
166233 {
167− BLOCKD *d = &xd->block[i];
168− vpx_memcpy(&d->bmi, &xd->mode_info_context->bmi[i], sizeof(B_MODE_INFO));
234+ for (i = 0; i < 16; i++)
235+ {
236+ BLOCKD *d = &xd->block[i];
237+ vpx_memcpy(&d->bmi, &xd->mode_info_context->bmi[i], sizeof(B_MODE_INFO));
238+ }
169239 }
170− }
171−
172− // Distance of Mb to the various image edges.
173− // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
174− xd->mb_to_left_edge = -((mb_col * 16) << 3);
175− xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
176240
177− xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
178− xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
179− xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
241+ // Distance of Mb to the various image edges.
242+ // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
243+ xd->mb_to_left_edge = -((mb_col * 16) << 3);
244+ xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
180245
181− xd->left_available = (mb_col != 0);
246+ xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
247+ xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
248+ xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
182249
183− // Select the appropriate reference frame for this MB
184− if (xd->mbmi.ref_frame == LAST_FRAME)
185− ref_fb_idx = pc->lst_fb_idx;
186− else if (xd->mbmi.ref_frame == GOLDEN_FRAME)
187− ref_fb_idx = pc->gld_fb_idx;
188− else
189− ref_fb_idx = pc->alt_fb_idx;
250+ xd->left_available = (mb_col != 0);
190251
191− xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
192− xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
193− xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
252+ // Select the appropriate reference frame for this MB
253+ if (xd->mbmi.ref_frame == LAST_FRAME)
254+ ref_fb_idx = pc->lst_fb_idx;
255+ else if (xd->mbmi.ref_frame == GOLDEN_FRAME)
256+ ref_fb_idx = pc->gld_fb_idx;
257+ else
258+ ref_fb_idx = pc->alt_fb_idx;
194259
195− vp8_build_uvmvs(xd, pc->full_pixel);
260+ xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
261+ xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
262+ xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
196263
197− vp8_decode_macroblock(pbi, xd);
264+ vp8_build_uvmvs(xd, pc->full_pixel);
198265
266+ vp8_decode_macroblock(pbi, xd);
199267
200− recon_yoffset += 16;
201− recon_uvoffset += 8;
268+ recon_yoffset += 16;
269+ recon_uvoffset += 8;
202270
203− ++xd->mode_info_context; /* next mb */
271+ ++xd->mode_info_context; /* next mb */
204272
205− xd->gf_active_ptr++; // GF useage flag for next MB
273+ xd->gf_active_ptr++; // GF useage flag for next MB
206274
207− xd->above_context[Y1CONTEXT] += 4;
208− xd->above_context[UCONTEXT ] += 2;
209− xd->above_context[VCONTEXT ] += 2;
210− xd->above_context[Y2CONTEXT] ++;
211− pbi->mb_row_di[ithread].current_mb_col = mb_col;
275+ xd->above_context[Y1CONTEXT] += 4;
276+ xd->above_context[UCONTEXT ] += 2;
277+ xd->above_context[VCONTEXT ] += 2;
278+ xd->above_context[Y2CONTEXT] ++;
212279
213− }
280+ //pbi->mb_row_di[ithread].current_mb_col = mb_col;
281+ pbi->current_mb_col[mb_row] = mb_col;
282+ }
214283
215− // adjust to the next row of mbs
216− vp8_extend_mb_row(
284+ // adjust to the next row of mbs
285+ vp8_extend_mb_row(
217286 &pc->yv12_fb[dst_fb_idx],
218287 xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8
219− );
288+ );
220289
221− ++xd->mode_info_context; /* skip prediction column */
290+ ++xd->mode_info_context; /* skip prediction column */
222291
223− // since we have multithread
224− xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
292+ // since we have multithread
293+ xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
225294
226− //memcpy(&pbi->lpfmb, &pbi->mb, sizeof(pbi->mb));
227− if ((mb_row & 1) == 1)
228− {
229295 pbi->last_mb_row_decoded = mb_row;
230− //printf("S%d", pbi->last_mb_row_decoded);
231− }
232−
233− if (ithread == (pbi->decoding_thread_count - 1) || mb_row == pc->mb_rows - 1)
234− {
235− //SetEvent(pbi->h_event_main);
236− sem_post(&pbi->h_event_main);
237296
238297 }
239298 }
240299 }
241− }
300+ // add this to each frame
301+ if ((mbrd->mb_row == pbi->common.mb_rows-1) || ((mbrd->mb_row == pbi->common.mb_rows-2) && (pbi->common.mb_rows % (pbi->decoding_thread_count+1))==1))
302+ {
303+ //SetEvent(pbi->h_event_end_decoding);
304+ sem_post(&pbi->h_event_end_decoding);
305+ }
306+
307+ if ((pbi->b_multithreaded_lf) &&(pbi->common.filter_level))
308+ vp8_thread_loop_filter(pbi, mbrd, ithread);
242309
310+ }
243311 #else
244312 (void) p_data;
245313 #endif
@@ -247,96 +315,60 @@ THREAD_FUNCTION vp8_thread_decoding_proc(void *p_data) · 1 unmodified line
247315 return 0 ;
248316 }
249317
250−THREAD_FUNCTION vp8_thread_loop_filter(void *p_data)
318+
319+void vp8_thread_loop_filter(VP8D_COMP *pbi, MB_ROW_DEC *mbrd, int ithread)
251320 {
252321 #if CONFIG_MULTITHREAD
253− VP8D_COMP *pbi = (VP8D_COMP *)p_data;
254322
255− while (1)
256− {
257− if (pbi->b_multithreaded_lf == 0)
258− break;
259−
260− //printf("before waiting for start_lpf\n");
261−
262− //if(WaitForSingleObject(pbi->h_event_start_lpf, INFINITE) == WAIT_OBJECT_0)
263− if (sem_wait(&pbi->h_event_start_lpf) == 0)
323+ if (sem_wait(&pbi->h_event_start_lpf[ithread]) == 0)
264324 {
265− if (pbi->b_multithreaded_lf == 0) // we're shutting down
266− break;
267− else
325+ // if (pbi->b_multithreaded_lf == 0) // we're shutting down ????
326+ // break;
327+ // else
268328 {
269−
270329 VP8_COMMON *cm = &pbi->common;
271− MACROBLOCKD *mbd = &pbi->lpfmb;
330+ MACROBLOCKD *mbd = &mbrd->mbd;
272331 int default_filt_lvl = pbi->common.filter_level;
273332
274− YV12_BUFFER_CONFIG *post = &cm->yv12_fb[cm->new_fb_idx];
333+ YV12_BUFFER_CONFIG *post = cm->frame_to_show;
275334 loop_filter_info *lfi = cm->lf_info;
276− int frame_type = cm->frame_type;
335+ //int frame_type = cm->frame_type;
277336
278337 int mb_row;
279338 int mb_col;
280339
281− int baseline_filter_level[MAX_MB_SEGMENTS];
282340 int filter_level;
283341 int alt_flt_enabled = mbd->segmentation_enabled;
284342
285343 int i;
286344 unsigned char *y_ptr, *u_ptr, *v_ptr;
287345
288− volatile int *last_mb_row_decoded = &pbi->last_mb_row_decoded;
289−
290− //MODE_INFO * this_mb_mode_info = cm->mi;
291− mbd->mode_info_context = cm->mi; // Point at base of Mb MODE_INFO list
292−
293− // Note the baseline filter values for each segment
294− if (alt_flt_enabled)
295− {
296− for (i = 0; i < MAX_MB_SEGMENTS; i++)
297− {
298− if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
299− baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
300− else
301− {
302− baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
303− baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0; // Clamp to valid range
304− }
305− }
306− }
307− else
308− {
309− for (i = 0; i < MAX_MB_SEGMENTS; i++)
310− baseline_filter_level[i] = default_filt_lvl;
311− }
312−
313− // Initialize the loop filter for this frame.
314− if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
315− vp8_init_loop_filter(cm);
316− else if (frame_type != cm->last_frame_type)
317− vp8_frame_init_loop_filter(lfi, frame_type);
346+ volatile int *last_row_current_mb_col;
318347
319348 // Set up the buffer pointers
320− y_ptr = post->y_buffer;
321− u_ptr = post->u_buffer;
322− v_ptr = post->v_buffer;
349+ y_ptr = post->y_buffer + post->y_stride * 16 * (ithread +1);
350+ u_ptr = post->u_buffer + post->uv_stride * 8 * (ithread +1);
351+ v_ptr = post->v_buffer + post->uv_stride * 8 * (ithread +1);
323352
324353 // vp8_filter each macro block
325− for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
354+ for (mb_row = ithread+1; mb_row < cm->mb_rows; mb_row+= (pbi->decoding_thread_count + 1))
326355 {
356+ last_row_current_mb_col = &pbi->current_mb_col[mb_row -1];
327357
328− while (mb_row >= *last_mb_row_decoded)
329− {
330− x86_pause_hint();
331− thread_sleep(0);
332− }
333−
334− //printf("R%d", mb_row);
335358 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
336359 {
337360 int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
338361
339− filter_level = baseline_filter_level[Segment];
362+ if ((mb_col & 7) == 0)
363+ {
364+ while (mb_col > (*last_row_current_mb_col-8) && *last_row_current_mb_col != cm->mb_cols - 1)
365+ {
366+ x86_pause_hint();
367+ thread_sleep(0);
368+ }
369+ }
370+
371+ filter_level = pbi->mt_baseline_filter_level[Segment];
340372
341373 // Apply any context driven MB level adjustment
342374 vp8_adjust_mb_lf_value(mbd, &filter_level);
@@ -362,29 +394,28 @@ THREAD_FUNCTION vp8_thread_loop_filter(void *p_data) · 19 unmodified lines
362394 v_ptr += 8;
363395
364396 mbd->mode_info_context++; // step to next MB
365−
397+ pbi->current_mb_col[mb_row] = mb_col;
366398 }
367399
368− y_ptr += post->y_stride * 16 - post->y_width;
369− u_ptr += post->uv_stride * 8 - post->uv_width;
370− v_ptr += post->uv_stride * 8 - post->uv_width;
371−
372400 mbd->mode_info_context++; // Skip border mb
373− }
374401
375− //printf("R%d\n", mb_row);
376− // When done, signal main thread that ME is finished
377− //SetEvent(pbi->h_event_lpf);
378− sem_post(&pbi->h_event_lpf);
379− }
402+ y_ptr += post->y_stride * 16 * (pbi->decoding_thread_count + 1) - post->y_width;
403+ u_ptr += post->uv_stride * 8 * (pbi->decoding_thread_count + 1) - post->uv_width;
404+ v_ptr += post->uv_stride * 8 * (pbi->decoding_thread_count + 1) - post->uv_width;
380405
406+ mbd->mode_info_context += pbi->decoding_thread_count * mbd->mode_info_stride; // Skip border mb
407+ }
408+ }
381409 }
382− }
383410
411+ // add this to each frame
412+ if ((mbrd->mb_row == pbi->common.mb_rows-1) || ((mbrd->mb_row == pbi->common.mb_rows-2) && (pbi->common.mb_rows % (pbi->decoding_thread_count+1))==1))
413+ {
414+ sem_post(&pbi->h_event_end_lpf);
415+ }
384416 #else
385− (void) p_data;
417+ (void) pbi;
386418 #endif
387− return 0;
388419 }
389420
390421 void vp8_decoder_create_threads(VP8D_COMP *pbi)
@@ -396,39 +427,38 @@ void vp8_decoder_create_threads(VP8D_COMP *pbi) · 5 unmodified lines
396427 pbi->b_multithreaded_rd = 0;
397428 pbi->b_multithreaded_lf = 0;
398429 pbi->allocated_decoding_thread_count = 0;
399− core_count = (pbi->max_threads > 16) ? 16 : pbi->max_threads; //vp8_get_proc_core_count();
400− if (core_count > 1)
401− {
402− sem_init(&pbi->h_event_lpf, 0, 0);
403− sem_init(&pbi->h_event_start_lpf, 0, 0);
404− pbi->b_multithreaded_lf = 1;
405− pthread_create(&pbi->h_thread_lpf, 0, vp8_thread_loop_filter, (pbi));
406− }
430+ core_count = (pbi->max_threads > 16) ? 16 : pbi->max_threads;
407431
408432 if (core_count > 1)
409433 {
410434 pbi->b_multithreaded_rd = 1;
411− pbi->decoding_thread_count = core_count - 1;
435+ pbi->b_multithreaded_lf = 1; // this can be merged with pbi->b_multithreaded_rd ?
436+ pbi->decoding_thread_count = core_count -1;
412437
413438 CHECK_MEM_ERROR(pbi->h_decoding_thread, vpx_malloc(sizeof(pthread_t) * pbi->decoding_thread_count));
414− CHECK_MEM_ERROR(pbi->h_event_mbrdecoding, vpx_malloc(sizeof(sem_t) * pbi->decoding_thread_count));
439+ CHECK_MEM_ERROR(pbi->h_event_start_decoding, vpx_malloc(sizeof(sem_t) * pbi->decoding_thread_count));
415440 CHECK_MEM_ERROR(pbi->mb_row_di, vpx_memalign(32, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count));
416441 vpx_memset(pbi->mb_row_di, 0, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count);
417442 CHECK_MEM_ERROR(pbi->de_thread_data, vpx_malloc(sizeof(DECODETHREAD_DATA) * pbi->decoding_thread_count));
418443
444+ CHECK_MEM_ERROR(pbi->current_mb_col, vpx_malloc(sizeof(int) * MAX_ROWS)); // pc->mb_rows));
445+ CHECK_MEM_ERROR(pbi->h_event_start_lpf, vpx_malloc(sizeof(sem_t) * pbi->decoding_thread_count));
446+
419447 for (ithread = 0; ithread < pbi->decoding_thread_count; ithread++)
420448 {
421− sem_init(&pbi->h_event_mbrdecoding[ithread], 0, 0);
449+ sem_init(&pbi->h_event_start_decoding[ithread], 0, 0);
450+ sem_init(&pbi->h_event_start_lpf[ithread], 0, 0);
422451
423452 pbi->de_thread_data[ithread].ithread = ithread;
424453 pbi->de_thread_data[ithread].ptr1 = (void *)pbi;
425454 pbi->de_thread_data[ithread].ptr2 = (void *) &pbi->mb_row_di[ithread];
426455
427456 pthread_create(&pbi->h_decoding_thread[ithread], 0, vp8_thread_decoding_proc, (&pbi->de_thread_data[ithread]));
428−
429457 }
430458
431− sem_init(&pbi->h_event_main, 0, 0);
459+ sem_init(&pbi->h_event_end_decoding, 0, 0);
460+ sem_init(&pbi->h_event_end_lpf, 0, 0);
461+
432462 pbi->allocated_decoding_thread_count = pbi->decoding_thread_count;
433463 }
434464
@@ -443,39 +473,35 @@ void vp8_decoder_remove_threads(VP8D_COMP *pbi) · 8 unmodified lines
443473
444474 if (pbi->b_multithreaded_lf)
445475 {
476+ int i;
446477 pbi->b_multithreaded_lf = 0;
447− sem_post(&pbi->h_event_start_lpf);
448− pthread_join(pbi->h_thread_lpf, 0);
449− sem_destroy(&pbi->h_event_start_lpf);
478+
479+ for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
480+ sem_destroy(&pbi->h_event_start_lpf[i]);
481+
482+ sem_destroy(&pbi->h_event_end_lpf);
450483 }
451484
452485 //shutdown MB Decoding thread;
453486 if (pbi->b_multithreaded_rd)
454487 {
488+ int i;
489+
455490 pbi->b_multithreaded_rd = 0;
491+
456492 // allow all threads to exit
493+ for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
457494 {
458− int i;
459−
460− for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
461− {
462−
463− sem_post(&pbi->h_event_mbrdecoding[i]);
464− pthread_join(pbi->h_decoding_thread[i], NULL);
465− }
495+ sem_post(&pbi->h_event_start_decoding[i]);
496+ pthread_join(pbi->h_decoding_thread[i], NULL);
466497 }
467− {
468−
469− int i;
470− for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
471− {
472− sem_destroy(&pbi->h_event_mbrdecoding[i]);
473− }
474−
475498
499+ for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
500+ {
501+ sem_destroy(&pbi->h_event_start_decoding[i]);
476502 }
477503
478− sem_destroy(&pbi->h_event_main);
504+ sem_destroy(&pbi->h_event_end_decoding);
479505
480506 if (pbi->h_decoding_thread)
481507 {
@@ -483,10 +509,16 @@ void vp8_decoder_remove_threads(VP8D_COMP *pbi) · 1 unmodified line
483509 pbi->h_decoding_thread = NULL;
484510 }
485511
486− if (pbi->h_event_mbrdecoding)
512+ if (pbi->h_event_start_decoding)
487513 {
488− vpx_free(pbi->h_event_mbrdecoding);
489− pbi->h_event_mbrdecoding = NULL;
514+ vpx_free(pbi->h_event_start_decoding);
515+ pbi->h_event_start_decoding = NULL;
516+ }
517+
518+ if (pbi->h_event_start_lpf)
519+ {
520+ vpx_free(pbi->h_event_start_lpf);
521+ pbi->h_event_start_lpf = NULL;
490522 }
491523
492524 if (pbi->mb_row_di)
@@ -500,8 +532,13 @@ void vp8_decoder_remove_threads(VP8D_COMP *pbi) · 7 unmodified lines
500532 vpx_free(pbi->de_thread_data);
501533 pbi->de_thread_data = NULL;
502534 }
503− }
504535
536+ if (pbi->current_mb_col)
537+ {
538+ vpx_free(pbi->current_mb_col);
539+ pbi->current_mb_col = NULL ;
540+ }
541+ }
505542 #else
506543 (void) pbi;
507544 #endif
@@ -511,9 +548,12 @@ void vp8_decoder_remove_threads(VP8D_COMP *pbi) · 3 unmodified lines
511548 void vp8_start_lfthread(VP8D_COMP *pbi)
512549 {
513550 #if CONFIG_MULTITHREAD
551+ /*
514552 memcpy(&pbi->lpfmb, &pbi->mb, sizeof(pbi->mb));
515553 pbi->last_mb_row_decoded = 0;
516554 sem_post(&pbi->h_event_start_lpf);
555+ */
556+ (void) pbi;
517557 #else
518558 (void) pbi;
519559 #endif
@@ -522,14 +562,17 @@ void vp8_start_lfthread(VP8D_COMP *pbi) · 2 unmodified lines
522562 void vp8_stop_lfthread(VP8D_COMP *pbi)
523563 {
524564 #if CONFIG_MULTITHREAD
565+ /*
525566 struct vpx_usec_timer timer;
526567
527568 vpx_usec_timer_start(&timer);
528569
529− sem_wait(&pbi->h_event_lpf);
570+ sem_wait(&pbi->h_event_end_lpf);
530571
531572 vpx_usec_timer_mark(&timer);
532573 pbi->time_loop_filtering += vpx_usec_timer_elapsed(&timer);
574+ */
575+ (void) pbi;
533576 #else
534577 (void) pbi;
535578 #endif
@@ -545,49 +588,263 @@ void vp8_mtdecode_mb_rows(VP8D_COMP *pbi, · 9 unmodified lines
545588
546589 int ibc = 0;
547590 int num_part = 1 << pbi->common.multi_token_partition;
591+ int i;
592+ volatile int *last_row_current_mb_col = NULL;
548593
549594 vp8_setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count);
550595
596+ for (i = 0; i < pbi->decoding_thread_count; i++)
597+ sem_post(&pbi->h_event_start_decoding[i]);
598+
551599 for (mb_row = 0; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
552600 {
553601 int i;
554− pbi->current_mb_col_main = -1;
555602
556− xd->current_bc = &pbi->mbc[ibc];
557− ibc++ ;
603+ xd->current_bc = &pbi->mbc[mb_row%num_part];
558604
559− if (ibc == num_part)
560− ibc = 0;
561−
562− for (i = 0; i < pbi->decoding_thread_count; i++)
605+ //vp8_decode_mb_row(pbi, pc, mb_row, xd);
563606 {
564− if ((mb_row + i + 1) >= pc->mb_rows)
565− break;
607+ int i;
608+ int recon_yoffset, recon_uvoffset;
609+ int mb_col;
610+ int ref_fb_idx = pc->lst_fb_idx;
611+ int dst_fb_idx = pc->new_fb_idx;
612+ int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
613+ int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
614+
615+ // volatile int *last_row_current_mb_col = NULL;
616+ if (mb_row > 0)
617+ last_row_current_mb_col = &pbi->current_mb_col[mb_row -1];
618+
619+ vpx_memset(pc->left_context, 0, sizeof(pc->left_context));
620+ recon_yoffset = mb_row * recon_y_stride * 16;
621+ recon_uvoffset = mb_row * recon_uv_stride * 8;
622+ // reset above block coeffs
623+
624+ xd->above_context[Y1CONTEXT] = pc->above_context[Y1CONTEXT];
625+ xd->above_context[UCONTEXT ] = pc->above_context[UCONTEXT];
626+ xd->above_context[VCONTEXT ] = pc->above_context[VCONTEXT];
627+ xd->above_context[Y2CONTEXT] = pc->above_context[Y2CONTEXT];
628+ xd->up_available = (mb_row != 0);
629+
630+ xd->mb_to_top_edge = -((mb_row * 16)) << 3;
631+ xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
632+
633+ for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
634+ {
566635
567− pbi->mb_row_di[i].mb_row = mb_row + i + 1;
568− pbi->mb_row_di[i].mbd.current_bc = &pbi->mbc[ibc];
569− ibc++;
636+ if ( mb_row > 0 && (mb_col & 7) == 0){
637+ //if ( mb_row > 0 ){
638+ while (mb_col > (*last_row_current_mb_col - 8) && *last_row_current_mb_col != pc->mb_cols - 1)
639+ {
640+ x86_pause_hint();
641+ thread_sleep(0);
642+ }
570643
571− if (ibc == num_part)
572− ibc = 0;
644+ }
573645
574− pbi->mb_row_di[i].current_mb_col = -1;
575− sem_post(&pbi->h_event_mbrdecoding[i]);
576− }
646+ // Take a copy of the mode and Mv information for this macroblock into the xd->mbmi
647+ // the partition_bmi array is unused in the decoder, so don't copy it.
648+ vpx_memcpy(&xd->mbmi, &xd->mode_info_context->mbmi,
649+ sizeof(MB_MODE_INFO) - sizeof(xd->mbmi.partition_bmi));
650+
651+ if (xd->mbmi.mode == SPLITMV || xd->mbmi.mode == B_PRED)
652+ {
653+ for (i = 0; i < 16; i++)
654+ {
655+ BLOCKD *d = &xd->block[i];
656+ vpx_memcpy(&d->bmi, &xd->mode_info_context->bmi[i], sizeof(B_MODE_INFO));
657+ }
658+ }
659+
660+ // Distance of Mb to the various image edges.
661+ // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
662+ xd->mb_to_left_edge = -((mb_col * 16) << 3);
663+ xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
664+
665+ xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
666+ xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
667+ xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
668+
669+ xd->left_available = (mb_col != 0);
670+
671+ // Select the appropriate reference frame for this MB
672+ if (xd->mbmi.ref_frame == LAST_FRAME)
673+ ref_fb_idx = pc->lst_fb_idx;
674+ else if (xd->mbmi.ref_frame == GOLDEN_FRAME)
675+ ref_fb_idx = pc->gld_fb_idx;
676+ else
677+ ref_fb_idx = pc->alt_fb_idx;
678+
679+ xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
680+ xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
681+ xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
682+
683+ vp8_build_uvmvs(xd, pc->full_pixel);
684+
685+ vp8_decode_macroblock(pbi, xd);
686+
687+ recon_yoffset += 16;
688+ recon_uvoffset += 8;
689+
690+ ++xd->mode_info_context; /* next mb */
691+
692+ xd->gf_active_ptr++; // GF useage flag for next MB
693+
694+ xd->above_context[Y1CONTEXT] += 4;
695+ xd->above_context[UCONTEXT ] += 2;
696+ xd->above_context[VCONTEXT ] += 2;
697+ xd->above_context[Y2CONTEXT] ++;
698+
699+ //pbi->current_mb_col_main = mb_col;
700+ pbi->current_mb_col[mb_row] = mb_col;
701+ }
702+
703+ // adjust to the next row of mbs
704+ vp8_extend_mb_row(
705+ &pc->yv12_fb[dst_fb_idx],
706+ xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8
707+ );
577708
578− vp8_decode_mb_row(pbi, pc, mb_row, xd);
709+ ++xd->mode_info_context; /* skip prediction column */
579710
711+ pbi->last_mb_row_decoded = mb_row;
712+ }
580713 xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
714+ }
715+
716+ sem_wait(&pbi->h_event_end_decoding); // add back for each frame
717+#else
718+ (void) pbi;
719+ (void) xd;
720+#endif
721+}
722+
723+
724+void vp8_mt_loop_filter_frame( VP8D_COMP *pbi)
725+{
726+#if CONFIG_MULTITHREAD
727+ VP8_COMMON *cm = &pbi->common;
728+ MACROBLOCKD *mbd = &pbi->mb;
729+ int default_filt_lvl = pbi->common.filter_level;
730+
731+ YV12_BUFFER_CONFIG *post = cm->frame_to_show;
732+ loop_filter_info *lfi = cm->lf_info;
733+ int frame_type = cm->frame_type;
734+
735+ int mb_row;
736+ int mb_col;
737+
738+ int filter_level;
739+ int alt_flt_enabled = mbd->segmentation_enabled;
740+
741+ int i;
742+ unsigned char *y_ptr, *u_ptr, *v_ptr;
743+
744+ volatile int *last_row_current_mb_col=NULL;
745+
746+ vp8_setup_loop_filter_thread_data(pbi, mbd, pbi->mb_row_di, pbi->decoding_thread_count);
747+
748+ mbd->mode_info_context = cm->mi; // Point at base of Mb MODE_INFO list
749+
750+ // Note the baseline filter values for each segment
751+ if (alt_flt_enabled)
752+ {
753+ for (i = 0; i < MAX_MB_SEGMENTS; i++)
754+ {
755+ // Abs value
756+ if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
757+ pbi->mt_baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
758+ // Delta Value
759+ else
760+ {
761+ pbi->mt_baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
762+ pbi->mt_baseline_filter_level[i] = (pbi->mt_baseline_filter_level[i] >= 0) ? ((pbi->mt_baseline_filter_level[i] <= MAX_LOOP_FILTER) ? pbi->mt_baseline_filter_level[i] : MAX_LOOP_FILTER) : 0; // Clamp to valid range
763+ }
764+ }
765+ }
766+ else
767+ {
768+ for (i = 0; i < MAX_MB_SEGMENTS; i++)
769+ pbi->mt_baseline_filter_level[i] = default_filt_lvl;
770+ }
771+
772+ // Initialize the loop filter for this frame.
773+ if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
774+ vp8_init_loop_filter(cm);
775+ else if (frame_type != cm->last_frame_type)
776+ vp8_frame_init_loop_filter(lfi, frame_type);
777+
778+ for (i = 0; i < pbi->decoding_thread_count; i++)
779+ sem_post(&pbi->h_event_start_lpf[i]);
780+ // sem_post(&pbi->h_event_start_lpf);
781+
782+ // Set up the buffer pointers
783+ y_ptr = post->y_buffer;
784+ u_ptr = post->u_buffer;
785+ v_ptr = post->v_buffer;
581786
582− if (mb_row < pc->mb_rows - 1)
787+ // vp8_filter each macro block
788+ for (mb_row = 0; mb_row < cm->mb_rows; mb_row+= (pbi->decoding_thread_count + 1))
789+ {
790+ if (mb_row > 0)
791+ last_row_current_mb_col = &pbi->current_mb_col[mb_row -1];
792+
793+ for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
583794 {
584− sem_wait(&pbi->h_event_main);
795+ int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
796+
797+
798+ if ( mb_row > 0 && (mb_col & 7) == 0){
799+ // if ( mb_row > 0 ){
800+ while (mb_col > (*last_row_current_mb_col-8) && *last_row_current_mb_col != cm->mb_cols - 1)
801+ {
802+ x86_pause_hint();
803+ thread_sleep(0);
804+ }
805+ }
806+
807+ filter_level = pbi->mt_baseline_filter_level[Segment];
808+
809+ // Distance of Mb to the various image edges.
810+ // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
811+ // Apply any context driven MB level adjustment
812+ vp8_adjust_mb_lf_value(mbd, &filter_level);
813+
814+ if (filter_level)
815+ {
816+ if (mb_col > 0)
817+ cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
818+
819+ if (mbd->mode_info_context->mbmi.dc_diff > 0)
820+ cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
821+
822+ // don't apply across umv border
823+ if (mb_row > 0)
824+ cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
825+
826+ if (mbd->mode_info_context->mbmi.dc_diff > 0)
827+ cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
828+ }
829+
830+ y_ptr += 16;
831+ u_ptr += 8;
832+ v_ptr += 8;
833+
834+ mbd->mode_info_context++; // step to next MB
835+ pbi->current_mb_col[mb_row] = mb_col;
585836 }
837+ mbd->mode_info_context++; // Skip border mb
838+
839+ //update for multi-thread
840+ y_ptr += post->y_stride * 16 * (pbi->decoding_thread_count + 1) - post->y_width;
841+ u_ptr += post->uv_stride * 8 * (pbi->decoding_thread_count + 1) - post->uv_width;
842+ v_ptr += post->uv_stride * 8 * (pbi->decoding_thread_count + 1) - post->uv_width;
843+ mbd->mode_info_context += pbi->decoding_thread_count * mbd->mode_info_stride;
586844 }
587845
588− pbi->last_mb_row_decoded = mb_row;
846+ sem_wait(&pbi->h_event_end_lpf);
589847 #else
590848 (void) pbi;
591− (void) xd;
592849 #endif
593850 }

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