274
#define CLIP_SYMM(a, b) av_clip(a, -(b), b)
276
* weaker deblocking very similar to the one described in 4.4.2 of JVT-A003r1
278
static inline void rv40_weak_loop_filter(uint8_t *src, const int step,
279
const int filter_p1, const int filter_q1,
280
const int alpha, const int beta,
282
const int lim_q1, const int lim_p1,
283
const int diff_p1p0, const int diff_q1q0,
284
const int diff_p1p2, const int diff_q1q2)
286
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
289
t = src[0*step] - src[-1*step];
292
u = (alpha * FFABS(t)) >> 7;
293
if(u > 3 - (filter_p1 && filter_q1))
297
if(filter_p1 && filter_q1)
298
t += src[-2*step] - src[1*step];
299
diff = CLIP_SYMM((t + 4) >> 3, lim_p0q0);
300
src[-1*step] = cm[src[-1*step] + diff];
301
src[ 0*step] = cm[src[ 0*step] - diff];
302
if(FFABS(diff_p1p2) <= beta && filter_p1){
303
t = (diff_p1p0 + diff_p1p2 - diff) >> 1;
304
src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim_p1)];
306
if(FFABS(diff_q1q2) <= beta && filter_q1){
307
t = (diff_q1q0 + diff_q1q2 + diff) >> 1;
308
src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim_q1)];
312
static av_always_inline void rv40_adaptive_loop_filter(uint8_t *src, const int step,
313
const int stride, const int dmode,
314
const int lim_q1, const int lim_p1,
316
const int beta, const int beta2,
317
const int chroma, const int edge)
319
int diff_p1p0[4], diff_q1q0[4], diff_p1p2[4], diff_q1q2[4];
320
int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0;
322
int flag_strong0 = 1, flag_strong1 = 1;
323
int filter_p1, filter_q1;
327
for(i = 0, ptr = src; i < 4; i++, ptr += stride){
328
diff_p1p0[i] = ptr[-2*step] - ptr[-1*step];
329
diff_q1q0[i] = ptr[ 1*step] - ptr[ 0*step];
330
sum_p1p0 += diff_p1p0[i];
331
sum_q1q0 += diff_q1q0[i];
333
filter_p1 = FFABS(sum_p1p0) < (beta<<2);
334
filter_q1 = FFABS(sum_q1q0) < (beta<<2);
335
if(!filter_p1 && !filter_q1)
338
for(i = 0, ptr = src; i < 4; i++, ptr += stride){
339
diff_p1p2[i] = ptr[-2*step] - ptr[-3*step];
340
diff_q1q2[i] = ptr[ 1*step] - ptr[ 2*step];
341
sum_p1p2 += diff_p1p2[i];
342
sum_q1q2 += diff_q1q2[i];
346
flag_strong0 = filter_p1 && (FFABS(sum_p1p2) < beta2);
347
flag_strong1 = filter_q1 && (FFABS(sum_q1q2) < beta2);
349
flag_strong0 = flag_strong1 = 0;
352
lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1;
353
if(flag_strong0 && flag_strong1){ /* strong filtering */
354
for(i = 0; i < 4; i++, src += stride){
355
int sflag, p0, q0, p1, q1;
356
int t = src[0*step] - src[-1*step];
359
sflag = (alpha * FFABS(t)) >> 7;
360
if(sflag > 1) continue;
362
p0 = (25*src[-3*step] + 26*src[-2*step]
364
+ 26*src[ 0*step] + 25*src[ 1*step] + rv40_dither_l[dmode + i]) >> 7;
365
q0 = (25*src[-2*step] + 26*src[-1*step]
367
+ 26*src[ 1*step] + 25*src[ 2*step] + rv40_dither_r[dmode + i]) >> 7;
369
p0 = av_clip(p0, src[-1*step] - lims, src[-1*step] + lims);
370
q0 = av_clip(q0, src[ 0*step] - lims, src[ 0*step] + lims);
372
p1 = (25*src[-4*step] + 26*src[-3*step]
374
+ 26*p0 + 25*src[ 0*step] + rv40_dither_l[dmode + i]) >> 7;
375
q1 = (25*src[-1*step] + 26*q0
377
+ 26*src[ 2*step] + 25*src[ 3*step] + rv40_dither_r[dmode + i]) >> 7;
379
p1 = av_clip(p1, src[-2*step] - lims, src[-2*step] + lims);
380
q1 = av_clip(q1, src[ 1*step] - lims, src[ 1*step] + lims);
387
src[-3*step] = (25*src[-1*step] + 26*src[-2*step] + 51*src[-3*step] + 26*src[-4*step] + 64) >> 7;
388
src[ 2*step] = (25*src[ 0*step] + 26*src[ 1*step] + 51*src[ 2*step] + 26*src[ 3*step] + 64) >> 7;
391
}else if(filter_p1 && filter_q1){
392
for(i = 0; i < 4; i++, src += stride)
393
rv40_weak_loop_filter(src, step, 1, 1, alpha, beta, lims, lim_q1, lim_p1,
394
diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]);
396
for(i = 0; i < 4; i++, src += stride)
397
rv40_weak_loop_filter(src, step, filter_p1, filter_q1,
398
alpha, beta, lims>>1, lim_q1>>1, lim_p1>>1,
399
diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]);
403
static void rv40_v_loop_filter(uint8_t *src, int stride, int dmode,
404
int lim_q1, int lim_p1,
405
int alpha, int beta, int beta2, int chroma, int edge){
406
rv40_adaptive_loop_filter(src, 1, stride, dmode, lim_q1, lim_p1,
407
alpha, beta, beta2, chroma, edge);
409
static void rv40_h_loop_filter(uint8_t *src, int stride, int dmode,
410
int lim_q1, int lim_p1,
411
int alpha, int beta, int beta2, int chroma, int edge){
412
rv40_adaptive_loop_filter(src, stride, 1, dmode, lim_q1, lim_p1,
413
alpha, beta, beta2, chroma, edge);
416
274
enum RV40BlockPos{
436
294
static const int neighbour_offs_x[4] = { 0, 0, -1, 0 };
437
295
static const int neighbour_offs_y[4] = { 0, -1, 0, 1 };
297
static void rv40_adaptive_loop_filter(RV34DSPContext *rdsp,
298
uint8_t *src, int stride, int dmode,
299
int lim_q1, int lim_p1,
300
int alpha, int beta, int beta2,
301
int chroma, int edge, int dir)
303
int filter_p1, filter_q1;
307
strong = rdsp->rv40_loop_filter_strength[dir](src, stride, beta, beta2,
308
edge, &filter_p1, &filter_q1);
310
lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1;
313
rdsp->rv40_strong_loop_filter[dir](src, stride, alpha,
314
lims, dmode, chroma);
315
} else if (filter_p1 & filter_q1) {
316
rdsp->rv40_weak_loop_filter[dir](src, stride, 1, 1, alpha, beta,
317
lims, lim_q1, lim_p1);
318
} else if (filter_p1 | filter_q1) {
319
rdsp->rv40_weak_loop_filter[dir](src, stride, filter_p1, filter_q1,
320
alpha, beta, lims >> 1, lim_q1 >> 1,
440
326
* RV40 loop filtering function
583
470
clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;
585
472
clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;
586
rv40_v_loop_filter(Y, s->linesize, dither,
589
alpha, beta, betaY, 0, 0);
473
rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
476
alpha, beta, betaY, 0, 0, 1);
591
478
// filter top edge of the current macroblock when filtering strength is high
592
479
if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){
593
rv40_h_loop_filter(Y, s->linesize, dither,
480
rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
595
482
mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0,
596
alpha, beta, betaY, 0, 1);
483
alpha, beta, betaY, 0, 1, 0);
598
485
// filter left block edge in edge mode (with high filtering strength)
599
486
if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){
600
487
clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;
601
rv40_v_loop_filter(Y, s->linesize, dither,
488
rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
604
alpha, beta, betaY, 0, 1);
491
alpha, beta, betaY, 0, 1, 1);
608
495
for(k = 0; k < 2; k++){
609
496
for(j = 0; j < 2; j++){
610
C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize;
497
C = s->current_picture_ptr->f.data[k + 1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize;
611
498
for(i = 0; i < 2; i++, C += 4){
612
499
int ij = i + j*2;
613
500
int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0;
614
501
if(c_h_deblock[k] & (MASK_CUR << (ij+2))){
615
502
int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0;
616
rv40_h_loop_filter(C+4*s->uvlinesize, s->uvlinesize, i*8,
503
rv40_adaptive_loop_filter(&r->rdsp, C+4*s->uvlinesize, s->uvlinesize, i*8,
619
alpha, beta, betaC, 1, 0);
506
alpha, beta, betaC, 1, 0, 0);
621
508
if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){
623
510
clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;
625
512
clip_left = c_to_deblock[k] & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;
626
rv40_v_loop_filter(C, s->uvlinesize, j*8,
513
rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8,
629
alpha, beta, betaC, 1, 0);
516
alpha, beta, betaC, 1, 0, 1);
631
518
if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){
632
519
int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0;
633
rv40_h_loop_filter(C, s->uvlinesize, i*8,
520
rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, i*8,
636
alpha, beta, betaC, 1, 1);
523
alpha, beta, betaC, 1, 1, 0);
638
525
if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){
639
526
clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;
640
rv40_v_loop_filter(C, s->uvlinesize, j*8,
527
rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8,
643
alpha, beta, betaC, 1, 1);
530
alpha, beta, betaC, 1, 1, 1);