1 : /*
2 : * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 :
12 : #if !defined(WIN32) && CONFIG_OS_SUPPORT == 1
13 : # include <unistd.h>
14 : #endif
15 : #include "onyxd_int.h"
16 : #include "vpx_mem/vpx_mem.h"
17 : #include "vp8/common/threading.h"
18 :
19 : #include "vp8/common/loopfilter.h"
20 : #include "vp8/common/extend.h"
21 : #include "vpx_ports/vpx_timer.h"
22 : #include "detokenize.h"
23 : #include "vp8/common/reconinter.h"
24 : #include "reconintra_mt.h"
25 : #if CONFIG_ERROR_CONCEALMENT
26 : #include "error_concealment.h"
27 : #endif
28 :
29 : extern void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd);
30 : extern void clamp_mvs(MACROBLOCKD *xd);
31 : extern void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel);
32 :
33 : #if CONFIG_RUNTIME_CPU_DETECT
34 : #define RTCD_VTABLE(x) (&(pbi)->common.rtcd.x)
35 : #else
36 : #define RTCD_VTABLE(x) NULL
37 : #endif
38 :
39 0 : static void setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
40 : {
41 0 : VP8_COMMON *const pc = & pbi->common;
42 : int i, j;
43 :
44 0 : for (i = 0; i < count; i++)
45 : {
46 0 : MACROBLOCKD *mbd = &mbrd[i].mbd;
47 : #if CONFIG_RUNTIME_CPU_DETECT
48 0 : mbd->rtcd = xd->rtcd;
49 : #endif
50 0 : mbd->subpixel_predict = xd->subpixel_predict;
51 0 : mbd->subpixel_predict8x4 = xd->subpixel_predict8x4;
52 0 : mbd->subpixel_predict8x8 = xd->subpixel_predict8x8;
53 0 : mbd->subpixel_predict16x16 = xd->subpixel_predict16x16;
54 :
55 0 : mbd->mode_info_context = pc->mi + pc->mode_info_stride * (i + 1);
56 0 : mbd->mode_info_stride = pc->mode_info_stride;
57 :
58 0 : mbd->frame_type = pc->frame_type;
59 0 : mbd->frames_since_golden = pc->frames_since_golden;
60 0 : mbd->frames_till_alt_ref_frame = pc->frames_till_alt_ref_frame;
61 :
62 0 : mbd->pre = pc->yv12_fb[pc->lst_fb_idx];
63 0 : mbd->dst = pc->yv12_fb[pc->new_fb_idx];
64 :
65 0 : vp8_setup_block_dptrs(mbd);
66 0 : vp8_build_block_doffsets(mbd);
67 0 : mbd->segmentation_enabled = xd->segmentation_enabled;
68 0 : mbd->mb_segement_abs_delta = xd->mb_segement_abs_delta;
69 0 : vpx_memcpy(mbd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
70 :
71 : /*signed char ref_lf_deltas[MAX_REF_LF_DELTAS];*/
72 0 : vpx_memcpy(mbd->ref_lf_deltas, xd->ref_lf_deltas, sizeof(xd->ref_lf_deltas));
73 : /*signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];*/
74 0 : vpx_memcpy(mbd->mode_lf_deltas, xd->mode_lf_deltas, sizeof(xd->mode_lf_deltas));
75 : /*unsigned char mode_ref_lf_delta_enabled;
76 : unsigned char mode_ref_lf_delta_update;*/
77 0 : mbd->mode_ref_lf_delta_enabled = xd->mode_ref_lf_delta_enabled;
78 0 : mbd->mode_ref_lf_delta_update = xd->mode_ref_lf_delta_update;
79 :
80 0 : mbd->current_bc = &pbi->bc2;
81 :
82 0 : for (j = 0; j < 25; j++)
83 : {
84 0 : mbd->block[j].dequant = xd->block[j].dequant;
85 : }
86 : }
87 :
88 0 : for (i=0; i< pc->mb_rows; i++)
89 0 : pbi->mt_current_mb_col[i]=-1;
90 0 : }
91 :
92 :
93 0 : static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int mb_col)
94 : {
95 0 : int eobtotal = 0;
96 0 : int throw_residual = 0;
97 0 : int i, do_clamp = xd->mode_info_context->mbmi.need_to_clamp_mvs;
98 :
99 0 : if (xd->mode_info_context->mbmi.mb_skip_coeff)
100 : {
101 0 : vp8_reset_mb_tokens_context(xd);
102 : }
103 : else
104 : {
105 0 : eobtotal = vp8_decode_mb_tokens(pbi, xd);
106 : }
107 :
108 : /* Perform temporary clamping of the MV to be used for prediction */
109 0 : if (do_clamp)
110 : {
111 0 : clamp_mvs(xd);
112 : }
113 :
114 0 : eobtotal |= (xd->mode_info_context->mbmi.mode == B_PRED ||
115 0 : xd->mode_info_context->mbmi.mode == SPLITMV);
116 0 : if (!eobtotal && !vp8dx_bool_error(xd->current_bc))
117 : {
118 : /* Special case: Force the loopfilter to skip when eobtotal and
119 : * mb_skip_coeff are zero.
120 : * */
121 0 : xd->mode_info_context->mbmi.mb_skip_coeff = 1;
122 :
123 : /*mt_skip_recon_mb(pbi, xd, mb_row, mb_col);*/
124 0 : if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
125 : {
126 0 : vp8mt_build_intra_predictors_mbuv_s(pbi, xd, mb_row, mb_col);
127 0 : vp8mt_build_intra_predictors_mby_s(pbi, xd, mb_row, mb_col);
128 : }
129 : else
130 : {
131 0 : vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
132 : xd->dst.u_buffer, xd->dst.v_buffer,
133 : xd->dst.y_stride, xd->dst.uv_stride);
134 : }
135 0 : return;
136 : }
137 :
138 0 : if (xd->segmentation_enabled)
139 0 : mb_init_dequantizer(pbi, xd);
140 :
141 : /* do prediction */
142 0 : if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
143 : {
144 0 : vp8mt_build_intra_predictors_mbuv(pbi, xd, mb_row, mb_col);
145 :
146 0 : if (xd->mode_info_context->mbmi.mode != B_PRED)
147 : {
148 0 : vp8mt_build_intra_predictors_mby(pbi, xd, mb_row, mb_col);
149 : } else {
150 0 : vp8mt_intra_prediction_down_copy(pbi, xd, mb_row, mb_col);
151 : }
152 : }
153 : else
154 : {
155 0 : vp8_build_inter_predictors_mb(xd);
156 : }
157 :
158 : /* When we have independent partitions we can apply residual even
159 : * though other partitions within the frame are corrupt.
160 : */
161 0 : throw_residual = (!pbi->independent_partitions &&
162 0 : pbi->frame_corrupt_residual);
163 0 : throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc));
164 :
165 : #if CONFIG_ERROR_CONCEALMENT
166 : if (pbi->ec_active &&
167 : (mb_row * pbi->common.mb_cols + mb_col >= pbi->mvs_corrupt_from_mb ||
168 : throw_residual))
169 : {
170 : /* MB with corrupt residuals or corrupt mode/motion vectors.
171 : * Better to use the predictor as reconstruction.
172 : */
173 : pbi->frame_corrupt_residual = 1;
174 : vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
175 : vp8_conceal_corrupt_mb(xd);
176 : return;
177 : }
178 : #endif
179 :
180 : /* dequantization and idct */
181 0 : if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV)
182 0 : {
183 0 : BLOCKD *b = &xd->block[24];
184 0 : DEQUANT_INVOKE(&pbi->dequant, block)(b);
185 :
186 : /* do 2nd order transform on the dc block */
187 0 : if (xd->eobs[24] > 1)
188 : {
189 0 : IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], b->diff);
190 0 : ((int *)b->qcoeff)[0] = 0;
191 0 : ((int *)b->qcoeff)[1] = 0;
192 0 : ((int *)b->qcoeff)[2] = 0;
193 0 : ((int *)b->qcoeff)[3] = 0;
194 0 : ((int *)b->qcoeff)[4] = 0;
195 0 : ((int *)b->qcoeff)[5] = 0;
196 0 : ((int *)b->qcoeff)[6] = 0;
197 0 : ((int *)b->qcoeff)[7] = 0;
198 : }
199 : else
200 : {
201 0 : IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], b->diff);
202 0 : ((int *)b->qcoeff)[0] = 0;
203 : }
204 :
205 0 : DEQUANT_INVOKE (&pbi->dequant, dc_idct_add_y_block)
206 0 : (xd->qcoeff, xd->block[0].dequant,
207 : xd->predictor, xd->dst.y_buffer,
208 : xd->dst.y_stride, xd->eobs, xd->block[24].diff);
209 : }
210 0 : else if (xd->mode_info_context->mbmi.mode == B_PRED)
211 : {
212 0 : for (i = 0; i < 16; i++)
213 : {
214 0 : BLOCKD *b = &xd->block[i];
215 :
216 0 : vp8mt_predict_intra4x4(pbi, xd, b->bmi.as_mode, b->predictor, mb_row, mb_col, i);
217 :
218 0 : if (xd->eobs[i] > 1)
219 : {
220 0 : DEQUANT_INVOKE(&pbi->dequant, idct_add)
221 0 : (b->qcoeff, b->dequant, b->predictor,
222 0 : *(b->base_dst) + b->dst, 16, b->dst_stride);
223 : }
224 : else
225 : {
226 0 : IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar_add)
227 0 : (b->qcoeff[0] * b->dequant[0], b->predictor,
228 0 : *(b->base_dst) + b->dst, 16, b->dst_stride);
229 0 : ((int *)b->qcoeff)[0] = 0;
230 : }
231 : }
232 : }
233 : else
234 : {
235 0 : DEQUANT_INVOKE (&pbi->dequant, idct_add_y_block)
236 0 : (xd->qcoeff, xd->block[0].dequant,
237 : xd->predictor, xd->dst.y_buffer,
238 : xd->dst.y_stride, xd->eobs);
239 : }
240 :
241 0 : DEQUANT_INVOKE (&pbi->dequant, idct_add_uv_block)
242 0 : (xd->qcoeff+16*16, xd->block[16].dequant,
243 : xd->predictor+16*16, xd->dst.u_buffer, xd->dst.v_buffer,
244 : xd->dst.uv_stride, xd->eobs+16);
245 : }
246 :
247 :
248 0 : static THREAD_FUNCTION thread_decoding_proc(void *p_data)
249 : {
250 0 : int ithread = ((DECODETHREAD_DATA *)p_data)->ithread;
251 0 : VP8D_COMP *pbi = (VP8D_COMP *)(((DECODETHREAD_DATA *)p_data)->ptr1);
252 0 : MB_ROW_DEC *mbrd = (MB_ROW_DEC *)(((DECODETHREAD_DATA *)p_data)->ptr2);
253 : ENTROPY_CONTEXT_PLANES mb_row_left_context;
254 :
255 : while (1)
256 : {
257 0 : if (pbi->b_multithreaded_rd == 0)
258 0 : break;
259 :
260 : /*if(WaitForSingleObject(pbi->h_event_start_decoding[ithread], INFINITE) == WAIT_OBJECT_0)*/
261 0 : if (sem_wait(&pbi->h_event_start_decoding[ithread]) == 0)
262 : {
263 0 : if (pbi->b_multithreaded_rd == 0)
264 0 : break;
265 : else
266 : {
267 0 : VP8_COMMON *pc = &pbi->common;
268 0 : MACROBLOCKD *xd = &mbrd->mbd;
269 :
270 : int mb_row;
271 0 : int num_part = 1 << pbi->common.multi_token_partition;
272 : volatile int *last_row_current_mb_col;
273 0 : int nsync = pbi->sync_range;
274 :
275 0 : for (mb_row = ithread+1; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
276 : {
277 : int i;
278 : int recon_yoffset, recon_uvoffset;
279 : int mb_col;
280 0 : int ref_fb_idx = pc->lst_fb_idx;
281 0 : int dst_fb_idx = pc->new_fb_idx;
282 0 : int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
283 0 : int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
284 :
285 : int filter_level;
286 0 : loop_filter_info_n *lfi_n = &pc->lf_info;
287 :
288 0 : pbi->mb_row_di[ithread].mb_row = mb_row;
289 0 : pbi->mb_row_di[ithread].mbd.current_bc = &pbi->mbc[mb_row%num_part];
290 :
291 0 : last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
292 :
293 0 : recon_yoffset = mb_row * recon_y_stride * 16;
294 0 : recon_uvoffset = mb_row * recon_uv_stride * 8;
295 : /* reset above block coeffs */
296 :
297 0 : xd->above_context = pc->above_context;
298 0 : xd->left_context = &mb_row_left_context;
299 0 : vpx_memset(&mb_row_left_context, 0, sizeof(mb_row_left_context));
300 0 : xd->up_available = (mb_row != 0);
301 :
302 0 : xd->mb_to_top_edge = -((mb_row * 16)) << 3;
303 0 : xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
304 :
305 0 : for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
306 : {
307 0 : if ((mb_col & (nsync-1)) == 0)
308 : {
309 0 : while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != pc->mb_cols - 1)
310 : {
311 0 : x86_pause_hint();
312 0 : thread_sleep(0);
313 : }
314 : }
315 :
316 0 : update_blockd_bmi(xd);
317 :
318 : /* Distance of MB to the various image edges.
319 : * These are specified to 8th pel as they are always
320 : * compared to values that are in 1/8th pel units.
321 : */
322 0 : xd->mb_to_left_edge = -((mb_col * 16) << 3);
323 0 : xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
324 :
325 : #if CONFIG_ERROR_CONCEALMENT
326 : {
327 : int corrupt_residual =
328 : (!pbi->independent_partitions &&
329 : pbi->frame_corrupt_residual) ||
330 : vp8dx_bool_error(xd->current_bc);
331 : if (pbi->ec_active &&
332 : (xd->mode_info_context->mbmi.ref_frame ==
333 : INTRA_FRAME) &&
334 : corrupt_residual)
335 : {
336 : /* We have an intra block with corrupt
337 : * coefficients, better to conceal with an inter
338 : * block.
339 : * Interpolate MVs from neighboring MBs
340 : *
341 : * Note that for the first mb with corrupt
342 : * residual in a frame, we might not discover
343 : * that before decoding the residual. That
344 : * happens after this check, and therefore no
345 : * inter concealment will be done.
346 : */
347 : vp8_interpolate_motion(xd,
348 : mb_row, mb_col,
349 : pc->mb_rows, pc->mb_cols,
350 : pc->mode_info_stride);
351 : }
352 : }
353 : #endif
354 :
355 :
356 0 : xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
357 0 : xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
358 0 : xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
359 :
360 0 : xd->left_available = (mb_col != 0);
361 :
362 : /* Select the appropriate reference frame for this MB */
363 0 : if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
364 0 : ref_fb_idx = pc->lst_fb_idx;
365 0 : else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
366 0 : ref_fb_idx = pc->gld_fb_idx;
367 : else
368 0 : ref_fb_idx = pc->alt_fb_idx;
369 :
370 0 : xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
371 0 : xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
372 0 : xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
373 :
374 0 : if (xd->mode_info_context->mbmi.ref_frame !=
375 : INTRA_FRAME)
376 : {
377 : /* propagate errors from reference frames */
378 0 : xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
379 : }
380 :
381 0 : vp8_build_uvmvs(xd, pc->full_pixel);
382 0 : decode_macroblock(pbi, xd, mb_row, mb_col);
383 :
384 : /* check if the boolean decoder has suffered an error */
385 0 : xd->corrupted |= vp8dx_bool_error(xd->current_bc);
386 :
387 0 : if (pbi->common.filter_level)
388 : {
389 0 : int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
390 0 : xd->mode_info_context->mbmi.mode != SPLITMV &&
391 0 : xd->mode_info_context->mbmi.mb_skip_coeff);
392 :
393 0 : const int mode_index = lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode];
394 0 : const int seg = xd->mode_info_context->mbmi.segment_id;
395 0 : const int ref_frame = xd->mode_info_context->mbmi.ref_frame;
396 :
397 0 : filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
398 :
399 0 : if( mb_row != pc->mb_rows-1 )
400 : {
401 : /* Save decoded MB last row data for next-row decoding */
402 0 : vpx_memcpy((pbi->mt_yabove_row[mb_row + 1] + 32 + mb_col*16), (xd->dst.y_buffer + 15 * recon_y_stride), 16);
403 0 : vpx_memcpy((pbi->mt_uabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
404 0 : vpx_memcpy((pbi->mt_vabove_row[mb_row + 1] + 16 + mb_col*8), (xd->dst.v_buffer + 7 * recon_uv_stride), 8);
405 : }
406 :
407 : /* save left_col for next MB decoding */
408 0 : if(mb_col != pc->mb_cols-1)
409 : {
410 0 : MODE_INFO *next = xd->mode_info_context +1;
411 :
412 0 : if (next->mbmi.ref_frame == INTRA_FRAME)
413 : {
414 0 : for (i = 0; i < 16; i++)
415 0 : pbi->mt_yleft_col[mb_row][i] = xd->dst.y_buffer [i* recon_y_stride + 15];
416 0 : for (i = 0; i < 8; i++)
417 : {
418 0 : pbi->mt_uleft_col[mb_row][i] = xd->dst.u_buffer [i* recon_uv_stride + 7];
419 0 : pbi->mt_vleft_col[mb_row][i] = xd->dst.v_buffer [i* recon_uv_stride + 7];
420 : }
421 : }
422 : }
423 :
424 : /* loopfilter on this macroblock. */
425 0 : if (filter_level)
426 : {
427 0 : if(pc->filter_type == NORMAL_LOOPFILTER)
428 : {
429 : loop_filter_info lfi;
430 0 : FRAME_TYPE frame_type = pc->frame_type;
431 0 : const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
432 0 : lfi.mblim = lfi_n->mblim[filter_level];
433 0 : lfi.blim = lfi_n->blim[filter_level];
434 0 : lfi.lim = lfi_n->lim[filter_level];
435 0 : lfi.hev_thr = lfi_n->hev_thr[hev_index];
436 :
437 0 : if (mb_col > 0)
438 0 : LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_v)
439 0 : (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
440 :
441 0 : if (!skip_lf)
442 0 : LF_INVOKE(&pc->rtcd.loopfilter, normal_b_v)
443 0 : (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
444 :
445 : /* don't apply across umv border */
446 0 : if (mb_row > 0)
447 0 : LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_h)
448 0 : (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
449 :
450 0 : if (!skip_lf)
451 0 : LF_INVOKE(&pc->rtcd.loopfilter, normal_b_h)
452 0 : (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
453 : }
454 : else
455 : {
456 0 : if (mb_col > 0)
457 0 : LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_v)
458 0 : (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
459 :
460 0 : if (!skip_lf)
461 0 : LF_INVOKE(&pc->rtcd.loopfilter, simple_b_v)
462 0 : (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
463 :
464 : /* don't apply across umv border */
465 0 : if (mb_row > 0)
466 0 : LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_h)
467 0 : (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
468 :
469 0 : if (!skip_lf)
470 0 : LF_INVOKE(&pc->rtcd.loopfilter, simple_b_h)
471 0 : (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
472 : }
473 : }
474 :
475 : }
476 :
477 0 : recon_yoffset += 16;
478 0 : recon_uvoffset += 8;
479 :
480 0 : ++xd->mode_info_context; /* next mb */
481 :
482 0 : xd->above_context++;
483 :
484 : /*pbi->mb_row_di[ithread].current_mb_col = mb_col;*/
485 0 : pbi->mt_current_mb_col[mb_row] = mb_col;
486 : }
487 :
488 : /* adjust to the next row of mbs */
489 0 : if (pbi->common.filter_level)
490 : {
491 0 : if(mb_row != pc->mb_rows-1)
492 : {
493 0 : int lasty = pc->yv12_fb[ref_fb_idx].y_width + VP8BORDERINPIXELS;
494 0 : int lastuv = (pc->yv12_fb[ref_fb_idx].y_width>>1) + (VP8BORDERINPIXELS>>1);
495 :
496 0 : for (i = 0; i < 4; i++)
497 : {
498 0 : pbi->mt_yabove_row[mb_row +1][lasty + i] = pbi->mt_yabove_row[mb_row +1][lasty -1];
499 0 : pbi->mt_uabove_row[mb_row +1][lastuv + i] = pbi->mt_uabove_row[mb_row +1][lastuv -1];
500 0 : pbi->mt_vabove_row[mb_row +1][lastuv + i] = pbi->mt_vabove_row[mb_row +1][lastuv -1];
501 : }
502 : }
503 : } else
504 0 : vp8_extend_mb_row(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
505 :
506 0 : ++xd->mode_info_context; /* skip prediction column */
507 :
508 : /* since we have multithread */
509 0 : xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
510 : }
511 : }
512 : }
513 : /* add this to each frame */
514 0 : 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))
515 : {
516 : /*SetEvent(pbi->h_event_end_decoding);*/
517 0 : sem_post(&pbi->h_event_end_decoding);
518 : }
519 0 : }
520 :
521 0 : return 0 ;
522 : }
523 :
524 :
525 0 : void vp8_decoder_create_threads(VP8D_COMP *pbi)
526 : {
527 0 : int core_count = 0;
528 : int ithread;
529 :
530 0 : pbi->b_multithreaded_rd = 0;
531 0 : pbi->allocated_decoding_thread_count = 0;
532 :
533 : /* limit decoding threads to the max number of token partitions */
534 0 : core_count = (pbi->max_threads > 8) ? 8 : pbi->max_threads;
535 :
536 : /* limit decoding threads to the available cores */
537 0 : if (core_count > pbi->common.processor_core_count)
538 0 : core_count = pbi->common.processor_core_count;
539 :
540 0 : if (core_count > 1)
541 : {
542 0 : pbi->b_multithreaded_rd = 1;
543 0 : pbi->decoding_thread_count = core_count - 1;
544 :
545 0 : CHECK_MEM_ERROR(pbi->h_decoding_thread, vpx_malloc(sizeof(pthread_t) * pbi->decoding_thread_count));
546 0 : CHECK_MEM_ERROR(pbi->h_event_start_decoding, vpx_malloc(sizeof(sem_t) * pbi->decoding_thread_count));
547 0 : CHECK_MEM_ERROR(pbi->mb_row_di, vpx_memalign(32, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count));
548 0 : vpx_memset(pbi->mb_row_di, 0, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count);
549 0 : CHECK_MEM_ERROR(pbi->de_thread_data, vpx_malloc(sizeof(DECODETHREAD_DATA) * pbi->decoding_thread_count));
550 :
551 0 : for (ithread = 0; ithread < pbi->decoding_thread_count; ithread++)
552 : {
553 0 : sem_init(&pbi->h_event_start_decoding[ithread], 0, 0);
554 :
555 0 : pbi->de_thread_data[ithread].ithread = ithread;
556 0 : pbi->de_thread_data[ithread].ptr1 = (void *)pbi;
557 0 : pbi->de_thread_data[ithread].ptr2 = (void *) &pbi->mb_row_di[ithread];
558 :
559 0 : pthread_create(&pbi->h_decoding_thread[ithread], 0, thread_decoding_proc, (&pbi->de_thread_data[ithread]));
560 : }
561 :
562 0 : sem_init(&pbi->h_event_end_decoding, 0, 0);
563 :
564 0 : pbi->allocated_decoding_thread_count = pbi->decoding_thread_count;
565 : }
566 0 : }
567 :
568 :
569 0 : void vp8mt_de_alloc_temp_buffers(VP8D_COMP *pbi, int mb_rows)
570 : {
571 : int i;
572 :
573 0 : if (pbi->b_multithreaded_rd)
574 : {
575 0 : vpx_free(pbi->mt_current_mb_col);
576 0 : pbi->mt_current_mb_col = NULL ;
577 :
578 : /* Free above_row buffers. */
579 0 : if (pbi->mt_yabove_row)
580 : {
581 0 : for (i=0; i< mb_rows; i++)
582 : {
583 0 : vpx_free(pbi->mt_yabove_row[i]);
584 0 : pbi->mt_yabove_row[i] = NULL ;
585 : }
586 0 : vpx_free(pbi->mt_yabove_row);
587 0 : pbi->mt_yabove_row = NULL ;
588 : }
589 :
590 0 : if (pbi->mt_uabove_row)
591 : {
592 0 : for (i=0; i< mb_rows; i++)
593 : {
594 0 : vpx_free(pbi->mt_uabove_row[i]);
595 0 : pbi->mt_uabove_row[i] = NULL ;
596 : }
597 0 : vpx_free(pbi->mt_uabove_row);
598 0 : pbi->mt_uabove_row = NULL ;
599 : }
600 :
601 0 : if (pbi->mt_vabove_row)
602 : {
603 0 : for (i=0; i< mb_rows; i++)
604 : {
605 0 : vpx_free(pbi->mt_vabove_row[i]);
606 0 : pbi->mt_vabove_row[i] = NULL ;
607 : }
608 0 : vpx_free(pbi->mt_vabove_row);
609 0 : pbi->mt_vabove_row = NULL ;
610 : }
611 :
612 : /* Free left_col buffers. */
613 0 : if (pbi->mt_yleft_col)
614 : {
615 0 : for (i=0; i< mb_rows; i++)
616 : {
617 0 : vpx_free(pbi->mt_yleft_col[i]);
618 0 : pbi->mt_yleft_col[i] = NULL ;
619 : }
620 0 : vpx_free(pbi->mt_yleft_col);
621 0 : pbi->mt_yleft_col = NULL ;
622 : }
623 :
624 0 : if (pbi->mt_uleft_col)
625 : {
626 0 : for (i=0; i< mb_rows; i++)
627 : {
628 0 : vpx_free(pbi->mt_uleft_col[i]);
629 0 : pbi->mt_uleft_col[i] = NULL ;
630 : }
631 0 : vpx_free(pbi->mt_uleft_col);
632 0 : pbi->mt_uleft_col = NULL ;
633 : }
634 :
635 0 : if (pbi->mt_vleft_col)
636 : {
637 0 : for (i=0; i< mb_rows; i++)
638 : {
639 0 : vpx_free(pbi->mt_vleft_col[i]);
640 0 : pbi->mt_vleft_col[i] = NULL ;
641 : }
642 0 : vpx_free(pbi->mt_vleft_col);
643 0 : pbi->mt_vleft_col = NULL ;
644 : }
645 : }
646 0 : }
647 :
648 :
649 0 : void vp8mt_alloc_temp_buffers(VP8D_COMP *pbi, int width, int prev_mb_rows)
650 : {
651 0 : VP8_COMMON *const pc = & pbi->common;
652 : int i;
653 : int uv_width;
654 :
655 0 : if (pbi->b_multithreaded_rd)
656 : {
657 0 : vp8mt_de_alloc_temp_buffers(pbi, prev_mb_rows);
658 :
659 : /* our internal buffers are always multiples of 16 */
660 0 : if ((width & 0xf) != 0)
661 0 : width += 16 - (width & 0xf);
662 :
663 0 : if (width < 640) pbi->sync_range = 1;
664 0 : else if (width <= 1280) pbi->sync_range = 8;
665 0 : else if (width <= 2560) pbi->sync_range =16;
666 0 : else pbi->sync_range = 32;
667 :
668 0 : uv_width = width >>1;
669 :
670 : /* Allocate an int for each mb row. */
671 0 : CHECK_MEM_ERROR(pbi->mt_current_mb_col, vpx_malloc(sizeof(int) * pc->mb_rows));
672 :
673 : /* Allocate memory for above_row buffers. */
674 0 : CHECK_MEM_ERROR(pbi->mt_yabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
675 0 : for (i=0; i< pc->mb_rows; i++)
676 0 : CHECK_MEM_ERROR(pbi->mt_yabove_row[i], vpx_calloc(sizeof(unsigned char) * (width + (VP8BORDERINPIXELS<<1)), 1));
677 :
678 0 : CHECK_MEM_ERROR(pbi->mt_uabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
679 0 : for (i=0; i< pc->mb_rows; i++)
680 0 : CHECK_MEM_ERROR(pbi->mt_uabove_row[i], vpx_calloc(sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS), 1));
681 :
682 0 : CHECK_MEM_ERROR(pbi->mt_vabove_row, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
683 0 : for (i=0; i< pc->mb_rows; i++)
684 0 : CHECK_MEM_ERROR(pbi->mt_vabove_row[i], vpx_calloc(sizeof(unsigned char) * (uv_width + VP8BORDERINPIXELS), 1));
685 :
686 : /* Allocate memory for left_col buffers. */
687 0 : CHECK_MEM_ERROR(pbi->mt_yleft_col, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
688 0 : for (i=0; i< pc->mb_rows; i++)
689 0 : CHECK_MEM_ERROR(pbi->mt_yleft_col[i], vpx_calloc(sizeof(unsigned char) * 16, 1));
690 :
691 0 : CHECK_MEM_ERROR(pbi->mt_uleft_col, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
692 0 : for (i=0; i< pc->mb_rows; i++)
693 0 : CHECK_MEM_ERROR(pbi->mt_uleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));
694 :
695 0 : CHECK_MEM_ERROR(pbi->mt_vleft_col, vpx_malloc(sizeof(unsigned char *) * pc->mb_rows));
696 0 : for (i=0; i< pc->mb_rows; i++)
697 0 : CHECK_MEM_ERROR(pbi->mt_vleft_col[i], vpx_calloc(sizeof(unsigned char) * 8, 1));
698 : }
699 0 : }
700 :
701 :
702 0 : void vp8_decoder_remove_threads(VP8D_COMP *pbi)
703 : {
704 : /* shutdown MB Decoding thread; */
705 0 : if (pbi->b_multithreaded_rd)
706 : {
707 : int i;
708 :
709 0 : pbi->b_multithreaded_rd = 0;
710 :
711 : /* allow all threads to exit */
712 0 : for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
713 : {
714 0 : sem_post(&pbi->h_event_start_decoding[i]);
715 0 : pthread_join(pbi->h_decoding_thread[i], NULL);
716 : }
717 :
718 0 : for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
719 : {
720 0 : sem_destroy(&pbi->h_event_start_decoding[i]);
721 : }
722 :
723 0 : sem_destroy(&pbi->h_event_end_decoding);
724 :
725 0 : vpx_free(pbi->h_decoding_thread);
726 0 : pbi->h_decoding_thread = NULL;
727 :
728 0 : vpx_free(pbi->h_event_start_decoding);
729 0 : pbi->h_event_start_decoding = NULL;
730 :
731 0 : vpx_free(pbi->mb_row_di);
732 0 : pbi->mb_row_di = NULL ;
733 :
734 0 : vpx_free(pbi->de_thread_data);
735 0 : pbi->de_thread_data = NULL;
736 : }
737 0 : }
738 :
739 0 : void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
740 : {
741 : int mb_row;
742 0 : VP8_COMMON *pc = &pbi->common;
743 :
744 0 : int num_part = 1 << pbi->common.multi_token_partition;
745 : int i;
746 0 : volatile int *last_row_current_mb_col = NULL;
747 0 : int nsync = pbi->sync_range;
748 :
749 0 : int filter_level = pc->filter_level;
750 0 : loop_filter_info_n *lfi_n = &pc->lf_info;
751 :
752 0 : if (filter_level)
753 : {
754 : /* Set above_row buffer to 127 for decoding first MB row */
755 0 : vpx_memset(pbi->mt_yabove_row[0] + VP8BORDERINPIXELS-1, 127, pc->yv12_fb[pc->lst_fb_idx].y_width + 5);
756 0 : vpx_memset(pbi->mt_uabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
757 0 : vpx_memset(pbi->mt_vabove_row[0] + (VP8BORDERINPIXELS>>1)-1, 127, (pc->yv12_fb[pc->lst_fb_idx].y_width>>1) +5);
758 :
759 0 : for (i=1; i<pc->mb_rows; i++)
760 : {
761 0 : vpx_memset(pbi->mt_yabove_row[i] + VP8BORDERINPIXELS-1, (unsigned char)129, 1);
762 0 : vpx_memset(pbi->mt_uabove_row[i] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
763 0 : vpx_memset(pbi->mt_vabove_row[i] + (VP8BORDERINPIXELS>>1)-1, (unsigned char)129, 1);
764 : }
765 :
766 : /* Set left_col to 129 initially */
767 0 : for (i=0; i<pc->mb_rows; i++)
768 : {
769 0 : vpx_memset(pbi->mt_yleft_col[i], (unsigned char)129, 16);
770 0 : vpx_memset(pbi->mt_uleft_col[i], (unsigned char)129, 8);
771 0 : vpx_memset(pbi->mt_vleft_col[i], (unsigned char)129, 8);
772 : }
773 :
774 : /* Initialize the loop filter for this frame. */
775 0 : vp8_loop_filter_frame_init(pc, &pbi->mb, filter_level);
776 : }
777 :
778 0 : setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count);
779 :
780 0 : for (i = 0; i < pbi->decoding_thread_count; i++)
781 0 : sem_post(&pbi->h_event_start_decoding[i]);
782 :
783 0 : for (mb_row = 0; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
784 : {
785 0 : xd->current_bc = &pbi->mbc[mb_row%num_part];
786 :
787 : /* vp8_decode_mb_row(pbi, pc, mb_row, xd); */
788 : {
789 : int i;
790 : int recon_yoffset, recon_uvoffset;
791 : int mb_col;
792 0 : int ref_fb_idx = pc->lst_fb_idx;
793 0 : int dst_fb_idx = pc->new_fb_idx;
794 0 : int recon_y_stride = pc->yv12_fb[ref_fb_idx].y_stride;
795 0 : int recon_uv_stride = pc->yv12_fb[ref_fb_idx].uv_stride;
796 :
797 : /* volatile int *last_row_current_mb_col = NULL; */
798 0 : if (mb_row > 0)
799 0 : last_row_current_mb_col = &pbi->mt_current_mb_col[mb_row -1];
800 :
801 0 : vpx_memset(&pc->left_context, 0, sizeof(pc->left_context));
802 0 : recon_yoffset = mb_row * recon_y_stride * 16;
803 0 : recon_uvoffset = mb_row * recon_uv_stride * 8;
804 : /* reset above block coeffs */
805 :
806 0 : xd->above_context = pc->above_context;
807 0 : xd->up_available = (mb_row != 0);
808 :
809 0 : xd->mb_to_top_edge = -((mb_row * 16)) << 3;
810 0 : xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
811 :
812 0 : for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
813 : {
814 0 : if ( mb_row > 0 && (mb_col & (nsync-1)) == 0){
815 0 : while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != pc->mb_cols - 1)
816 : {
817 0 : x86_pause_hint();
818 0 : thread_sleep(0);
819 : }
820 : }
821 :
822 0 : update_blockd_bmi(xd);
823 :
824 : /* Distance of MB to the various image edges.
825 : * These are specified to 8th pel as they are always compared to
826 : * values that are in 1/8th pel units.
827 : */
828 0 : xd->mb_to_left_edge = -((mb_col * 16) << 3);
829 0 : xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
830 :
831 : #if CONFIG_ERROR_CONCEALMENT
832 : {
833 : int corrupt_residual = (!pbi->independent_partitions &&
834 : pbi->frame_corrupt_residual) ||
835 : vp8dx_bool_error(xd->current_bc);
836 : if (pbi->ec_active &&
837 : (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) &&
838 : corrupt_residual)
839 : {
840 : /* We have an intra block with corrupt coefficients,
841 : * better to conceal with an inter block. Interpolate
842 : * MVs from neighboring MBs
843 : *
844 : * Note that for the first mb with corrupt residual in a
845 : * frame, we might not discover that before decoding the
846 : * residual. That happens after this check, and
847 : * therefore no inter concealment will be done.
848 : */
849 : vp8_interpolate_motion(xd,
850 : mb_row, mb_col,
851 : pc->mb_rows, pc->mb_cols,
852 : pc->mode_info_stride);
853 : }
854 : }
855 : #endif
856 :
857 :
858 0 : xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
859 0 : xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
860 0 : xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
861 :
862 0 : xd->left_available = (mb_col != 0);
863 :
864 : /* Select the appropriate reference frame for this MB */
865 0 : if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)
866 0 : ref_fb_idx = pc->lst_fb_idx;
867 0 : else if (xd->mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
868 0 : ref_fb_idx = pc->gld_fb_idx;
869 : else
870 0 : ref_fb_idx = pc->alt_fb_idx;
871 :
872 0 : xd->pre.y_buffer = pc->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
873 0 : xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
874 0 : xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
875 :
876 0 : if (xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME)
877 : {
878 : /* propagate errors from reference frames */
879 0 : xd->corrupted |= pc->yv12_fb[ref_fb_idx].corrupted;
880 : }
881 :
882 0 : vp8_build_uvmvs(xd, pc->full_pixel);
883 0 : decode_macroblock(pbi, xd, mb_row, mb_col);
884 :
885 : /* check if the boolean decoder has suffered an error */
886 0 : xd->corrupted |= vp8dx_bool_error(xd->current_bc);
887 :
888 0 : if (pbi->common.filter_level)
889 : {
890 0 : int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED &&
891 0 : xd->mode_info_context->mbmi.mode != SPLITMV &&
892 0 : xd->mode_info_context->mbmi.mb_skip_coeff);
893 :
894 0 : const int mode_index = lfi_n->mode_lf_lut[xd->mode_info_context->mbmi.mode];
895 0 : const int seg = xd->mode_info_context->mbmi.segment_id;
896 0 : const int ref_frame = xd->mode_info_context->mbmi.ref_frame;
897 :
898 0 : filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
899 :
900 : /* Save decoded MB last row data for next-row decoding */
901 0 : if(mb_row != pc->mb_rows-1)
902 : {
903 0 : vpx_memcpy((pbi->mt_yabove_row[mb_row +1] + 32 + mb_col*16), (xd->dst.y_buffer + 15 * recon_y_stride), 16);
904 0 : vpx_memcpy((pbi->mt_uabove_row[mb_row +1] + 16 + mb_col*8), (xd->dst.u_buffer + 7 * recon_uv_stride), 8);
905 0 : vpx_memcpy((pbi->mt_vabove_row[mb_row +1] + 16 + mb_col*8), (xd->dst.v_buffer + 7 * recon_uv_stride), 8);
906 : }
907 :
908 : /* save left_col for next MB decoding */
909 0 : if(mb_col != pc->mb_cols-1)
910 : {
911 0 : MODE_INFO *next = xd->mode_info_context +1;
912 :
913 0 : if (next->mbmi.ref_frame == INTRA_FRAME)
914 : {
915 0 : for (i = 0; i < 16; i++)
916 0 : pbi->mt_yleft_col[mb_row][i] = xd->dst.y_buffer [i* recon_y_stride + 15];
917 0 : for (i = 0; i < 8; i++)
918 : {
919 0 : pbi->mt_uleft_col[mb_row][i] = xd->dst.u_buffer [i* recon_uv_stride + 7];
920 0 : pbi->mt_vleft_col[mb_row][i] = xd->dst.v_buffer [i* recon_uv_stride + 7];
921 : }
922 : }
923 : }
924 :
925 : /* loopfilter on this macroblock. */
926 0 : if (filter_level)
927 : {
928 0 : if(pc->filter_type == NORMAL_LOOPFILTER)
929 : {
930 : loop_filter_info lfi;
931 0 : FRAME_TYPE frame_type = pc->frame_type;
932 0 : const int hev_index = lfi_n->hev_thr_lut[frame_type][filter_level];
933 0 : lfi.mblim = lfi_n->mblim[filter_level];
934 0 : lfi.blim = lfi_n->blim[filter_level];
935 0 : lfi.lim = lfi_n->lim[filter_level];
936 0 : lfi.hev_thr = lfi_n->hev_thr[hev_index];
937 :
938 0 : if (mb_col > 0)
939 0 : LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_v)
940 0 : (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
941 :
942 0 : if (!skip_lf)
943 0 : LF_INVOKE(&pc->rtcd.loopfilter, normal_b_v)
944 0 : (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
945 :
946 : /* don't apply across umv border */
947 0 : if (mb_row > 0)
948 0 : LF_INVOKE(&pc->rtcd.loopfilter, normal_mb_h)
949 0 : (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
950 :
951 0 : if (!skip_lf)
952 0 : LF_INVOKE(&pc->rtcd.loopfilter, normal_b_h)
953 0 : (xd->dst.y_buffer, xd->dst.u_buffer, xd->dst.v_buffer, recon_y_stride, recon_uv_stride, &lfi);
954 : }
955 : else
956 : {
957 0 : if (mb_col > 0)
958 0 : LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_v)
959 0 : (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
960 :
961 0 : if (!skip_lf)
962 0 : LF_INVOKE(&pc->rtcd.loopfilter, simple_b_v)
963 0 : (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
964 :
965 : /* don't apply across umv border */
966 0 : if (mb_row > 0)
967 0 : LF_INVOKE(&pc->rtcd.loopfilter, simple_mb_h)
968 0 : (xd->dst.y_buffer, recon_y_stride, lfi_n->mblim[filter_level]);
969 :
970 0 : if (!skip_lf)
971 0 : LF_INVOKE(&pc->rtcd.loopfilter, simple_b_h)
972 0 : (xd->dst.y_buffer, recon_y_stride, lfi_n->blim[filter_level]);
973 : }
974 : }
975 :
976 : }
977 0 : recon_yoffset += 16;
978 0 : recon_uvoffset += 8;
979 :
980 0 : ++xd->mode_info_context; /* next mb */
981 :
982 0 : xd->above_context++;
983 :
984 0 : pbi->mt_current_mb_col[mb_row] = mb_col;
985 : }
986 :
987 : /* adjust to the next row of mbs */
988 0 : if (pbi->common.filter_level)
989 : {
990 0 : if(mb_row != pc->mb_rows-1)
991 : {
992 0 : int lasty = pc->yv12_fb[ref_fb_idx].y_width + VP8BORDERINPIXELS;
993 0 : int lastuv = (pc->yv12_fb[ref_fb_idx].y_width>>1) + (VP8BORDERINPIXELS>>1);
994 :
995 0 : for (i = 0; i < 4; i++)
996 : {
997 0 : pbi->mt_yabove_row[mb_row +1][lasty + i] = pbi->mt_yabove_row[mb_row +1][lasty -1];
998 0 : pbi->mt_uabove_row[mb_row +1][lastuv + i] = pbi->mt_uabove_row[mb_row +1][lastuv -1];
999 0 : pbi->mt_vabove_row[mb_row +1][lastuv + i] = pbi->mt_vabove_row[mb_row +1][lastuv -1];
1000 : }
1001 : }
1002 : }else
1003 0 : vp8_extend_mb_row(&pc->yv12_fb[dst_fb_idx], xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
1004 :
1005 0 : ++xd->mode_info_context; /* skip prediction column */
1006 : }
1007 0 : xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
1008 : }
1009 :
1010 0 : sem_wait(&pbi->h_event_end_decoding); /* add back for each frame */
1011 0 : }
|