Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
d33ee3f2
Commit
d33ee3f2
authored
Nov 29, 2008
by
Kostya Shishkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
RV40 loop filter
Originally committed as revision 15950 to
svn://svn.ffmpeg.org/ffmpeg/trunk
parent
de8cac16
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
238 additions
and
0 deletions
+238
-0
rv40.c
libavcodec/rv40.c
+238
-0
No files found.
libavcodec/rv40.c
View file @
d33ee3f2
...
@@ -389,6 +389,243 @@ static void rv40_h_loop_filter(uint8_t *src, int stride, int dmode,
...
@@ -389,6 +389,243 @@ static void rv40_h_loop_filter(uint8_t *src, int stride, int dmode,
alpha
,
beta
,
beta2
,
chroma
,
edge
);
alpha
,
beta
,
beta2
,
chroma
,
edge
);
}
}
enum
RV40BlockPos
{
POS_CUR
,
POS_TOP
,
POS_LEFT
,
POS_BOTTOM
,
};
#define MASK_CUR 0x0001
#define MASK_RIGHT 0x0008
#define MASK_BOTTOM 0x0010
#define MASK_TOP 0x1000
#define MASK_Y_TOP_ROW 0x000F
#define MASK_Y_LAST_ROW 0xF000
#define MASK_Y_LEFT_COL 0x1111
#define MASK_Y_RIGHT_COL 0x8888
#define MASK_C_TOP_ROW 0x0003
#define MASK_C_LAST_ROW 0x000C
#define MASK_C_LEFT_COL 0x0005
#define MASK_C_RIGHT_COL 0x000A
static
const
int
neighbour_offs_x
[
4
]
=
{
0
,
0
,
-
1
,
0
};
static
const
int
neighbour_offs_y
[
4
]
=
{
0
,
-
1
,
0
,
1
};
/**
* RV40 loop filtering function
*/
static
void
rv40_loop_filter
(
RV34DecContext
*
r
,
int
row
)
{
MpegEncContext
*
s
=
&
r
->
s
;
int
mb_pos
,
mb_x
;
int
i
,
j
,
k
;
uint8_t
*
Y
,
*
C
;
int
alpha
,
beta
,
betaY
,
betaC
;
int
q
;
int
mbtype
[
4
];
///< current macroblock and its neighbours types
/**
* flags indicating that macroblock can be filtered with strong filter
* it is set only for intra coded MB and MB with DCs coded separately
*/
int
mb_strong
[
4
];
int
clip
[
4
];
///< MB filter clipping value calculated from filtering strength
/**
* coded block patterns for luma part of current macroblock and its neighbours
* Format:
* LSB corresponds to the top left block,
* each nibble represents one row of subblocks.
*/
int
cbp
[
4
];
/**
* coded block patterns for chroma part of current macroblock and its neighbours
* Format is the same as for luma with two subblocks in a row.
*/
int
uvcbp
[
4
][
2
];
/**
* This mask represents the pattern of luma subblocks that should be filtered
* in addition to the coded ones because because they lie at the edge of
* 8x8 block with different enough motion vectors
*/
int
mvmasks
[
4
];
mb_pos
=
row
*
s
->
mb_stride
;
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
,
mb_pos
++
){
int
mbtype
=
s
->
current_picture_ptr
->
mb_type
[
mb_pos
];
if
(
IS_INTRA
(
mbtype
)
||
IS_SEPARATE_DC
(
mbtype
))
r
->
cbp_luma
[
mb_pos
]
=
0xFFFF
;
if
(
IS_INTRA
(
mbtype
))
r
->
cbp_chroma
[
mb_pos
]
=
0xFF
;
}
mb_pos
=
row
*
s
->
mb_stride
;
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
,
mb_pos
++
){
int
y_h_deblock
,
y_v_deblock
;
int
c_v_deblock
[
2
],
c_h_deblock
[
2
];
int
clip_left
;
int
avail
[
4
];
int
y_to_deblock
,
c_to_deblock
[
2
];
q
=
s
->
current_picture_ptr
->
qscale_table
[
mb_pos
];
alpha
=
rv40_alpha_tab
[
q
];
beta
=
rv40_beta_tab
[
q
];
betaY
=
betaC
=
beta
*
3
;
if
(
s
->
width
*
s
->
height
<=
176
*
144
)
betaY
+=
beta
;
avail
[
0
]
=
1
;
avail
[
1
]
=
row
;
avail
[
2
]
=
mb_x
;
avail
[
3
]
=
row
<
s
->
mb_height
-
1
;
for
(
i
=
0
;
i
<
4
;
i
++
){
if
(
avail
[
i
]){
int
pos
=
mb_pos
+
neighbour_offs_x
[
i
]
+
neighbour_offs_y
[
i
]
*
s
->
mb_stride
;
mvmasks
[
i
]
=
r
->
deblock_coefs
[
pos
];
mbtype
[
i
]
=
s
->
current_picture_ptr
->
mb_type
[
pos
];
cbp
[
i
]
=
r
->
cbp_luma
[
pos
];
uvcbp
[
i
][
0
]
=
r
->
cbp_chroma
[
pos
]
&
0xF
;
uvcbp
[
i
][
1
]
=
r
->
cbp_chroma
[
pos
]
>>
4
;
}
else
{
mvmasks
[
i
]
=
0
;
mbtype
[
i
]
=
mbtype
[
0
];
cbp
[
i
]
=
0
;
uvcbp
[
i
][
0
]
=
uvcbp
[
i
][
1
]
=
0
;
}
mb_strong
[
i
]
=
IS_INTRA
(
mbtype
[
i
])
||
IS_SEPARATE_DC
(
mbtype
[
i
]);
clip
[
i
]
=
rv40_filter_clip_tbl
[
mb_strong
[
i
]
+
1
][
q
];
}
y_to_deblock
=
cbp
[
POS_CUR
]
|
(
cbp
[
POS_BOTTOM
]
<<
16
)
|
mvmasks
[
POS_CUR
]
|
(
mvmasks
[
POS_BOTTOM
]
<<
16
);
/* This pattern contains bits signalling that horizontal edges of
* the current block can be filtered.
* That happens when either of adjacent subblocks is coded or lies on
* the edge of 8x8 blocks with motion vectors differing by more than
* 3/4 pel in any component (any edge orientation for some reason).
*/
y_h_deblock
=
y_to_deblock
|
((
cbp
[
POS_CUR
]
<<
4
)
&
~
MASK_Y_TOP_ROW
)
|
((
cbp
[
POS_TOP
]
&
MASK_Y_LAST_ROW
)
>>
12
);
/* This pattern contains bits signalling that vertical edges of
* the current block can be filtered.
* That happens when either of adjacent subblocks is coded or lies on
* the edge of 8x8 blocks with motion vectors differing by more than
* 3/4 pel in any component (any edge orientation for some reason).
*/
y_v_deblock
=
y_to_deblock
|
((
cbp
[
POS_CUR
]
<<
1
)
&
~
MASK_Y_LEFT_COL
)
|
((
cbp
[
POS_LEFT
]
&
MASK_Y_RIGHT_COL
)
>>
3
);
if
(
!
mb_x
)
y_v_deblock
&=
~
MASK_Y_LEFT_COL
;
if
(
!
row
)
y_h_deblock
&=
~
MASK_Y_TOP_ROW
;
if
(
row
==
s
->
mb_height
-
1
||
(
mb_strong
[
POS_CUR
]
||
mb_strong
[
POS_BOTTOM
]))
y_h_deblock
&=
~
(
MASK_Y_TOP_ROW
<<
16
);
/* Calculating chroma patterns is similar and easier since there is
* no motion vector pattern for them.
*/
for
(
i
=
0
;
i
<
2
;
i
++
){
c_to_deblock
[
i
]
=
(
uvcbp
[
POS_BOTTOM
][
i
]
<<
4
)
|
uvcbp
[
POS_CUR
][
i
];
c_v_deblock
[
i
]
=
c_to_deblock
[
i
]
|
((
uvcbp
[
POS_CUR
]
[
i
]
<<
1
)
&
~
MASK_C_LEFT_COL
)
|
((
uvcbp
[
POS_LEFT
][
i
]
&
MASK_C_RIGHT_COL
)
>>
1
);
c_h_deblock
[
i
]
=
c_to_deblock
[
i
]
|
((
uvcbp
[
POS_TOP
][
i
]
&
MASK_C_LAST_ROW
)
>>
2
)
|
(
uvcbp
[
POS_CUR
][
i
]
<<
2
);
if
(
!
mb_x
)
c_v_deblock
[
i
]
&=
~
MASK_C_LEFT_COL
;
if
(
!
row
)
c_h_deblock
[
i
]
&=
~
MASK_C_TOP_ROW
;
if
(
row
==
s
->
mb_height
-
1
||
mb_strong
[
POS_CUR
]
||
mb_strong
[
POS_BOTTOM
])
c_h_deblock
[
i
]
&=
~
(
MASK_C_TOP_ROW
<<
4
);
}
for
(
j
=
0
;
j
<
16
;
j
+=
4
){
Y
=
s
->
current_picture_ptr
->
data
[
0
]
+
mb_x
*
16
+
(
row
*
16
+
j
)
*
s
->
linesize
;
for
(
i
=
0
;
i
<
4
;
i
++
,
Y
+=
4
){
int
ij
=
i
+
j
;
int
clip_cur
=
y_to_deblock
&
(
MASK_CUR
<<
ij
)
?
clip
[
POS_CUR
]
:
0
;
int
dither
=
j
?
ij
:
i
*
4
;
// if bottom block is coded then we can filter its top edge
// (or bottom edge of this block, which is the same)
if
(
y_h_deblock
&
(
MASK_BOTTOM
<<
ij
)){
rv40_h_loop_filter
(
Y
+
4
*
s
->
linesize
,
s
->
linesize
,
dither
,
y_to_deblock
&
(
MASK_BOTTOM
<<
ij
)
?
clip
[
POS_CUR
]
:
0
,
clip_cur
,
alpha
,
beta
,
betaY
,
0
,
0
);
}
// filter left block edge in ordinary mode (with low filtering strength)
if
(
y_v_deblock
&
(
MASK_CUR
<<
ij
)
&&
(
i
||
!
(
mb_strong
[
POS_CUR
]
||
mb_strong
[
POS_LEFT
]))){
if
(
!
i
)
clip_left
=
(
cbp
[
POS_LEFT
]
|
mvmasks
[
POS_LEFT
])
&
(
MASK_RIGHT
<<
j
)
?
clip
[
POS_LEFT
]
:
0
;
else
clip_left
=
y_to_deblock
&
(
MASK_CUR
<<
(
ij
-
1
))
?
clip
[
POS_CUR
]
:
0
;
rv40_v_loop_filter
(
Y
,
s
->
linesize
,
dither
,
clip_cur
,
clip_left
,
alpha
,
beta
,
betaY
,
0
,
0
);
}
// filter top edge of the current macroblock when filtering strength is high
if
(
!
j
&&
y_h_deblock
&
(
MASK_CUR
<<
i
)
&&
(
mb_strong
[
POS_CUR
]
||
mb_strong
[
POS_TOP
])){
rv40_h_loop_filter
(
Y
,
s
->
linesize
,
dither
,
clip_cur
,
(
cbp
[
POS_TOP
]
|
mvmasks
[
POS_TOP
])
&
(
MASK_TOP
<<
i
)
?
clip
[
POS_TOP
]
:
0
,
alpha
,
beta
,
betaY
,
0
,
1
);
}
// filter left block edge in edge mode (with high filtering strength)
if
(
y_v_deblock
&
(
MASK_CUR
<<
ij
)
&&
!
i
&&
(
mb_strong
[
POS_CUR
]
||
mb_strong
[
POS_LEFT
])){
clip_left
=
(
cbp
[
POS_LEFT
]
|
mvmasks
[
POS_LEFT
])
&
(
MASK_RIGHT
<<
j
)
?
clip
[
POS_LEFT
]
:
0
;
rv40_v_loop_filter
(
Y
,
s
->
linesize
,
dither
,
clip_cur
,
clip_left
,
alpha
,
beta
,
betaY
,
0
,
1
);
}
}
}
for
(
k
=
0
;
k
<
2
;
k
++
){
for
(
j
=
0
;
j
<
2
;
j
++
){
C
=
s
->
current_picture_ptr
->
data
[
k
+
1
]
+
mb_x
*
8
+
(
row
*
8
+
j
*
4
)
*
s
->
uvlinesize
;
for
(
i
=
0
;
i
<
2
;
i
++
,
C
+=
4
){
int
ij
=
i
+
j
*
2
;
int
clip_cur
=
c_to_deblock
[
k
]
&
(
MASK_CUR
<<
ij
)
?
clip
[
POS_CUR
]
:
0
;
if
(
c_h_deblock
[
k
]
&
(
MASK_CUR
<<
(
ij
+
2
))){
int
clip_bot
=
c_to_deblock
[
k
]
&
(
MASK_CUR
<<
(
ij
+
2
))
?
clip
[
POS_CUR
]
:
0
;
rv40_h_loop_filter
(
C
+
4
*
s
->
uvlinesize
,
s
->
uvlinesize
,
i
*
8
,
clip_bot
,
clip_cur
,
alpha
,
beta
,
betaC
,
1
,
0
);
}
if
((
c_v_deblock
[
k
]
&
(
MASK_CUR
<<
ij
))
&&
(
i
||
!
(
mb_strong
[
POS_CUR
]
||
mb_strong
[
POS_LEFT
]))){
if
(
!
i
)
clip_left
=
uvcbp
[
POS_LEFT
][
k
]
&
(
MASK_CUR
<<
(
2
*
j
+
1
))
?
clip
[
POS_LEFT
]
:
0
;
else
clip_left
=
c_to_deblock
[
k
]
&
(
MASK_CUR
<<
(
ij
-
1
))
?
clip
[
POS_CUR
]
:
0
;
rv40_v_loop_filter
(
C
,
s
->
uvlinesize
,
j
*
8
,
clip_cur
,
clip_left
,
alpha
,
beta
,
betaC
,
1
,
0
);
}
if
(
!
j
&&
c_h_deblock
[
k
]
&
(
MASK_CUR
<<
ij
)
&&
(
mb_strong
[
POS_CUR
]
||
mb_strong
[
POS_TOP
])){
int
clip_top
=
uvcbp
[
POS_TOP
][
k
]
&
(
MASK_CUR
<<
(
ij
+
2
))
?
clip
[
POS_TOP
]
:
0
;
rv40_h_loop_filter
(
C
,
s
->
uvlinesize
,
i
*
8
,
clip_cur
,
clip_top
,
alpha
,
beta
,
betaC
,
1
,
1
);
}
if
(
c_v_deblock
[
k
]
&
(
MASK_CUR
<<
ij
)
&&
!
i
&&
(
mb_strong
[
POS_CUR
]
||
mb_strong
[
POS_LEFT
])){
clip_left
=
uvcbp
[
POS_LEFT
][
k
]
&
(
MASK_CUR
<<
(
2
*
j
+
1
))
?
clip
[
POS_LEFT
]
:
0
;
rv40_v_loop_filter
(
C
,
s
->
uvlinesize
,
j
*
8
,
clip_cur
,
clip_left
,
alpha
,
beta
,
betaC
,
1
,
1
);
}
}
}
}
}
}
/**
/**
* Initialize decoder.
* Initialize decoder.
*/
*/
...
@@ -403,6 +640,7 @@ static av_cold int rv40_decode_init(AVCodecContext *avctx)
...
@@ -403,6 +640,7 @@ static av_cold int rv40_decode_init(AVCodecContext *avctx)
r
->
parse_slice_header
=
rv40_parse_slice_header
;
r
->
parse_slice_header
=
rv40_parse_slice_header
;
r
->
decode_intra_types
=
rv40_decode_intra_types
;
r
->
decode_intra_types
=
rv40_decode_intra_types
;
r
->
decode_mb_info
=
rv40_decode_mb_info
;
r
->
decode_mb_info
=
rv40_decode_mb_info
;
r
->
loop_filter
=
rv40_loop_filter
;
r
->
luma_dc_quant_i
=
rv40_luma_dc_quant
[
0
];
r
->
luma_dc_quant_i
=
rv40_luma_dc_quant
[
0
];
r
->
luma_dc_quant_p
=
rv40_luma_dc_quant
[
1
];
r
->
luma_dc_quant_p
=
rv40_luma_dc_quant
[
1
];
return
0
;
return
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment