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
2ade1cda
Commit
2ade1cda
authored
Feb 24, 2016
by
Vittorio Giovara
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
intrax8: K&R formatting cosmetics
parent
6f5ff559
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1792 additions
and
1653 deletions
+1792
-1653
intrax8.c
libavcodec/intrax8.c
+540
-480
intrax8.h
libavcodec/intrax8.h
+16
-12
intrax8dsp.c
libavcodec/intrax8dsp.c
+316
-284
intrax8dsp.h
libavcodec/intrax8dsp.h
+2
-2
intrax8huf.h
libavcodec/intrax8huf.h
+918
-875
No files found.
libavcodec/intrax8.c
View file @
2ade1cda
...
...
@@ -30,7 +30,8 @@
#include "intrax8.h"
#include "intrax8dsp.h"
#define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits)
#define MAX_TABLE_DEPTH(table_bits, max_bits) \
((max_bits + table_bits - 1) / table_bits)
#define DC_VLC_BITS 9
#define AC_VLC_BITS 9
...
...
@@ -40,15 +41,16 @@
#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
static
VLC
j_ac_vlc
[
2
][
2
][
8
];
//
[quant<13],[intra/inter],
[select]
static
VLC
j_dc_vlc
[
2
][
8
];
//[quant], [select]
static
VLC
j_orient_vlc
[
2
][
4
];
//[quant], [select]
static
VLC
j_ac_vlc
[
2
][
2
][
8
];
//
[quant < 13], [intra / inter],
[select]
static
VLC
j_dc_vlc
[
2
][
8
];
//
[quant], [select]
static
VLC
j_orient_vlc
[
2
][
4
];
//
[quant], [select]
static
av_cold
void
x8_vlc_init
(
void
){
static
av_cold
void
x8_vlc_init
(
void
)
{
int
i
;
int
offset
=
0
;
int
sizeidx
=
0
;
static
const
uint16_t
sizes
[
8
*
4
+
8
*
2
+
2
+
4
]
=
{
static
const
uint16_t
sizes
[
8
*
4
+
8
*
2
+
2
+
4
]
=
{
576
,
548
,
582
,
618
,
546
,
616
,
560
,
642
,
584
,
582
,
704
,
664
,
512
,
544
,
656
,
640
,
512
,
648
,
582
,
566
,
532
,
614
,
596
,
648
,
...
...
@@ -57,95 +59,97 @@ static av_cold void x8_vlc_init(void){
528
,
528
,
526
,
528
,
536
,
528
,
526
,
544
,
544
,
512
,
512
,
528
,
528
,
544
,
512
,
544
,
128
,
128
,
128
,
128
,
128
,
128
};
128
,
128
,
128
,
128
,
128
,
128
,
};
static
VLC_TYPE
table
[
28150
][
2
];
#define init_ac_vlc(dst,src) do { \
// set ac tables
#define init_ac_vlc(dst, src) \
do { \
dst.table = &table[offset]; \
dst.table_allocated = sizes[sizeidx]; \
offset += sizes[sizeidx++]; \
init_vlc(&dst, \
AC_VLC_BITS,77, \
&src[1],4,2, \
&src[0],4,2, \
init_vlc(&dst, AC_VLC_BITS, 77, &src[1], 4, 2, &src[0], 4, 2, \
INIT_VLC_USE_NEW_STATIC); \
} while(0)
//set ac tables
for
(
i
=
0
;
i
<
8
;
i
++
)
{
init_ac_vlc
(
j_ac_vlc
[
0
][
0
][
i
],
x8_ac0_highquant_table
[
i
][
0
]
);
init_ac_vlc
(
j_ac_vlc
[
0
][
1
][
i
],
x8_ac1_highquant_table
[
i
][
0
]
);
init_ac_vlc
(
j_ac_vlc
[
1
][
0
][
i
],
x8_ac0_lowquant_table
[
i
][
0
]
);
init_ac_vlc
(
j_ac_vlc
[
1
][
1
][
i
],
x8_ac1_lowquant_table
[
i
][
0
]
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
init_ac_vlc
(
j_ac_vlc
[
0
][
0
][
i
],
x8_ac0_highquant_table
[
i
][
0
]
);
init_ac_vlc
(
j_ac_vlc
[
0
][
1
][
i
],
x8_ac1_highquant_table
[
i
][
0
]
);
init_ac_vlc
(
j_ac_vlc
[
1
][
0
][
i
],
x8_ac0_lowquant_table
[
i
][
0
]
);
init_ac_vlc
(
j_ac_vlc
[
1
][
1
][
i
],
x8_ac1_lowquant_table
[
i
][
0
]
);
}
#undef init_ac_vlc
//set dc tables
#define init_dc_vlc(dst,src) do { \
// set dc tables
#define init_dc_vlc(dst, src) \
do { \
dst.table = &table[offset]; \
dst.table_allocated = sizes[sizeidx]; \
offset += sizes[sizeidx++]; \
init_vlc(&dst, \
DC_VLC_BITS,34, \
&src[1],4,2, \
&src[0],4,2, \
init_vlc(&dst, DC_VLC_BITS, 34, &src[1], 4, 2, &src[0], 4, 2, \
INIT_VLC_USE_NEW_STATIC); \
} while(0)
for
(
i
=
0
;
i
<
8
;
i
++
){
init_dc_vlc
(
j_dc_vlc
[
0
][
i
],
x8_dc_highquant_table
[
i
][
0
]);
init_dc_vlc
(
j_dc_vlc
[
1
][
i
],
x8_dc_lowquant_table
[
i
][
0
]);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
init_dc_vlc
(
j_dc_vlc
[
0
][
i
],
x8_dc_highquant_table
[
i
][
0
]);
init_dc_vlc
(
j_dc_vlc
[
1
][
i
],
x8_dc_lowquant_table
[
i
][
0
]);
}
#undef init_dc_vlc
//set orient tables
#define init_or_vlc(dst,src) do { \
// set orient tables
#define init_or_vlc(dst, src) \
do { \
dst.table = &table[offset]; \
dst.table_allocated = sizes[sizeidx]; \
offset += sizes[sizeidx++]; \
init_vlc(&dst, \
OR_VLC_BITS,12, \
&src[1],4,2, \
&src[0],4,2, \
init_vlc(&dst, OR_VLC_BITS, 12, &src[1], 4, 2, &src[0], 4, 2, \
INIT_VLC_USE_NEW_STATIC); \
} while(0)
for
(
i
=
0
;
i
<
2
;
i
++
){
init_or_vlc
(
j_orient_vlc
[
0
][
i
],
x8_orient_highquant_table
[
i
][
0
]);
}
for
(
i
=
0
;
i
<
4
;
i
++
){
init_or_vlc
(
j_orient_vlc
[
1
][
i
],
x8_orient_lowquant_table
[
i
][
0
]);
}
for
(
i
=
0
;
i
<
2
;
i
++
)
init_or_vlc
(
j_orient_vlc
[
0
][
i
],
x8_orient_highquant_table
[
i
][
0
]);
for
(
i
=
0
;
i
<
4
;
i
++
)
init_or_vlc
(
j_orient_vlc
[
1
][
i
],
x8_orient_lowquant_table
[
i
][
0
]);
#undef init_or_vlc
if
(
offset
!=
sizeof
(
table
)
/
sizeof
(
VLC_TYPE
)
/
2
)
av_log
(
NULL
,
AV_LOG_ERROR
,
"table size %zd does not match needed %i
\n
"
,
sizeof
(
table
)
/
sizeof
(
VLC_TYPE
)
/
2
,
offset
);
}
#undef init_or_vlc
static
void
x8_reset_vlc_tables
(
IntraX8Context
*
w
){
memset
(
w
->
j_dc_vlc
,
0
,
sizeof
(
w
->
j_dc_vlc
));
memset
(
w
->
j_ac_vlc
,
0
,
sizeof
(
w
->
j_ac_vlc
));
w
->
j_orient_vlc
=
NULL
;
static
void
x8_reset_vlc_tables
(
IntraX8Context
*
w
)
{
memset
(
w
->
j_dc_vlc
,
0
,
sizeof
(
w
->
j_dc_vlc
));
memset
(
w
->
j_ac_vlc
,
0
,
sizeof
(
w
->
j_ac_vlc
));
w
->
j_orient_vlc
=
NULL
;
}
static
inline
void
x8_select_ac_table
(
IntraX8Context
*
const
w
,
int
mode
){
MpegEncContext
*
const
s
=
w
->
s
;
static
inline
void
x8_select_ac_table
(
IntraX8Context
*
const
w
,
int
mode
)
{
MpegEncContext
*
const
s
=
w
->
s
;
int
table_index
;
assert
(
mode
<
4
);
assert
(
mode
<
4
);
if
(
w
->
j_ac_vlc
[
mode
]
)
return
;
if
(
w
->
j_ac_vlc
[
mode
])
return
;
table_index
=
get_bits
(
&
s
->
gb
,
3
);
w
->
j_ac_vlc
[
mode
]
=
&
j_ac_vlc
[
w
->
quant
<
13
][
mode
>>
1
][
table_index
];
//2 modes use same tables
// 2 modes use same tables
w
->
j_ac_vlc
[
mode
]
=
&
j_ac_vlc
[
w
->
quant
<
13
][
mode
>>
1
][
table_index
];
assert
(
w
->
j_ac_vlc
[
mode
]);
}
static
inline
int
x8_get_orient_vlc
(
IntraX8Context
*
w
){
MpegEncContext
*
const
s
=
w
->
s
;
int
table_index
;
static
inline
int
x8_get_orient_vlc
(
IntraX8Context
*
w
)
{
MpegEncContext
*
const
s
=
w
->
s
;
if
(
!
w
->
j_orient_vlc
)
{
table_index
=
get_bits
(
&
s
->
gb
,
1
+
(
w
->
quant
<
13
)
);
w
->
j_orient_vlc
=
&
j_orient_vlc
[
w
->
quant
<
13
][
table_index
];
if
(
!
w
->
j_orient_vlc
)
{
int
table_index
=
get_bits
(
&
s
->
gb
,
1
+
(
w
->
quant
<
13
)
);
w
->
j_orient_vlc
=
&
j_orient_vlc
[
w
->
quant
<
13
][
table_index
];
}
assert
(
w
->
j_orient_vlc
);
assert
(
w
->
j_orient_vlc
->
table
);
...
...
@@ -158,41 +162,41 @@ static inline int x8_get_orient_vlc(IntraX8Context * w){
#define extra_level (0x00 << 8) // 1 bit
#define run_offset(r) ((r) << 16) // 6 bits
#define level_offset(l) ((l) << 24) // 5 bits
static
const
uint32_t
ac_decode_table
[]
=
{
/*
46*/
extra_bits
(
3
)
|
extra_run
|
run_offset
(
16
)
|
level_offset
(
0
),
/*
47*/
extra_bits
(
3
)
|
extra_run
|
run_offset
(
24
)
|
level_offset
(
0
),
/*
48*/
extra_bits
(
2
)
|
extra_run
|
run_offset
(
4
)
|
level_offset
(
1
),
/*
49*/
extra_bits
(
3
)
|
extra_run
|
run_offset
(
8
)
|
level_offset
(
1
),
/*
50*/
extra_bits
(
5
)
|
extra_run
|
run_offset
(
32
)
|
level_offset
(
0
),
/*
51*/
extra_bits
(
4
)
|
extra_run
|
run_offset
(
16
)
|
level_offset
(
1
),
/*
52*/
extra_bits
(
2
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
4
),
/*
53*/
extra_bits
(
2
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
8
),
/*
54*/
extra_bits
(
2
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
12
),
/*
55*/
extra_bits
(
3
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
16
),
/*
56*/
extra_bits
(
3
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
24
),
/*
57*/
extra_bits
(
2
)
|
extra_level
|
run_offset
(
1
)
|
level_offset
(
3
),
/*
58*/
extra_bits
(
3
)
|
extra_level
|
run_offset
(
1
)
|
level_offset
(
7
),
/*
59*/
extra_bits
(
2
)
|
extra_run
|
run_offset
(
16
)
|
level_offset
(
0
),
/*
60*/
extra_bits
(
2
)
|
extra_run
|
run_offset
(
20
)
|
level_offset
(
0
),
/*
61*/
extra_bits
(
2
)
|
extra_run
|
run_offset
(
24
)
|
level_offset
(
0
),
/*
62*/
extra_bits
(
2
)
|
extra_run
|
run_offset
(
28
)
|
level_offset
(
0
),
/*
63*/
extra_bits
(
4
)
|
extra_run
|
run_offset
(
32
)
|
level_offset
(
0
),
/*
64*/
extra_bits
(
4
)
|
extra_run
|
run_offset
(
48
)
|
level_offset
(
0
),
/*
65*/
extra_bits
(
2
)
|
extra_run
|
run_offset
(
4
)
|
level_offset
(
1
),
/*
66*/
extra_bits
(
3
)
|
extra_run
|
run_offset
(
8
)
|
level_offset
(
1
),
/*
67*/
extra_bits
(
4
)
|
extra_run
|
run_offset
(
16
)
|
level_offset
(
1
),
/*
68*/
extra_bits
(
2
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
4
),
/*
69*/
extra_bits
(
3
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
8
),
/*
70*/
extra_bits
(
4
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
16
),
/*
71*/
extra_bits
(
2
)
|
extra_level
|
run_offset
(
1
)
|
level_offset
(
3
),
/*
72*/
extra_bits
(
3
)
|
extra_level
|
run_offset
(
1
)
|
level_offset
(
7
),
static
const
uint32_t
ac_decode_table
[]
=
{
/*
46 */
extra_bits
(
3
)
|
extra_run
|
run_offset
(
16
)
|
level_offset
(
0
),
/*
47 */
extra_bits
(
3
)
|
extra_run
|
run_offset
(
24
)
|
level_offset
(
0
),
/*
48 */
extra_bits
(
2
)
|
extra_run
|
run_offset
(
4
)
|
level_offset
(
1
),
/*
49 */
extra_bits
(
3
)
|
extra_run
|
run_offset
(
8
)
|
level_offset
(
1
),
/*
50 */
extra_bits
(
5
)
|
extra_run
|
run_offset
(
32
)
|
level_offset
(
0
),
/*
51 */
extra_bits
(
4
)
|
extra_run
|
run_offset
(
16
)
|
level_offset
(
1
),
/*
52 */
extra_bits
(
2
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
4
),
/*
53 */
extra_bits
(
2
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
8
),
/*
54 */
extra_bits
(
2
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
12
),
/*
55 */
extra_bits
(
3
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
16
),
/*
56 */
extra_bits
(
3
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
24
),
/*
57 */
extra_bits
(
2
)
|
extra_level
|
run_offset
(
1
)
|
level_offset
(
3
),
/*
58 */
extra_bits
(
3
)
|
extra_level
|
run_offset
(
1
)
|
level_offset
(
7
),
/*
59 */
extra_bits
(
2
)
|
extra_run
|
run_offset
(
16
)
|
level_offset
(
0
),
/*
60 */
extra_bits
(
2
)
|
extra_run
|
run_offset
(
20
)
|
level_offset
(
0
),
/*
61 */
extra_bits
(
2
)
|
extra_run
|
run_offset
(
24
)
|
level_offset
(
0
),
/*
62 */
extra_bits
(
2
)
|
extra_run
|
run_offset
(
28
)
|
level_offset
(
0
),
/*
63 */
extra_bits
(
4
)
|
extra_run
|
run_offset
(
32
)
|
level_offset
(
0
),
/*
64 */
extra_bits
(
4
)
|
extra_run
|
run_offset
(
48
)
|
level_offset
(
0
),
/*
65 */
extra_bits
(
2
)
|
extra_run
|
run_offset
(
4
)
|
level_offset
(
1
),
/*
66 */
extra_bits
(
3
)
|
extra_run
|
run_offset
(
8
)
|
level_offset
(
1
),
/*
67 */
extra_bits
(
4
)
|
extra_run
|
run_offset
(
16
)
|
level_offset
(
1
),
/*
68 */
extra_bits
(
2
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
4
),
/*
69 */
extra_bits
(
3
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
8
),
/*
70 */
extra_bits
(
4
)
|
extra_level
|
run_offset
(
0
)
|
level_offset
(
16
),
/*
71 */
extra_bits
(
2
)
|
extra_level
|
run_offset
(
1
)
|
level_offset
(
3
),
/*
72 */
extra_bits
(
3
)
|
extra_level
|
run_offset
(
1
)
|
level_offset
(
7
),
};
#undef extra_bits
#undef extra_run
...
...
@@ -200,203 +204,235 @@ static const uint32_t ac_decode_table[]={
#undef run_offset
#undef level_offset
static
void
x8_get_ac_rlf
(
IntraX8Context
*
const
w
,
const
int
mode
,
int
*
const
run
,
int
*
const
level
,
int
*
const
final
){
MpegEncContext
*
const
s
=
w
->
s
;
int
i
,
e
;
static
void
x8_get_ac_rlf
(
IntraX8Context
*
const
w
,
const
int
mode
,
int
*
const
run
,
int
*
const
level
,
int
*
const
final
)
{
MpegEncContext
*
const
s
=
w
->
s
;
int
i
,
e
;
// x8_select_ac_table(w,mode);
// x8_select_ac_table(w,
mode);
i
=
get_vlc2
(
&
s
->
gb
,
w
->
j_ac_vlc
[
mode
]
->
table
,
AC_VLC_BITS
,
AC_VLC_MTD
);
if
(
i
<
46
){
//[0-45]
int
t
,
l
;
if
(
i
<
0
){
(
*
level
)
=
(
*
final
)
=
//prevent 'may be used unilitialized'
(
*
run
)
=
64
;
//this would cause error exit in the ac loop
if
(
i
<
46
)
{
// [0-45]
int
t
,
l
;
if
(
i
<
0
)
{
(
*
level
)
=
(
*
final
)
=
// prevent 'may be used unilitialized'
(
*
run
)
=
64
;
// this would cause error exit in the ac loop
return
;
}
(
*
final
)
=
t
=
(
i
>
22
);
i
-=
23
*
t
;
/*
i== 0-15 r=0-15 l=0 ;r=i& %01111
i==16-19 r=0-3 l=1 ;r=i& %00011
i==20-21 r=0-1 l=2 ;r=i& %00001
i==22 r=0 l=3 ;r=i& %00000
l=lut_l[i/2]={0,0,0,0,0,0,0,0,1,1,2,3}[i>>1];// 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000
t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */
l
=
(
0xE50000
>>
(
i
&
(
0x1E
)))
&
3
;
/*0x1E or (~1) or ((i>>1)<<1)*/
t
=
(
0x01030F
>>
(
l
<<
3
));
(
*
run
)
=
i
&
t
;
/*
* i == 0-15 r = 0-15 l = 0; r = i & %01111
* i == 16-19 r = 0-3 l = 1; r = i & %00011
* i == 20-21 r = 0-1 l = 2; r = i & %00001
* i == 22 r = 0 l = 3; r = i & %00000
*/
(
*
final
)
=
t
=
(
i
>
22
);
i
-=
23
*
t
;
/* l = lut_l[i / 2] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3 }[i >> 1];
* 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 */
l
=
(
0xE50000
>>
(
i
&
(
0x1E
)))
&
3
;
// 0x1E or (~1) or ((i >> 1) << 1)
/* t = lut_mask[l] = { 0x0f, 0x03, 0x01, 0x00 }[l];
* as i < 256 the higher bits do not matter */
t
=
(
0x01030F
>>
(
l
<<
3
));
(
*
run
)
=
i
&
t
;
(
*
level
)
=
l
;
}
else
if
(
i
<
73
){
//
[46-72]
}
else
if
(
i
<
73
)
{
//
[46-72]
uint32_t
sm
;
uint32_t
mask
;
i
-=
46
;
sm
=
ac_decode_table
[
i
];
e
=
get_bits
(
&
s
->
gb
,
sm
&
0xF
);
sm
>>=
8
;
//3bits
mask
=
sm
&
0xff
;
sm
>>=
8
;
//1bit
(
*
run
)
=
(
sm
&
0xff
)
+
(
e
&
(
mask
));
//6bits
(
*
level
)
=
(
sm
>>
8
)
+
(
e
&
(
~
mask
));
//5bits
(
*
final
)
=
i
>
(
58
-
46
);
}
else
if
(
i
<
75
){
//[73-74]
static
const
uint8_t
crazy_mix_runlevel
[
32
]
=
{
0x22
,
0x32
,
0x33
,
0x53
,
0x23
,
0x42
,
0x43
,
0x63
,
0x24
,
0x52
,
0x34
,
0x73
,
0x25
,
0x62
,
0x44
,
0x83
,
0x26
,
0x72
,
0x35
,
0x54
,
0x27
,
0x82
,
0x45
,
0x64
,
0x28
,
0x92
,
0x36
,
0x74
,
0x29
,
0xa2
,
0x46
,
0x84
};
(
*
final
)
=!
(
i
&
1
);
e
=
get_bits
(
&
s
->
gb
,
5
);
//get the extra bits
(
*
run
)
=
crazy_mix_runlevel
[
e
]
>>
4
;
(
*
level
)
=
crazy_mix_runlevel
[
e
]
&
0x0F
;
}
else
{
(
*
level
)
=
get_bits
(
&
s
->
gb
,
7
-
3
*
(
i
&
1
));
(
*
run
)
=
get_bits
(
&
s
->
gb
,
6
);
(
*
final
)
=
get_bits1
(
&
s
->
gb
);
i
-=
46
;
sm
=
ac_decode_table
[
i
];
e
=
get_bits
(
&
s
->
gb
,
sm
&
0xF
);
sm
>>=
8
;
// 3bits
mask
=
sm
&
0xff
;
sm
>>=
8
;
// 1bit
(
*
run
)
=
(
sm
&
0xff
)
+
(
e
&
(
mask
));
// 6bits
(
*
level
)
=
(
sm
>>
8
)
+
(
e
&
(
~
mask
));
// 5bits
(
*
final
)
=
i
>
(
58
-
46
);
}
else
if
(
i
<
75
)
{
// [73-74]
static
const
uint8_t
crazy_mix_runlevel
[
32
]
=
{
0x22
,
0x32
,
0x33
,
0x53
,
0x23
,
0x42
,
0x43
,
0x63
,
0x24
,
0x52
,
0x34
,
0x73
,
0x25
,
0x62
,
0x44
,
0x83
,
0x26
,
0x72
,
0x35
,
0x54
,
0x27
,
0x82
,
0x45
,
0x64
,
0x28
,
0x92
,
0x36
,
0x74
,
0x29
,
0xa2
,
0x46
,
0x84
,
};
(
*
final
)
=
!
(
i
&
1
);
e
=
get_bits
(
&
s
->
gb
,
5
);
// get the extra bits
(
*
run
)
=
crazy_mix_runlevel
[
e
]
>>
4
;
(
*
level
)
=
crazy_mix_runlevel
[
e
]
&
0x0F
;
}
else
{
(
*
level
)
=
get_bits
(
&
s
->
gb
,
7
-
3
*
(
i
&
1
));
(
*
run
)
=
get_bits
(
&
s
->
gb
,
6
);
(
*
final
)
=
get_bits1
(
&
s
->
gb
);
}
return
;
}
//static const uint8_t dc_extra_sbits[] ={0, 1,1, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 };
static
const
uint8_t
dc_index_offset
[]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
7
,
9
,
13
,
17
,
25
,
33
,
49
,
65
,
97
,
129
,
193
};
/* static const uint8_t dc_extra_sbits[] = {
* 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
* }; */
static
const
uint8_t
dc_index_offset
[]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
7
,
9
,
13
,
17
,
25
,
33
,
49
,
65
,
97
,
129
,
193
,
};
static
int
x8_get_dc_rlf
(
IntraX8Context
*
const
w
,
int
const
mode
,
int
*
const
level
,
int
*
const
final
){
MpegEncContext
*
const
s
=
w
->
s
;
int
i
,
e
,
c
;
static
int
x8_get_dc_rlf
(
IntraX8Context
*
const
w
,
int
const
mode
,
int
*
const
level
,
int
*
const
final
)
{
MpegEncContext
*
const
s
=
w
->
s
;
int
i
,
e
,
c
;
assert
(
mode
<
3
);
if
(
!
w
->
j_dc_vlc
[
mode
]
)
{
int
table_index
;
table_index
=
get_bits
(
&
s
->
gb
,
3
);
//4 modes, same table
w
->
j_dc_vlc
[
mode
]
=
&
j_dc_vlc
[
w
->
quant
<
13
][
table_index
];
assert
(
mode
<
3
);
if
(
!
w
->
j_dc_vlc
[
mode
])
{
int
table_index
=
get_bits
(
&
s
->
gb
,
3
);
// 4 modes, same table
w
->
j_dc_vlc
[
mode
]
=
&
j_dc_vlc
[
w
->
quant
<
13
][
table_index
];
}
assert
(
w
->
j_dc_vlc
);
assert
(
w
->
j_dc_vlc
[
mode
]
->
table
);
i
=
get_vlc2
(
&
s
->
gb
,
w
->
j_dc_vlc
[
mode
]
->
table
,
DC_VLC_BITS
,
DC_VLC_MTD
);
i
=
get_vlc2
(
&
s
->
gb
,
w
->
j_dc_vlc
[
mode
]
->
table
,
DC_VLC_BITS
,
DC_VLC_MTD
);
/*
(i>=17) {i-=17;final=1;}
*/
c
=
i
>
16
;
(
*
final
)
=
c
;
i
-=
17
*
c
;
/*
(i >= 17) { i -= 17; final =1; }
*/
c
=
i
>
16
;
(
*
final
)
=
c
;
i
-=
17
*
c
;
if
(
i
<=
0
)
{
(
*
level
)
=
0
;
if
(
i
<=
0
)
{
(
*
level
)
=
0
;
return
-
i
;
}
c
=
(
i
+
1
)
>>
1
;
//
hackish way to calculate dc_extra_sbits[]
c
-=
c
>
1
;
c
=
(
i
+
1
)
>>
1
;
//
hackish way to calculate dc_extra_sbits[]
c
-=
c
>
1
;
e
=
get_bits
(
&
s
->
gb
,
c
);
//
get the extra bits
i
=
dc_index_offset
[
i
]
+
(
e
>>
1
);
e
=
get_bits
(
&
s
->
gb
,
c
);
//
get the extra bits
i
=
dc_index_offset
[
i
]
+
(
e
>>
1
);
e
=
-
(
e
&
1
);
//0,
0xffffff
(
*
level
)
=
(
i
^
e
)
-
e
;
// (i^0)-0 , (i^0xff)-
(-1)
e
=
-
(
e
&
1
);
// 0,
0xffffff
(
*
level
)
=
(
i
^
e
)
-
e
;
// (i ^ 0) -0 , (i ^ 0xff) -
(-1)
return
0
;
}
//end of huffman
static
int
x8_setup_spatial_predictor
(
IntraX8Context
*
const
w
,
const
int
chroma
){
MpegEncContext
*
const
s
=
w
->
s
;
// end of huffman
static
int
x8_setup_spatial_predictor
(
IntraX8Context
*
const
w
,
const
int
chroma
)
{
MpegEncContext
*
const
s
=
w
->
s
;
int
range
;
int
sum
;
int
quant
;
w
->
dsp
.
setup_spatial_compensation
(
s
->
dest
[
chroma
],
s
->
sc
.
edge_emu_buffer
,
s
->
current_picture
.
f
->
linesize
[
chroma
>
0
],
s
->
current_picture
.
f
->
linesize
[
chroma
>
0
],
&
range
,
&
sum
,
w
->
edges
);
if
(
chroma
)
{
w
->
orient
=
w
->
chroma_orient
;
quant
=
w
->
quant_dc_chroma
;
}
else
{
quant
=
w
->
quant
;
if
(
chroma
)
{
w
->
orient
=
w
->
chroma_orient
;
quant
=
w
->
quant_dc_chroma
;
}
else
{
quant
=
w
->
quant
;
}
w
->
flat_dc
=
0
;
if
(
range
<
quant
||
range
<
3
){
w
->
orient
=
0
;
if
(
range
<
3
){
//yep you read right, a +-1 idct error may break decoding!
w
->
flat_dc
=
1
;
sum
+=
9
;
w
->
predicted_dc
=
(
sum
*
6899
)
>>
17
;
//((1<<17)+9)/(8+8+1+2)=6899
w
->
flat_dc
=
0
;
if
(
range
<
quant
||
range
<
3
)
{
w
->
orient
=
0
;
// yep you read right, a +-1 idct error may break decoding!
if
(
range
<
3
)
{
w
->
flat_dc
=
1
;
sum
+=
9
;
// ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899
w
->
predicted_dc
=
(
sum
*
6899
)
>>
17
;
}
}
if
(
chroma
)
if
(
chroma
)
return
0
;
assert
(
w
->
orient
<
3
);
if
(
range
<
2
*
w
->
quant
){
if
(
(
w
->
edges
&
3
)
==
0
){
if
(
w
->
orient
==
1
)
w
->
orient
=
11
;
if
(
w
->
orient
==
2
)
w
->
orient
=
10
;
}
else
{
w
->
orient
=
0
;
if
(
range
<
2
*
w
->
quant
)
{
if
((
w
->
edges
&
3
)
==
0
)
{
if
(
w
->
orient
==
1
)
w
->
orient
=
11
;
if
(
w
->
orient
==
2
)
w
->
orient
=
10
;
}
else
{
w
->
orient
=
0
;
}
w
->
raw_orient
=
0
;
}
else
{
static
const
uint8_t
prediction_table
[
3
][
12
]
=
{
{
0
,
8
,
4
,
10
,
11
,
2
,
6
,
9
,
1
,
3
,
5
,
7
},
{
4
,
0
,
8
,
11
,
10
,
3
,
5
,
2
,
6
,
9
,
1
,
7
},
{
8
,
0
,
4
,
10
,
11
,
1
,
7
,
2
,
6
,
9
,
3
,
5
}
w
->
raw_orient
=
0
;
}
else
{
static
const
uint8_t
prediction_table
[
3
][
12
]
=
{
{
0
,
8
,
4
,
10
,
11
,
2
,
6
,
9
,
1
,
3
,
5
,
7
},
{
4
,
0
,
8
,
11
,
10
,
3
,
5
,
2
,
6
,
9
,
1
,
7
},
{
8
,
0
,
4
,
10
,
11
,
1
,
7
,
2
,
6
,
9
,
3
,
5
},
};
w
->
raw_orient
=
x8_get_orient_vlc
(
w
);
if
(
w
->
raw_orient
<
0
)
return
-
1
;
assert
(
w
->
raw_orient
<
12
);
assert
(
w
->
orient
<
3
);
w
->
orient
=
prediction_table
[
w
->
orient
][
w
->
raw_orient
];
w
->
raw_orient
=
x8_get_orient_vlc
(
w
);
if
(
w
->
raw_orient
<
0
)
return
-
1
;
assert
(
w
->
raw_orient
<
12
);
assert
(
w
->
orient
<
3
);
w
->
orient
=
prediction_table
[
w
->
orient
][
w
->
raw_orient
];
}
return
0
;
}
static
void
x8_update_predictions
(
IntraX8Context
*
const
w
,
const
int
orient
,
const
int
est_run
){
MpegEncContext
*
const
s
=
w
->
s
;
static
void
x8_update_predictions
(
IntraX8Context
*
const
w
,
const
int
orient
,
const
int
est_run
)
{
MpegEncContext
*
const
s
=
w
->
s
;
w
->
prediction_table
[
s
->
mb_x
*
2
+
(
s
->
mb_y
&
1
)]
=
(
est_run
<<
2
)
+
1
*
(
orient
==
4
)
+
2
*
(
orient
==
8
);
w
->
prediction_table
[
s
->
mb_x
*
2
+
(
s
->
mb_y
&
1
)]
=
(
est_run
<<
2
)
+
1
*
(
orient
==
4
)
+
2
*
(
orient
==
8
);
/*
y=2n+0 ->//
0 2 4
y=2n+1 ->//
1 3 5
*/
* y = 2n + 0 -> //
0 2 4
* y = 2n + 1 -> //
1 3 5
*/
}
static
void
x8_get_prediction_chroma
(
IntraX8Context
*
const
w
){
MpegEncContext
*
const
s
=
w
->
s
;
w
->
edges
=
1
*
(
!
(
s
->
mb_x
>>
1
)
);
w
->
edges
|=
2
*
(
!
(
s
->
mb_y
>>
1
)
);
w
->
edges
|=
4
*
(
s
->
mb_x
>=
(
2
*
s
->
mb_width
-
1
)
);
//mb_x for chroma would always be odd
static
void
x8_get_prediction_chroma
(
IntraX8Context
*
const
w
)
{
MpegEncContext
*
const
s
=
w
->
s
;
w
->
raw_orient
=
0
;
if
(
w
->
edges
&
3
){
//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
w
->
chroma_orient
=
4
<<
((
0xCC
>>
w
->
edges
)
&
1
);
w
->
edges
=
1
*
(
!
(
s
->
mb_x
>>
1
));
w
->
edges
|=
2
*
(
!
(
s
->
mb_y
>>
1
));
w
->
edges
|=
4
*
(
s
->
mb_x
>=
(
2
*
s
->
mb_width
-
1
));
// mb_x for chroma would always be odd
w
->
raw_orient
=
0
;
// lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC
if
(
w
->
edges
&
3
)
{
w
->
chroma_orient
=
4
<<
((
0xCC
>>
w
->
edges
)
&
1
);
return
;
}
w
->
chroma_orient
=
(
w
->
prediction_table
[
2
*
s
->
mb_x
-
2
]
&
0x03
)
<<
2
;
//block[x-1][y|1-1)]
// block[x - 1][y | 1 - 1)]
w
->
chroma_orient
=
(
w
->
prediction_table
[
2
*
s
->
mb_x
-
2
]
&
0x03
)
<<
2
;
}
static
void
x8_get_prediction
(
IntraX8Context
*
const
w
){
MpegEncContext
*
const
s
=
w
->
s
;
int
a
,
b
,
c
,
i
;
static
void
x8_get_prediction
(
IntraX8Context
*
const
w
)
{
MpegEncContext
*
const
s
=
w
->
s
;
int
a
,
b
,
c
,
i
;
w
->
edges
=
1
*
(
!
s
->
mb_x
);
w
->
edges
|=
2
*
(
!
s
->
mb_y
);
w
->
edges
|=
4
*
(
s
->
mb_x
>=
(
2
*
s
->
mb_width
-
1
)
);
w
->
edges
=
1
*
(
!
s
->
mb_x
);
w
->
edges
|=
2
*
(
!
s
->
mb_y
);
w
->
edges
|=
4
*
(
s
->
mb_x
>=
(
2
*
s
->
mb_width
-
1
)
);
switch
(
w
->
edges
&
3
)
{
switch
(
w
->
edges
&
3
)
{
case
0
:
break
;
case
1
:
//take the one from the above block[0][y-
1]
w
->
est_run
=
w
->
prediction_table
[
!
(
s
->
mb_y
&
1
)]
>>
2
;
// take the one from the above block[0][y -
1]
w
->
est_run
=
w
->
prediction_table
[
!
(
s
->
mb_y
&
1
)]
>>
2
;
w
->
orient
=
1
;
return
;
case
2
:
//take the one from the previous block[x-
1][0]
w
->
est_run
=
w
->
prediction_table
[
2
*
s
->
mb_x
-
2
]
>>
2
;
// take the one from the previous block[x -
1][0]
w
->
est_run
=
w
->
prediction_table
[
2
*
s
->
mb_x
-
2
]
>>
2
;
w
->
orient
=
2
;
return
;
case
3
:
...
...
@@ -404,104 +440,113 @@ static void x8_get_prediction(IntraX8Context * const w){
w
->
orient
=
0
;
return
;
}
//no edge cases
b
=
w
->
prediction_table
[
2
*
s
->
mb_x
+
!
(
s
->
mb_y
&
1
)
];
//block[x ][y-
1]
a
=
w
->
prediction_table
[
2
*
s
->
mb_x
-
2
+
(
s
->
mb_y
&
1
)
];
//block[x-1][y
]
c
=
w
->
prediction_table
[
2
*
s
->
mb_x
-
2
+
!
(
s
->
mb_y
&
1
)
];
//block[x-1][y-
1]
//
no edge cases
b
=
w
->
prediction_table
[
2
*
s
->
mb_x
+
!
(
s
->
mb_y
&
1
)];
// block[x ][y -
1]
a
=
w
->
prediction_table
[
2
*
s
->
mb_x
-
2
+
(
s
->
mb_y
&
1
)];
// block[x - 1][y
]
c
=
w
->
prediction_table
[
2
*
s
->
mb_x
-
2
+
!
(
s
->
mb_y
&
1
)];
// block[x - 1][y -
1]
w
->
est_run
=
FFMIN
(
b
,
a
);
w
->
est_run
=
FFMIN
(
b
,
a
);
/* This condition has nothing to do with w->edges, even if it looks
similar it would trigger if e.g. x=3;y=2;
I guess somebody wrote something wrong and it became standard. */
if
(
(
s
->
mb_x
&
s
->
mb_y
)
!=
0
)
w
->
est_run
=
FFMIN
(
c
,
w
->
est_run
);
w
->
est_run
>>=
2
;
a
&=
3
;
b
&=
3
;
c
&=
3
;
i
=
(
0xFFEAF4C4
>>
(
2
*
b
+
8
*
a
)
)
&
3
;
if
(
i
!=
3
)
w
->
orient
=
i
;
else
w
->
orient
=
(
0xFFEAD8
>>
(
2
*
c
+
8
*
(
w
->
quant
>
12
))
)
&
3
;
* similar it would trigger if e.g. x = 3; y = 2;
* I guess somebody wrote something wrong and it became standard. */
if
((
s
->
mb_x
&
s
->
mb_y
)
!=
0
)
w
->
est_run
=
FFMIN
(
c
,
w
->
est_run
);
w
->
est_run
>>=
2
;
a
&=
3
;
b
&=
3
;
c
&=
3
;
i
=
(
0xFFEAF4C4
>>
(
2
*
b
+
8
*
a
))
&
3
;
if
(
i
!=
3
)
w
->
orient
=
i
;
else
w
->
orient
=
(
0xFFEAD8
>>
(
2
*
c
+
8
*
(
w
->
quant
>
12
)))
&
3
;
/*
lut1[b][a]={
->{0, 1, 0, pad},
{0, 1, X, pad},
{2, 2, 2, pad}}
pad 2 2 2; pad X 1 0; pad 0 1 0 <-
-> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4
lut2[q>12][c]={
->{0,2,1,pad},
{2,2,2,pad}}
pad 2 2 2; pad 1 2 0 <-
-> 11 10'10 10 '11 01'10 00=>0xEAD8
*/
* lut1[b][a] = {
* ->{ 0, 1, 0, pad },
* { 0, 1, X, pad },
* { 2, 2, 2, pad }
* }
* pad 2 2 2;
* pad X 1 0;
* pad 0 1 0 <-
* -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4
*
* lut2[q>12][c] = {
* ->{ 0, 2, 1, pad},
* { 2, 2, 2, pad}
* }
* pad 2 2 2;
* pad 1 2 0 <-
* -> 11 10'10 10 '11 01'10 00 => 0xEAD8
*/
}
static
void
x8_ac_compensation
(
IntraX8Context
*
const
w
,
int
const
direction
,
int
const
dc_level
){
MpegEncContext
*
const
s
=
w
->
s
;
static
void
x8_ac_compensation
(
IntraX8Context
*
const
w
,
int
const
direction
,
int
const
dc_level
)
{
MpegEncContext
*
const
s
=
w
->
s
;
int
t
;
#define B(x, y) s->block[0][s->idsp.idct_permutation[(x) + (y) * 8]]
#define T(x) ((x) * dc_level + 0x8000) >> 16;
switch
(
direction
)
{
switch
(
direction
)
{
case
0
:
t
=
T
(
3811
);
//
h
B
(
1
,
0
)
-=
t
;
B
(
0
,
1
)
-=
t
;
t
=
T
(
487
);
//
e
B
(
2
,
0
)
-=
t
;
B
(
0
,
2
)
-=
t
;
t
=
T
(
506
);
//
f
B
(
3
,
0
)
-=
t
;
B
(
0
,
3
)
-=
t
;
t
=
T
(
135
);
//
c
B
(
4
,
0
)
-=
t
;
B
(
0
,
4
)
-=
t
;
B
(
2
,
1
)
+=
t
;
B
(
1
,
2
)
+=
t
;
B
(
3
,
1
)
+=
t
;
B
(
1
,
3
)
+=
t
;
t
=
T
(
173
);
//
d
B
(
5
,
0
)
-=
t
;
B
(
0
,
5
)
-=
t
;
t
=
T
(
61
);
//
b
B
(
6
,
0
)
-=
t
;
B
(
0
,
6
)
-=
t
;
B
(
5
,
1
)
+=
t
;
B
(
1
,
5
)
+=
t
;
t
=
T
(
42
);
//
a
B
(
7
,
0
)
-=
t
;
B
(
0
,
7
)
-=
t
;
B
(
4
,
1
)
+=
t
;
B
(
1
,
4
)
+=
t
;
B
(
4
,
4
)
+=
t
;
t
=
T
(
1084
);
//
g
B
(
1
,
1
)
+=
t
;
s
->
block_last_index
[
0
]
=
FFMAX
(
s
->
block_last_index
[
0
],
7
*
8
);
t
=
T
(
3811
);
//
h
B
(
1
,
0
)
-=
t
;
B
(
0
,
1
)
-=
t
;
t
=
T
(
487
);
//
e
B
(
2
,
0
)
-=
t
;
B
(
0
,
2
)
-=
t
;
t
=
T
(
506
);
//
f
B
(
3
,
0
)
-=
t
;
B
(
0
,
3
)
-=
t
;
t
=
T
(
135
);
//
c
B
(
4
,
0
)
-=
t
;
B
(
0
,
4
)
-=
t
;
B
(
2
,
1
)
+=
t
;
B
(
1
,
2
)
+=
t
;
B
(
3
,
1
)
+=
t
;
B
(
1
,
3
)
+=
t
;
t
=
T
(
173
);
//
d
B
(
5
,
0
)
-=
t
;
B
(
0
,
5
)
-=
t
;
t
=
T
(
61
);
//
b
B
(
6
,
0
)
-=
t
;
B
(
0
,
6
)
-=
t
;
B
(
5
,
1
)
+=
t
;
B
(
1
,
5
)
+=
t
;
t
=
T
(
42
);
//
a
B
(
7
,
0
)
-=
t
;
B
(
0
,
7
)
-=
t
;
B
(
4
,
1
)
+=
t
;
B
(
1
,
4
)
+=
t
;
B
(
4
,
4
)
+=
t
;
t
=
T
(
1084
);
//
g
B
(
1
,
1
)
+=
t
;
s
->
block_last_index
[
0
]
=
FFMAX
(
s
->
block_last_index
[
0
],
7
*
8
);
break
;
case
1
:
B
(
0
,
1
)
-=
T
(
6269
);
B
(
0
,
3
)
-=
T
(
708
);
B
(
0
,
5
)
-=
T
(
172
);
B
(
0
,
7
)
-=
T
(
73
);
B
(
0
,
1
)
-=
T
(
6269
);
B
(
0
,
3
)
-=
T
(
708
);
B
(
0
,
5
)
-=
T
(
172
);
B
(
0
,
7
)
-=
T
(
73
);
s
->
block_last_index
[
0
]
=
FFMAX
(
s
->
block_last_index
[
0
],
7
*
8
);
s
->
block_last_index
[
0
]
=
FFMAX
(
s
->
block_last_index
[
0
],
7
*
8
);
break
;
case
2
:
B
(
1
,
0
)
-=
T
(
6269
);
B
(
3
,
0
)
-=
T
(
708
);
B
(
5
,
0
)
-=
T
(
172
);
B
(
7
,
0
)
-=
T
(
73
);
B
(
1
,
0
)
-=
T
(
6269
);
B
(
3
,
0
)
-=
T
(
708
);
B
(
5
,
0
)
-=
T
(
172
);
B
(
7
,
0
)
-=
T
(
73
);
s
->
block_last_index
[
0
]
=
FFMAX
(
s
->
block_last_index
[
0
],
7
);
break
;
...
...
@@ -510,11 +555,13 @@ static void x8_ac_compensation(IntraX8Context * const w, int const direction, in
#undef T
}
static
void
dsp_x8_put_solidcolor
(
uint8_t
const
pix
,
uint8_t
*
dst
,
int
const
linesize
){
static
void
dsp_x8_put_solidcolor
(
uint8_t
const
pix
,
uint8_t
*
dst
,
int
const
linesize
)
{
int
k
;
for
(
k
=
0
;
k
<
8
;
k
++
)
{
memset
(
dst
,
pix
,
8
);
dst
+=
linesize
;
for
(
k
=
0
;
k
<
8
;
k
++
)
{
memset
(
dst
,
pix
,
8
);
dst
+=
linesize
;
}
}
...
...
@@ -526,156 +573,159 @@ static const int16_t quant_table[64] = {
353
,
358
,
362
,
366
,
371
,
375
,
379
,
384
,
389
,
393
,
398
,
403
,
408
,
413
,
417
,
422
,
428
,
433
,
438
,
443
,
448
,
454
,
459
,
465
,
470
,
476
,
482
,
488
,
493
,
499
,
505
,
511
470
,
476
,
482
,
488
,
493
,
499
,
505
,
511
,
};
static
int
x8_decode_intra_mb
(
IntraX8Context
*
const
w
,
const
int
chroma
){
MpegEncContext
*
const
s
=
w
->
s
;
static
int
x8_decode_intra_mb
(
IntraX8Context
*
const
w
,
const
int
chroma
)
{
MpegEncContext
*
const
s
=
w
->
s
;
uint8_t
*
scantable
;
int
final
,
run
,
level
;
int
ac_mode
,
dc_mode
,
est_run
,
dc_level
;
int
pos
,
n
;
uint8_t
*
scantable
;
int
final
,
run
,
level
;
int
ac_mode
,
dc_mode
,
est_run
,
dc_level
;
int
pos
,
n
;
int
zeros_only
;
int
use_quant_matrix
;
int
sign
;
assert
(
w
->
orient
<
12
);
assert
(
w
->
orient
<
12
);
s
->
bdsp
.
clear_block
(
s
->
block
[
0
]);
if
(
chroma
){
dc_mode
=
2
;
}
else
{
dc_mode
=!!
w
->
est_run
;
//0,1
}
if
(
chroma
)
dc_mode
=
2
;
else
dc_mode
=
!!
w
->
est_run
;
// 0, 1
if
(
x8_get_dc_rlf
(
w
,
dc_mode
,
&
dc_level
,
&
final
))
return
-
1
;
n
=
0
;
zeros_only
=
0
;
if
(
!
final
){
//decode ac
use_quant_matrix
=
w
->
use_quant_matrix
;
if
(
chroma
){
if
(
x8_get_dc_rlf
(
w
,
dc_mode
,
&
dc_level
,
&
final
))
return
-
1
;
n
=
0
;
zeros_only
=
0
;
if
(
!
final
)
{
// decode ac
use_quant_matrix
=
w
->
use_quant_matrix
;
if
(
chroma
)
{
ac_mode
=
1
;
est_run
=
64
;
//
not used
}
else
{
if
(
w
->
raw_orient
<
3
)
{
est_run
=
64
;
//
not used
}
else
{
if
(
w
->
raw_orient
<
3
)
use_quant_matrix
=
0
;
}
if
(
w
->
raw_orient
>
4
)
{
if
(
w
->
raw_orient
>
4
)
{
ac_mode
=
0
;
est_run
=
64
;
}
else
{
if
(
w
->
est_run
>
1
)
{
}
else
{
if
(
w
->
est_run
>
1
)
{
ac_mode
=
2
;
est_run
=
w
->
est_run
;
}
else
{
est_run
=
w
->
est_run
;
}
else
{
ac_mode
=
3
;
est_run
=
64
;
}
}
}
x8_select_ac_table
(
w
,
ac_mode
);
/*
scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};
<-
-> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>
0x928548 */
scantable
=
w
->
scantable
[
(
0x928548
>>
(
2
*
w
->
orient
))
&
3
].
permutated
;
pos
=
0
;
x8_select_ac_table
(
w
,
ac_mode
);
/*
scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 };
<-
* -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>
0x928548 */
scantable
=
w
->
scantable
[
(
0x928548
>>
(
2
*
w
->
orient
))
&
3
].
permutated
;
pos
=
0
;
do
{
n
++
;
if
(
n
>=
est_run
)
{
ac_mode
=
3
;
x8_select_ac_table
(
w
,
3
);
if
(
n
>=
est_run
)
{
ac_mode
=
3
;
x8_select_ac_table
(
w
,
3
);
}
x8_get_ac_rlf
(
w
,
ac_mode
,
&
run
,
&
level
,
&
final
);
x8_get_ac_rlf
(
w
,
ac_mode
,
&
run
,
&
level
,
&
final
);
pos
+=
run
+
1
;
if
(
pos
>
63
)
{
//this also handles vlc error in x8_get_ac_rlf
pos
+=
run
+
1
;
if
(
pos
>
63
)
{
//
this also handles vlc error in x8_get_ac_rlf
return
-
1
;
}
level
=
(
level
+
1
)
*
w
->
dquant
;
level
+=
w
->
qsum
;
level
=
(
level
+
1
)
*
w
->
dquant
;
level
+=
w
->
qsum
;
sign
=
-
get_bits1
(
&
s
->
gb
);
sign
=
-
get_bits1
(
&
s
->
gb
);
level
=
(
level
^
sign
)
-
sign
;
if
(
use_quant_matrix
){
level
=
(
level
*
quant_table
[
pos
])
>>
8
;
}
s
->
block
[
0
][
scantable
[
pos
]
]
=
level
;
}
while
(
!
final
);
if
(
use_quant_matrix
)
level
=
(
level
*
quant_table
[
pos
])
>>
8
;
s
->
block_last_index
[
0
]
=
pos
;
}
else
{
//DC only
s
->
block_last_index
[
0
]
=
0
;
if
(
w
->
flat_dc
&&
((
unsigned
)(
dc_level
+
1
))
<
3
){
//[-1;1]
int32_t
divide_quant
=
!
chroma
?
w
->
divide_quant_dc_luma
:
w
->
divide_quant_dc_chroma
;
int32_t
dc_quant
=
!
chroma
?
w
->
quant
:
w
->
quant_dc_chroma
;
s
->
block
[
0
][
scantable
[
pos
]]
=
level
;
}
while
(
!
final
);
//original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
dc_level
+=
(
w
->
predicted_dc
*
divide_quant
+
(
1
<<
12
)
)
>>
13
;
s
->
block_last_index
[
0
]
=
pos
;
}
else
{
// DC only
s
->
block_last_index
[
0
]
=
0
;
if
(
w
->
flat_dc
&&
((
unsigned
)
(
dc_level
+
1
))
<
3
)
{
// [-1; 1]
int32_t
divide_quant
=
!
chroma
?
w
->
divide_quant_dc_luma
:
w
->
divide_quant_dc_chroma
;
int32_t
dc_quant
=
!
chroma
?
w
->
quant
:
w
->
quant_dc_chroma
;
dsp_x8_put_solidcolor
(
av_clip_uint8
((
dc_level
*
dc_quant
+
4
)
>>
3
),
s
->
dest
[
chroma
],
s
->
current_picture
.
f
->
linesize
[
!!
chroma
]);
// original intent dc_level += predicted_dc/quant;
// but it got lost somewhere in the rounding
dc_level
+=
(
w
->
predicted_dc
*
divide_quant
+
(
1
<<
12
))
>>
13
;
dsp_x8_put_solidcolor
(
av_clip_uint8
((
dc_level
*
dc_quant
+
4
)
>>
3
),
s
->
dest
[
chroma
],
s
->
current_picture
.
f
->
linesize
[
!!
chroma
]);
goto
block_placed
;
}
zeros_only
=
(
dc_level
==
0
);
}
if
(
!
chroma
){
s
->
block
[
0
][
0
]
=
dc_level
*
w
->
quant
;
}
else
{
s
->
block
[
0
][
0
]
=
dc_level
*
w
->
quant_dc_chroma
;
}
if
(
!
chroma
)
s
->
block
[
0
][
0
]
=
dc_level
*
w
->
quant
;
else
s
->
block
[
0
][
0
]
=
dc_level
*
w
->
quant_dc_chroma
;
//there is !zero_only check in the original, but dc_level check is enough
if
(
(
unsigned
int
)(
dc_level
+
1
)
>=
3
&&
(
w
->
edges
&
3
)
!=
3
)
{
//
there is !zero_only check in the original, but dc_level check is enough
if
((
unsigned
int
)
(
dc_level
+
1
)
>=
3
&&
(
w
->
edges
&
3
)
!=
3
)
{
int
direction
;
/*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
-> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
direction
=
(
0x6A017C
>>
(
w
->
orient
*
2
))
&
3
;
if
(
direction
!=
3
){
x8_ac_compensation
(
w
,
direction
,
s
->
block
[
0
][
0
]);
//modify block_last[]
/* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <-
* -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */
direction
=
(
0x6A017C
>>
(
w
->
orient
*
2
))
&
3
;
if
(
direction
!=
3
)
{
// modify block_last[]
x8_ac_compensation
(
w
,
direction
,
s
->
block
[
0
][
0
]);
}
}
if
(
w
->
flat_dc
){
dsp_x8_put_solidcolor
(
w
->
predicted_dc
,
s
->
dest
[
chroma
],
s
->
current_picture
.
f
->
linesize
[
!!
chroma
]);
}
else
{
w
->
dsp
.
spatial_compensation
[
w
->
orient
](
s
->
sc
.
edge_emu_buffer
,
if
(
w
->
flat_dc
)
{
dsp_x8_put_solidcolor
(
w
->
predicted_dc
,
s
->
dest
[
chroma
],
s
->
current_picture
.
f
->
linesize
[
!!
chroma
]);
}
else
{
w
->
dsp
.
spatial_compensation
[
w
->
orient
](
s
->
sc
.
edge_emu_buffer
,
s
->
dest
[
chroma
],
s
->
current_picture
.
f
->
linesize
[
!!
chroma
]
);
s
->
current_picture
.
f
->
linesize
[
!!
chroma
]
);
}
if
(
!
zeros_only
)
if
(
!
zeros_only
)
s
->
idsp
.
idct_add
(
s
->
dest
[
chroma
],
s
->
current_picture
.
f
->
linesize
[
!!
chroma
],
s
->
block
[
0
]);
block_placed:
if
(
!
chroma
)
x8_update_predictions
(
w
,
w
->
orient
,
n
);
if
(
!
chroma
){
x8_update_predictions
(
w
,
w
->
orient
,
n
);
}
if
(
s
->
loop_filter
){
uint8_t
*
ptr
=
s
->
dest
[
chroma
];
if
(
s
->
loop_filter
)
{
uint8_t
*
ptr
=
s
->
dest
[
chroma
];
int
linesize
=
s
->
current_picture
.
f
->
linesize
[
!!
chroma
];
if
(
!
(
(
w
->
edges
&
2
)
||
(
zeros_only
&&
(
w
->
orient
|
4
)
==
4
)
)){
if
(
!
((
w
->
edges
&
2
)
||
(
zeros_only
&&
(
w
->
orient
|
4
)
==
4
)))
w
->
dsp
.
h_loop_filter
(
ptr
,
linesize
,
w
->
quant
);
}
if
(
!
(
(
w
->
edges
&
1
)
||
(
zeros_only
&&
(
w
->
orient
|
8
)
==
8
)
)){
if
(
!
((
w
->
edges
&
1
)
||
(
zeros_only
&&
(
w
->
orient
|
8
)
==
8
)))
w
->
dsp
.
v_loop_filter
(
ptr
,
linesize
,
w
->
quant
);
}
}
return
0
;
}
static
void
x8_init_block_index
(
MpegEncContext
*
s
){
//FIXME maybe merge with ff_*
//not s->linesize as this would be wrong for field pics
//not that IntraX8 has interlacing support ;)
// FIXME maybe merge with ff_*
static
void
x8_init_block_index
(
MpegEncContext
*
s
)
{
// not s->linesize as this would be wrong for field pics
// not that IntraX8 has interlacing support ;)
const
int
linesize
=
s
->
current_picture
.
f
->
linesize
[
0
];
const
int
uvlinesize
=
s
->
current_picture
.
f
->
linesize
[
1
];
...
...
@@ -684,8 +734,9 @@ static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_
s
->
dest
[
2
]
=
s
->
current_picture
.
f
->
data
[
2
];
s
->
dest
[
0
]
+=
s
->
mb_y
*
linesize
<<
3
;
s
->
dest
[
1
]
+=
(
s
->
mb_y
&
(
~
1
)
)
*
uvlinesize
<<
2
;
//chroma blocks are on add rows
s
->
dest
[
2
]
+=
(
s
->
mb_y
&
(
~
1
)
)
*
uvlinesize
<<
2
;
// chroma blocks are on add rows
s
->
dest
[
1
]
+=
(
s
->
mb_y
&
(
~
1
))
*
uvlinesize
<<
2
;
s
->
dest
[
2
]
+=
(
s
->
mb_y
&
(
~
1
))
*
uvlinesize
<<
2
;
}
/**
...
...
@@ -694,16 +745,21 @@ static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_
* @param w pointer to IntraX8Context
* @param s pointer to MpegEncContext of the parent codec
*/
av_cold
void
ff_intrax8_common_init
(
IntraX8Context
*
w
,
MpegEncContext
*
const
s
){
w
->
s
=
s
;
av_cold
void
ff_intrax8_common_init
(
IntraX8Context
*
w
,
MpegEncContext
*
const
s
)
{
w
->
s
=
s
;
x8_vlc_init
();
assert
(
s
->
mb_width
>
0
);
w
->
prediction_table
=
av_mallocz
(
s
->
mb_width
*
2
*
2
);
//two rows, 2 blocks per cannon mb
assert
(
s
->
mb_width
>
0
);
ff_init_scantable
(
s
->
idsp
.
idct_permutation
,
&
w
->
scantable
[
0
],
ff_wmv1_scantable
[
0
]);
ff_init_scantable
(
s
->
idsp
.
idct_permutation
,
&
w
->
scantable
[
1
],
ff_wmv1_scantable
[
2
]);
ff_init_scantable
(
s
->
idsp
.
idct_permutation
,
&
w
->
scantable
[
2
],
ff_wmv1_scantable
[
3
]);
// two rows, 2 blocks per cannon mb
w
->
prediction_table
=
av_mallocz
(
s
->
mb_width
*
2
*
2
);
ff_init_scantable
(
s
->
idsp
.
idct_permutation
,
&
w
->
scantable
[
0
],
ff_wmv1_scantable
[
0
]);
ff_init_scantable
(
s
->
idsp
.
idct_permutation
,
&
w
->
scantable
[
1
],
ff_wmv1_scantable
[
2
]);
ff_init_scantable
(
s
->
idsp
.
idct_permutation
,
&
w
->
scantable
[
2
],
ff_wmv1_scantable
[
3
]);
ff_intrax8dsp_init
(
&
w
->
dsp
);
}
...
...
@@ -712,7 +768,7 @@ av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s
* Destroy IntraX8 frame structure.
* @param w pointer to IntraX8Context
*/
av_cold
void
ff_intrax8_common_end
(
IntraX8Context
*
w
)
av_cold
void
ff_intrax8_common_end
(
IntraX8Context
*
w
)
{
av_freep
(
&
w
->
prediction_table
);
}
...
...
@@ -727,8 +783,10 @@ av_cold void ff_intrax8_common_end(IntraX8Context * w)
* @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
* @param quant_offset offset away from zero
*/
int
ff_intrax8_decode_picture
(
IntraX8Context
*
const
w
,
int
dquant
,
int
quant_offset
){
MpegEncContext
*
const
s
=
w
->
s
;
int
ff_intrax8_decode_picture
(
IntraX8Context
*
const
w
,
int
dquant
,
int
quant_offset
)
{
MpegEncContext
*
const
s
=
w
->
s
;
int
mb_xy
;
assert
(
s
);
w
->
use_quant_matrix
=
get_bits1
(
&
s
->
gb
);
...
...
@@ -737,51 +795,53 @@ int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_of
w
->
quant
=
dquant
>>
1
;
w
->
qsum
=
quant_offset
;
w
->
divide_quant_dc_luma
=
((
1
<<
16
)
+
(
w
->
quant
>>
1
))
/
w
->
quant
;
if
(
w
->
quant
<
5
)
{
w
->
divide_quant_dc_luma
=
((
1
<<
16
)
+
(
w
->
quant
>>
1
))
/
w
->
quant
;
if
(
w
->
quant
<
5
)
{
w
->
quant_dc_chroma
=
w
->
quant
;
w
->
divide_quant_dc_chroma
=
w
->
divide_quant_dc_luma
;
}
else
{
w
->
quant_dc_chroma
=
w
->
quant
+
((
w
->
quant
+
3
)
>>
3
);
w
->
divide_quant_dc_chroma
=
((
1
<<
16
)
+
(
w
->
quant_dc_chroma
>>
1
))
/
w
->
quant_dc_chroma
;
}
else
{
w
->
quant_dc_chroma
=
w
->
quant
+
((
w
->
quant
+
3
)
>>
3
);
w
->
divide_quant_dc_chroma
=
((
1
<<
16
)
+
(
w
->
quant_dc_chroma
>>
1
))
/
w
->
quant_dc_chroma
;
}
x8_reset_vlc_tables
(
w
);
for
(
s
->
mb_y
=
0
;
s
->
mb_y
<
s
->
mb_height
*
2
;
s
->
mb_y
++
){
for
(
s
->
mb_y
=
0
;
s
->
mb_y
<
s
->
mb_height
*
2
;
s
->
mb_y
++
)
{
x8_init_block_index
(
s
);
mb_xy
=
(
s
->
mb_y
>>
1
)
*
s
->
mb_stride
;
mb_xy
=
(
s
->
mb_y
>>
1
)
*
s
->
mb_stride
;
for
(
s
->
mb_x
=
0
;
s
->
mb_x
<
s
->
mb_width
*
2
;
s
->
mb_x
++
)
{
for
(
s
->
mb_x
=
0
;
s
->
mb_x
<
s
->
mb_width
*
2
;
s
->
mb_x
++
)
{
x8_get_prediction
(
w
);
if
(
x8_setup_spatial_predictor
(
w
,
0
))
goto
error
;
if
(
x8_decode_intra_mb
(
w
,
0
))
goto
error
;
if
(
x8_setup_spatial_predictor
(
w
,
0
))
goto
error
;
if
(
x8_decode_intra_mb
(
w
,
0
))
goto
error
;
if
(
s
->
mb_x
&
s
->
mb_y
&
1
)
{
if
(
s
->
mb_x
&
s
->
mb_y
&
1
)
{
x8_get_prediction_chroma
(
w
);
/*when setting up chroma, no vlc is read,
so no error condition can be reached*/
x8_setup_spatial_predictor
(
w
,
1
);
if
(
x8_decode_intra_mb
(
w
,
1
))
goto
error
;
/* when setting up chroma, no vlc is read,
* so no error condition can be reached */
x8_setup_spatial_predictor
(
w
,
1
);
if
(
x8_decode_intra_mb
(
w
,
1
))
goto
error
;
x8_setup_spatial_predictor
(
w
,
2
);
if
(
x8_decode_intra_mb
(
w
,
2
))
goto
error
;
x8_setup_spatial_predictor
(
w
,
2
);
if
(
x8_decode_intra_mb
(
w
,
2
))
goto
error
;
s
->
dest
[
1
]
+=
8
;
s
->
dest
[
2
]
+=
8
;
s
->
dest
[
1
]
+=
8
;
s
->
dest
[
2
]
+=
8
;
/*
emulate MB info in the relevant tables
*/
s
->
mbskip_table
[
mb_xy
]
=
0
;
s
->
mbintra_table
[
mb_xy
]
=
1
;
/*
emulate MB info in the relevant tables
*/
s
->
mbskip_table
[
mb_xy
]
=
0
;
s
->
mbintra_table
[
mb_xy
]
=
1
;
s
->
current_picture
.
qscale_table
[
mb_xy
]
=
w
->
quant
;
mb_xy
++
;
}
s
->
dest
[
0
]
+=
8
;
}
if
(
s
->
mb_y
&
1
){
ff_mpeg_draw_horiz_band
(
s
,
(
s
->
mb_y
-
1
)
*
8
,
16
);
s
->
dest
[
0
]
+=
8
;
}
if
(
s
->
mb_y
&
1
)
ff_mpeg_draw_horiz_band
(
s
,
(
s
->
mb_y
-
1
)
*
8
,
16
);
}
error:
...
...
libavcodec/intrax8.h
View file @
2ade1cda
...
...
@@ -24,25 +24,29 @@
#include "intrax8dsp.h"
typedef
struct
IntraX8Context
{
VLC
*
j_ac_vlc
[
4
];
//
they point to the static j_mb_vlc
VLC
*
j_orient_vlc
;
VLC
*
j_dc_vlc
[
3
];
VLC
*
j_ac_vlc
[
4
];
//
they point to the static j_mb_vlc
VLC
*
j_orient_vlc
;
VLC
*
j_dc_vlc
[
3
];
int
use_quant_matrix
;
//set by ff_intrax8_common_init
uint8_t
*
prediction_table
;
//2*(mb_w*2)
// set by ff_intrax8_common_init
uint8_t
*
prediction_table
;
// 2 * (mb_w * 2)
ScanTable
scantable
[
3
];
//set by the caller codec
MpegEncContext
*
s
;
// set by the caller codec
MpegEncContext
*
s
;
IntraX8DSPContext
dsp
;
int
quant
;
int
dquant
;
int
qsum
;
//calculated per frame
// calculated per frame
int
quant_dc_chroma
;
int
divide_quant_dc_luma
;
int
divide_quant_dc_chroma
;
//changed per block
// changed per block
int
edges
;
int
flat_dc
;
int
predicted_dc
;
...
...
@@ -52,8 +56,8 @@ typedef struct IntraX8Context {
int
est_run
;
}
IntraX8Context
;
void
ff_intrax8_common_init
(
IntraX8Context
*
w
,
MpegEncContext
*
const
s
);
void
ff_intrax8_common_end
(
IntraX8Context
*
w
);
int
ff_intrax8_decode_picture
(
IntraX8Context
*
w
,
int
quant
,
int
halfpq
);
void
ff_intrax8_common_init
(
IntraX8Context
*
w
,
MpegEncContext
*
const
s
);
void
ff_intrax8_common_end
(
IntraX8Context
*
w
);
int
ff_intrax8_decode_picture
(
IntraX8Context
*
w
,
int
quant
,
int
halfpq
);
#endif
/* AVCODEC_INTRAX8_H */
libavcodec/intrax8dsp.c
View file @
2ade1cda
...
...
@@ -17,7 +17,7 @@
*/
/**
* @file
* @file
*@brief IntraX8 frame subdecoder image manipulation routines
*/
...
...
@@ -25,27 +25,27 @@
#include "libavutil/common.h"
/*
area positions, #3 is 1 pixel only, other are 8 pixels
|66666666|
3|44444444|55555555|
- -+--------+--------+
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
^-start
*/
*
area positions, #3 is 1 pixel only, other are 8 pixels
*
|66666666|
*
3|44444444|55555555|
*
- -+--------+--------+
*
1 2|XXXXXXXX|
*
1 2|XXXXXXXX|
*
1 2|XXXXXXXX|
*
1 2|XXXXXXXX|
*
1 2|XXXXXXXX|
*
1 2|XXXXXXXX|
*
1 2|XXXXXXXX|
*
1 2|XXXXXXXX|
*
^-start
*/
#define area1 (0)
#define area2 (8)
#define area3 (8
+
8)
#define area4 (8
+8+
1)
#define area5 (8
+8+1+
8)
#define area6 (8
+8+1+
16)
#define area3 (8
+
8)
#define area4 (8
+ 8 +
1)
#define area5 (8
+ 8 + 1 +
8)
#define area6 (8
+ 8 + 1 +
16)
/**
Collect statistics and prepare the edge pixels required by the other spatial compensation functions.
...
...
@@ -61,372 +61,404 @@ area positions, #3 is 1 pixel only, other are 8 pixels
2 - mb_y==0 - first row, interpolate area #3,#4,#5,#6;
note: 1|2 - mb_x==mb_y==0 - first block, use 0x80 value for all areas;
4 - mb_x>= (mb_width-1) last block in the row, interpolate area #5;
*/
static
void
x8_setup_spatial_compensation
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
,
int
*
range
,
int
*
psum
,
int
edges
){
uint8_t
*
ptr
;
-*/
static
void
x8_setup_spatial_compensation
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
,
int
*
range
,
int
*
psum
,
int
edges
)
{
uint8_t
*
ptr
;
int
sum
;
int
i
;
int
min_pix
,
max_pix
;
int
min_pix
,
max_pix
;
uint8_t
c
;
if
((
edges
&
3
)
==
3
)
{
*
psum
=
0x80
*
(
8
+
1
+
8
+
2
);
*
range
=
0
;
memset
(
dst
,
0x80
,
16
+
1
+
16
+
8
);
/
/this triggers flat_dc for sure.
//flat_dc avoids all (other) prediction modes, but requires dc_level decoding.
if
((
edges
&
3
)
==
3
)
{
*
psum
=
0x80
*
(
8
+
1
+
8
+
2
);
*
range
=
0
;
memset
(
dst
,
0x80
,
16
+
1
+
16
+
8
);
/
* this triggers flat_dc for sure. flat_dc avoids all (other)
* prediction modes, but requires dc_level decoding. */
return
;
}
min_pix
=
256
;
max_pix
=
-
1
;
min_pix
=
256
;
max_pix
=
-
1
;
sum
=
0
;
sum
=
0
;
if
(
!
(
edges
&
1
)){
//(mb_x!=0)//
there is previous block on this row
ptr
=
src
-
1
;
//
left column, area 2
for
(
i
=
7
;
i
>=
0
;
i
--
)
{
c
=*
(
ptr
-
1
);
//
area1, same mb as area2, no need to check
dst
[
area1
+
i
]
=
c
;
c
=
*
(
ptr
);
if
(
!
(
edges
&
1
))
{
// (mb_x != 0) //
there is previous block on this row
ptr
=
src
-
1
;
//
left column, area 2
for
(
i
=
7
;
i
>=
0
;
i
--
)
{
c
=
*
(
ptr
-
1
);
//
area1, same mb as area2, no need to check
dst
[
area1
+
i
]
=
c
;
c
=
*
(
ptr
);
sum
+=
c
;
min_pix
=
FFMIN
(
min_pix
,
c
);
max_pix
=
FFMAX
(
max_pix
,
c
);
dst
[
area2
+
i
]
=
c
;
sum
+=
c
;
min_pix
=
FFMIN
(
min_pix
,
c
);
max_pix
=
FFMAX
(
max_pix
,
c
);
dst
[
area2
+
i
]
=
c
;
ptr
+=
linesize
;
ptr
+=
linesize
;
}
}
if
(
!
(
edges
&
2
)){
//(mb_y!=0)//there is row above
ptr
=
src
-
linesize
;
//top line
for
(
i
=
0
;
i
<
8
;
i
++
){
c
=*
(
ptr
+
i
);
sum
+=
c
;
min_pix
=
FFMIN
(
min_pix
,
c
);
max_pix
=
FFMAX
(
max_pix
,
c
);
}
if
(
edges
&
4
){
//last block on the row?
memset
(
dst
+
area5
,
c
,
8
);
//set with last pixel fr
memcpy
(
dst
+
area4
,
ptr
,
8
);
}
else
{
memcpy
(
dst
+
area4
,
ptr
,
16
);
//both area4 and 5
if
(
!
(
edges
&
2
))
{
// (mb_y != 0) // there is row above
ptr
=
src
-
linesize
;
// top line
for
(
i
=
0
;
i
<
8
;
i
++
)
{
c
=
*
(
ptr
+
i
);
sum
+=
c
;
min_pix
=
FFMIN
(
min_pix
,
c
);
max_pix
=
FFMAX
(
max_pix
,
c
);
}
memcpy
(
dst
+
area6
,
ptr
-
linesize
,
8
);
//area6 always present in the above block
if
(
edges
&
4
)
{
// last block on the row?
memset
(
dst
+
area5
,
c
,
8
);
// set with last pixel fr
memcpy
(
dst
+
area4
,
ptr
,
8
);
}
else
{
memcpy
(
dst
+
area4
,
ptr
,
16
);
// both area4 and 5
}
//now calculate the stuff we need
if
(
edges
&
3
){
//mb_x==0 || mb_y==0){
int
avg
=
(
sum
+
4
)
>>
3
;
if
(
edges
&
1
){
//(mb_x==0) {//implies mb_y!=0
memset
(
dst
+
area1
,
avg
,
8
+
8
+
1
);
//areas 1,2 and 3 are averaged
}
else
{
//implies y==0 x!=0
memset
(
dst
+
area3
,
avg
,
1
+
16
+
8
);
//areas 3, 4,5,6
// area6 always present in the above block
memcpy
(
dst
+
area6
,
ptr
-
linesize
,
8
);
}
sum
+=
avg
*
9
;
}
else
{
uint8_t
c
=*
(
src
-
1
-
linesize
);
//the edge pixel, in the top line and left column
dst
[
area3
]
=
c
;
sum
+=
c
;
//edge pixel is not part of min/max
// now calculate the stuff we need
if
(
edges
&
3
)
{
// mb_x ==0 || mb_y == 0) {
int
avg
=
(
sum
+
4
)
>>
3
;
if
(
edges
&
1
)
// (mb_x == 0) { // implies mb_y !=0
memset
(
dst
+
area1
,
avg
,
8
+
8
+
1
);
// areas 1, 2, 3 are averaged
else
// implies y == 0 x != 0
memset
(
dst
+
area3
,
avg
,
1
+
16
+
8
);
// areas 3, 4, 5, 6
sum
+=
avg
*
9
;
}
else
{
// the edge pixel, in the top line and left column
uint8_t
c
=
*
(
src
-
1
-
linesize
);
dst
[
area3
]
=
c
;
sum
+=
c
;
// edge pixel is not part of min/max
}
(
*
range
)
=
max_pix
-
min_pix
;
sum
+=
*
(
dst
+
area5
)
+
*
(
dst
+
area5
+
1
);
sum
+=
*
(
dst
+
area5
)
+
*
(
dst
+
area5
+
1
);
*
psum
=
sum
;
}
static
const
uint16_t
zero_prediction_weights
[
64
*
2
]
=
{
640
,
640
,
669
,
480
,
708
,
354
,
748
,
257
,
792
,
198
,
760
,
143
,
808
,
101
,
772
,
72
,
480
,
669
,
537
,
537
,
598
,
416
,
661
,
316
,
719
,
250
,
707
,
185
,
768
,
134
,
745
,
97
,
354
,
708
,
416
,
598
,
488
,
488
,
564
,
388
,
634
,
317
,
642
,
241
,
716
,
179
,
706
,
132
,
257
,
748
,
316
,
661
,
388
,
564
,
469
,
469
,
543
,
395
,
571
,
311
,
655
,
238
,
660
,
180
,
198
,
792
,
250
,
719
,
317
,
634
,
395
,
543
,
469
,
469
,
507
,
380
,
597
,
299
,
616
,
231
,
161
,
855
,
206
,
788
,
266
,
710
,
340
,
623
,
411
,
548
,
455
,
455
,
548
,
366
,
576
,
288
,
122
,
972
,
159
,
914
,
211
,
842
,
276
,
758
,
341
,
682
,
389
,
584
,
483
,
483
,
520
,
390
,
110
,
1172
,
144
,
1107
,
193
,
1028
,
254
,
932
,
317
,
846
,
366
,
731
,
458
,
611
,
499
,
499
static
const
uint16_t
zero_prediction_weights
[
64
*
2
]
=
{
640
,
640
,
669
,
480
,
708
,
354
,
748
,
257
,
792
,
198
,
760
,
143
,
808
,
101
,
772
,
72
,
480
,
669
,
537
,
537
,
598
,
416
,
661
,
316
,
719
,
250
,
707
,
185
,
768
,
134
,
745
,
97
,
354
,
708
,
416
,
598
,
488
,
488
,
564
,
388
,
634
,
317
,
642
,
241
,
716
,
179
,
706
,
132
,
257
,
748
,
316
,
661
,
388
,
564
,
469
,
469
,
543
,
395
,
571
,
311
,
655
,
238
,
660
,
180
,
198
,
792
,
250
,
719
,
317
,
634
,
395
,
543
,
469
,
469
,
507
,
380
,
597
,
299
,
616
,
231
,
161
,
855
,
206
,
788
,
266
,
710
,
340
,
623
,
411
,
548
,
455
,
455
,
548
,
366
,
576
,
288
,
122
,
972
,
159
,
914
,
211
,
842
,
276
,
758
,
341
,
682
,
389
,
584
,
483
,
483
,
520
,
390
,
110
,
1172
,
144
,
1107
,
193
,
1028
,
254
,
932
,
317
,
846
,
366
,
731
,
458
,
611
,
499
,
499
,
};
static
void
spatial_compensation_0
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
i
,
j
;
int
x
,
y
;
unsigned
int
p
;
//power divided by 2
static
void
spatial_compensation_0
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
i
,
j
;
int
x
,
y
;
unsigned
int
p
;
// power divided by 2
int
a
;
uint16_t
left_sum
[
2
][
8
]
=
{
{
0
}
};
uint16_t
top_sum
[
2
][
8
]
=
{
{
0
}
};
for
(
i
=
0
;
i
<
8
;
i
++
)
{
a
=
src
[
area2
+
7
-
i
]
<<
4
;
for
(
j
=
0
;
j
<
8
;
j
++
)
{
p
=
abs
(
i
-
j
);
left_sum
[
p
&
1
][
j
]
+=
a
>>
(
p
>>
1
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
a
=
src
[
area2
+
7
-
i
]
<<
4
;
for
(
j
=
0
;
j
<
8
;
j
++
)
{
p
=
abs
(
i
-
j
);
left_sum
[
p
&
1
][
j
]
+=
a
>>
(
p
>>
1
);
}
}
for
(
i
=
0
;
i
<
8
;
i
++
)
{
a
=
src
[
area4
+
i
]
<<
4
;
for
(
j
=
0
;
j
<
8
;
j
++
)
{
p
=
abs
(
i
-
j
);
top_sum
[
p
&
1
][
j
]
+=
a
>>
(
p
>>
1
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
a
=
src
[
area4
+
i
]
<<
4
;
for
(
j
=
0
;
j
<
8
;
j
++
)
{
p
=
abs
(
i
-
j
);
top_sum
[
p
&
1
][
j
]
+=
a
>>
(
p
>>
1
);
}
}
for
(;
i
<
10
;
i
++
)
{
a
=
src
[
area4
+
i
]
<<
4
;
for
(
j
=
5
;
j
<
8
;
j
++
)
{
p
=
abs
(
i
-
j
);
top_sum
[
p
&
1
][
j
]
+=
a
>>
(
p
>>
1
);
for
(;
i
<
10
;
i
++
)
{
a
=
src
[
area4
+
i
]
<<
4
;
for
(
j
=
5
;
j
<
8
;
j
++
)
{
p
=
abs
(
i
-
j
);
top_sum
[
p
&
1
][
j
]
+=
a
>>
(
p
>>
1
);
}
}
for
(;
i
<
12
;
i
++
)
{
a
=
src
[
area4
+
i
]
<<
4
;
for
(
j
=
7
;
j
<
8
;
j
++
)
{
p
=
abs
(
i
-
j
);
top_sum
[
p
&
1
][
j
]
+=
a
>>
(
p
>>
1
);
for
(;
i
<
12
;
i
++
)
{
a
=
src
[
area4
+
i
]
<<
4
;
for
(
j
=
7
;
j
<
8
;
j
++
)
{
p
=
abs
(
i
-
j
);
top_sum
[
p
&
1
][
j
]
+=
a
>>
(
p
>>
1
);
}
}
for
(
i
=
0
;
i
<
8
;
i
++
){
top_sum
[
0
][
i
]
+=
(
top_sum
[
1
][
i
]
*
181
+
128
)
>>
8
;
//181 is sqrt(2)/2
left_sum
[
0
][
i
]
+=
(
left_sum
[
1
][
i
]
*
181
+
128
)
>>
8
;
}
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
(
(
uint32_t
)
top_sum
[
0
][
x
]
*
zero_prediction_weights
[
y
*
16
+
x
*
2
+
0
]
+
(
uint32_t
)
left_sum
[
0
][
y
]
*
zero_prediction_weights
[
y
*
16
+
x
*
2
+
1
]
+
0x8000
)
>>
16
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
top_sum
[
0
][
i
]
+=
(
top_sum
[
1
][
i
]
*
181
+
128
)
>>
8
;
// 181 is sqrt(2)/2
left_sum
[
0
][
i
]
+=
(
left_sum
[
1
][
i
]
*
181
+
128
)
>>
8
;
}
dst
+=
linesize
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
((
uint32_t
)
top_sum
[
0
][
x
]
*
zero_prediction_weights
[
y
*
16
+
x
*
2
+
0
]
+
(
uint32_t
)
left_sum
[
0
][
y
]
*
zero_prediction_weights
[
y
*
16
+
x
*
2
+
1
]
+
0x8000
)
>>
16
;
dst
+=
linesize
;
}
}
static
void
spatial_compensation_1
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
src
[
area4
+
FFMIN
(
2
*
y
+
x
+
2
,
15
)
];
}
dst
+=
linesize
;
static
void
spatial_compensation_1
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
src
[
area4
+
FFMIN
(
2
*
y
+
x
+
2
,
15
)];
dst
+=
linesize
;
}
}
static
void
spatial_compensation_2
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
src
[
area4
+
1
+
y
+
x
];
}
dst
+=
linesize
;
static
void
spatial_compensation_2
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
src
[
area4
+
1
+
y
+
x
];
dst
+=
linesize
;
}
}
static
void
spatial_compensation_3
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
src
[
area4
+
((
y
+
1
)
>>
1
)
+
x
];
}
dst
+=
linesize
;
static
void
spatial_compensation_3
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
src
[
area4
+
((
y
+
1
)
>>
1
)
+
x
];
dst
+=
linesize
;
}
}
static
void
spatial_compensation_4
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
(
src
[
area4
+
x
]
+
src
[
area6
+
x
]
+
1
)
>>
1
;
}
dst
+=
linesize
;
static
void
spatial_compensation_4
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
(
src
[
area4
+
x
]
+
src
[
area6
+
x
]
+
1
)
>>
1
;
dst
+=
linesize
;
}
}
static
void
spatial_compensation_5
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
if
(
2
*
x
-
y
<
0
){
dst
[
x
]
=
src
[
area2
+
9
+
2
*
x
-
y
];
}
else
{
dst
[
x
]
=
src
[
area4
+
x
-
((
y
+
1
)
>>
1
)];
}
static
void
spatial_compensation_5
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
{
if
(
2
*
x
-
y
<
0
)
dst
[
x
]
=
src
[
area2
+
9
+
2
*
x
-
y
];
else
dst
[
x
]
=
src
[
area4
+
x
-
((
y
+
1
)
>>
1
)];
}
dst
+=
linesize
;
dst
+=
linesize
;
}
}
static
void
spatial_compensation_6
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
src
[
area3
+
x
-
y
];
}
dst
+=
linesize
;
static
void
spatial_compensation_6
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
src
[
area3
+
x
-
y
];
dst
+=
linesize
;
}
}
static
void
spatial_compensation_7
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
if
(
x
-
2
*
y
>
0
){
dst
[
x
]
=
(
src
[
area3
-
1
+
x
-
2
*
y
]
+
src
[
area3
+
x
-
2
*
y
]
+
1
)
>>
1
;
}
else
{
dst
[
x
]
=
src
[
area2
+
8
-
y
+
(
x
>>
1
)];
}
static
void
spatial_compensation_7
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
{
if
(
x
-
2
*
y
>
0
)
dst
[
x
]
=
(
src
[
area3
-
1
+
x
-
2
*
y
]
+
src
[
area3
+
x
-
2
*
y
]
+
1
)
>>
1
;
else
dst
[
x
]
=
src
[
area2
+
8
-
y
+
(
x
>>
1
)];
}
dst
+=
linesize
;
dst
+=
linesize
;
}
}
static
void
spatial_compensation_8
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
(
src
[
area1
+
7
-
y
]
+
src
[
area2
+
7
-
y
]
+
1
)
>>
1
;
}
dst
+=
linesize
;
static
void
spatial_compensation_8
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
(
src
[
area1
+
7
-
y
]
+
src
[
area2
+
7
-
y
]
+
1
)
>>
1
;
dst
+=
linesize
;
}
}
static
void
spatial_compensation_9
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
src
[
area2
+
6
-
FFMIN
(
x
+
y
,
6
)];
}
dst
+=
linesize
;
static
void
spatial_compensation_9
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
src
[
area2
+
6
-
FFMIN
(
x
+
y
,
6
)];
dst
+=
linesize
;
}
}
static
void
spatial_compensation_10
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
(
src
[
area2
+
7
-
y
]
*
(
8
-
x
)
+
src
[
area4
+
x
]
*
x
+
4
)
>>
3
;
}
dst
+=
linesize
;
static
void
spatial_compensation_10
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
(
src
[
area2
+
7
-
y
]
*
(
8
-
x
)
+
src
[
area4
+
x
]
*
x
+
4
)
>>
3
;
dst
+=
linesize
;
}
}
static
void
spatial_compensation_11
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
){
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
){
for
(
x
=
0
;
x
<
8
;
x
++
){
dst
[
x
]
=
(
src
[
area2
+
7
-
y
]
*
y
+
src
[
area4
+
x
]
*
(
8
-
y
)
+
4
)
>>
3
;
}
dst
+=
linesize
;
static
void
spatial_compensation_11
(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
)
{
int
x
,
y
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
dst
[
x
]
=
(
src
[
area2
+
7
-
y
]
*
y
+
src
[
area4
+
x
]
*
(
8
-
y
)
+
4
)
>>
3
;
dst
+=
linesize
;
}
}
static
void
x8_loop_filter
(
uint8_t
*
ptr
,
const
int
a_stride
,
const
int
b_stride
,
int
quant
){
int
i
,
t
;
int
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
p6
,
p7
,
p8
,
p9
;
int
ql
=
(
quant
+
10
)
>>
3
;
for
(
i
=
0
;
i
<
8
;
i
++
,
ptr
+=
b_stride
){
p0
=
ptr
[
-
5
*
a_stride
];
p1
=
ptr
[
-
4
*
a_stride
];
p2
=
ptr
[
-
3
*
a_stride
];
p3
=
ptr
[
-
2
*
a_stride
];
p4
=
ptr
[
-
1
*
a_stride
];
p5
=
ptr
[
0
];
p6
=
ptr
[
1
*
a_stride
];
p7
=
ptr
[
2
*
a_stride
];
p8
=
ptr
[
3
*
a_stride
];
p9
=
ptr
[
4
*
a_stride
];
t
=
(
FFABS
(
p1
-
p2
)
<=
ql
)
+
(
FFABS
(
p2
-
p3
)
<=
ql
)
+
(
FFABS
(
p3
-
p4
)
<=
ql
)
+
(
FFABS
(
p4
-
p5
)
<=
ql
);
if
(
t
>
0
){
//You need at least 1 to be able to reach a total score of 6.
t
+=
(
FFABS
(
p5
-
p6
)
<=
ql
)
+
(
FFABS
(
p6
-
p7
)
<=
ql
)
+
(
FFABS
(
p7
-
p8
)
<=
ql
)
+
(
FFABS
(
p8
-
p9
)
<=
ql
)
+
(
FFABS
(
p0
-
p1
)
<=
ql
);
if
(
t
>=
6
){
int
min
,
max
;
min
=
max
=
p1
;
min
=
FFMIN
(
min
,
p3
);
max
=
FFMAX
(
max
,
p3
);
min
=
FFMIN
(
min
,
p5
);
max
=
FFMAX
(
max
,
p5
);
min
=
FFMIN
(
min
,
p8
);
max
=
FFMAX
(
max
,
p8
);
if
(
max
-
min
<
2
*
quant
){
//early stop
min
=
FFMIN
(
min
,
p2
);
max
=
FFMAX
(
max
,
p2
);
min
=
FFMIN
(
min
,
p4
);
max
=
FFMAX
(
max
,
p4
);
min
=
FFMIN
(
min
,
p6
);
max
=
FFMAX
(
max
,
p6
);
min
=
FFMIN
(
min
,
p7
);
max
=
FFMAX
(
max
,
p7
);
if
(
max
-
min
<
2
*
quant
){
ptr
[
-
2
*
a_stride
]
=
(
4
*
p2
+
3
*
p3
+
1
*
p7
+
4
)
>>
3
;
ptr
[
-
1
*
a_stride
]
=
(
3
*
p2
+
3
*
p4
+
2
*
p7
+
4
)
>>
3
;
ptr
[
0
]
=
(
2
*
p2
+
3
*
p5
+
3
*
p7
+
4
)
>>
3
;
ptr
[
1
*
a_stride
]
=
(
1
*
p2
+
3
*
p6
+
4
*
p7
+
4
)
>>
3
;
static
void
x8_loop_filter
(
uint8_t
*
ptr
,
const
int
a_stride
,
const
int
b_stride
,
int
quant
)
{
int
i
,
t
;
int
p0
,
p1
,
p2
,
p3
,
p4
,
p5
,
p6
,
p7
,
p8
,
p9
;
int
ql
=
(
quant
+
10
)
>>
3
;
for
(
i
=
0
;
i
<
8
;
i
++
,
ptr
+=
b_stride
)
{
p0
=
ptr
[
-
5
*
a_stride
];
p1
=
ptr
[
-
4
*
a_stride
];
p2
=
ptr
[
-
3
*
a_stride
];
p3
=
ptr
[
-
2
*
a_stride
];
p4
=
ptr
[
-
1
*
a_stride
];
p5
=
ptr
[
0
];
p6
=
ptr
[
1
*
a_stride
];
p7
=
ptr
[
2
*
a_stride
];
p8
=
ptr
[
3
*
a_stride
];
p9
=
ptr
[
4
*
a_stride
];
t
=
(
FFABS
(
p1
-
p2
)
<=
ql
)
+
(
FFABS
(
p2
-
p3
)
<=
ql
)
+
(
FFABS
(
p3
-
p4
)
<=
ql
)
+
(
FFABS
(
p4
-
p5
)
<=
ql
);
// You need at least 1 to be able to reach a total score of 6.
if
(
t
>
0
)
{
t
+=
(
FFABS
(
p5
-
p6
)
<=
ql
)
+
(
FFABS
(
p6
-
p7
)
<=
ql
)
+
(
FFABS
(
p7
-
p8
)
<=
ql
)
+
(
FFABS
(
p8
-
p9
)
<=
ql
)
+
(
FFABS
(
p0
-
p1
)
<=
ql
);
if
(
t
>=
6
)
{
int
min
,
max
;
min
=
max
=
p1
;
min
=
FFMIN
(
min
,
p3
);
max
=
FFMAX
(
max
,
p3
);
min
=
FFMIN
(
min
,
p5
);
max
=
FFMAX
(
max
,
p5
);
min
=
FFMIN
(
min
,
p8
);
max
=
FFMAX
(
max
,
p8
);
if
(
max
-
min
<
2
*
quant
)
{
// early stop
min
=
FFMIN
(
min
,
p2
);
max
=
FFMAX
(
max
,
p2
);
min
=
FFMIN
(
min
,
p4
);
max
=
FFMAX
(
max
,
p4
);
min
=
FFMIN
(
min
,
p6
);
max
=
FFMAX
(
max
,
p6
);
min
=
FFMIN
(
min
,
p7
);
max
=
FFMAX
(
max
,
p7
);
if
(
max
-
min
<
2
*
quant
)
{
ptr
[
-
2
*
a_stride
]
=
(
4
*
p2
+
3
*
p3
+
1
*
p7
+
4
)
>>
3
;
ptr
[
-
1
*
a_stride
]
=
(
3
*
p2
+
3
*
p4
+
2
*
p7
+
4
)
>>
3
;
ptr
[
0
]
=
(
2
*
p2
+
3
*
p5
+
3
*
p7
+
4
)
>>
3
;
ptr
[
1
*
a_stride
]
=
(
1
*
p2
+
3
*
p6
+
4
*
p7
+
4
)
>>
3
;
continue
;
}
;
}
}
}
}
{
int
x
,
x0
,
x1
,
x2
;
int
x
,
x0
,
x1
,
x2
;
int
m
;
x0
=
(
2
*
p3
-
5
*
p4
+
5
*
p5
-
2
*
p6
+
4
)
>>
3
;
if
(
FFABS
(
x0
)
<
quant
)
{
x1
=
(
2
*
p1
-
5
*
p2
+
5
*
p3
-
2
*
p4
+
4
)
>>
3
;
x2
=
(
2
*
p5
-
5
*
p6
+
5
*
p7
-
2
*
p8
+
4
)
>>
3
;
x0
=
(
2
*
p3
-
5
*
p4
+
5
*
p5
-
2
*
p6
+
4
)
>>
3
;
if
(
FFABS
(
x0
)
<
quant
)
{
x1
=
(
2
*
p1
-
5
*
p2
+
5
*
p3
-
2
*
p4
+
4
)
>>
3
;
x2
=
(
2
*
p5
-
5
*
p6
+
5
*
p7
-
2
*
p8
+
4
)
>>
3
;
x
=
FFABS
(
x0
)
-
FFMIN
(
FFABS
(
x1
),
FFABS
(
x2
)
);
m
=
p4
-
p5
;
x
=
FFABS
(
x0
)
-
FFMIN
(
FFABS
(
x1
),
FFABS
(
x2
)
);
m
=
p4
-
p5
;
if
(
x
>
0
&&
(
m
^
x0
)
<
0
)
{
if
(
x
>
0
&&
(
m
^
x0
)
<
0
)
{
int32_t
sign
;
sign
=
m
>>
31
;
m
=
(
m
^
sign
)
-
sign
;
//
abs(m)
m
>>=
1
;
sign
=
m
>>
31
;
m
=
(
m
^
sign
)
-
sign
;
//
abs(m)
m
>>=
1
;
x
=
(
5
*
x
)
>>
3
;
x
=
(
5
*
x
)
>>
3
;
if
(
x
>
m
)
x
=
m
;
if
(
x
>
m
)
x
=
m
;
x
=
(
x
^
sign
)
-
sign
;
x
=
(
x
^
sign
)
-
sign
;
ptr
[
-
1
*
a_stride
]
-=
x
;
ptr
[
0
]
+=
x
;
ptr
[
-
1
*
a_stride
]
-=
x
;
ptr
[
0
]
+=
x
;
}
}
}
}
}
static
void
x8_h_loop_filter
(
uint8_t
*
src
,
int
stride
,
int
qscale
){
static
void
x8_h_loop_filter
(
uint8_t
*
src
,
int
stride
,
int
qscale
)
{
x8_loop_filter
(
src
,
stride
,
1
,
qscale
);
}
static
void
x8_v_loop_filter
(
uint8_t
*
src
,
int
stride
,
int
qscale
){
static
void
x8_v_loop_filter
(
uint8_t
*
src
,
int
stride
,
int
qscale
)
{
x8_loop_filter
(
src
,
1
,
stride
,
qscale
);
}
av_cold
void
ff_intrax8dsp_init
(
IntraX8DSPContext
*
dsp
)
{
dsp
->
h_loop_filter
=
x8_h_loop_filter
;
dsp
->
v_loop_filter
=
x8_v_loop_filter
;
dsp
->
setup_spatial_compensation
=
x8_setup_spatial_compensation
;
dsp
->
spatial_compensation
[
0
]
=
spatial_compensation_0
;
dsp
->
spatial_compensation
[
1
]
=
spatial_compensation_1
;
dsp
->
spatial_compensation
[
2
]
=
spatial_compensation_2
;
dsp
->
spatial_compensation
[
3
]
=
spatial_compensation_3
;
dsp
->
spatial_compensation
[
4
]
=
spatial_compensation_4
;
dsp
->
spatial_compensation
[
5
]
=
spatial_compensation_5
;
dsp
->
spatial_compensation
[
6
]
=
spatial_compensation_6
;
dsp
->
spatial_compensation
[
7
]
=
spatial_compensation_7
;
dsp
->
spatial_compensation
[
8
]
=
spatial_compensation_8
;
dsp
->
spatial_compensation
[
9
]
=
spatial_compensation_9
;
dsp
->
spatial_compensation
[
10
]
=
spatial_compensation_10
;
dsp
->
spatial_compensation
[
11
]
=
spatial_compensation_11
;
dsp
->
h_loop_filter
=
x8_h_loop_filter
;
dsp
->
v_loop_filter
=
x8_v_loop_filter
;
dsp
->
setup_spatial_compensation
=
x8_setup_spatial_compensation
;
dsp
->
spatial_compensation
[
0
]
=
spatial_compensation_0
;
dsp
->
spatial_compensation
[
1
]
=
spatial_compensation_1
;
dsp
->
spatial_compensation
[
2
]
=
spatial_compensation_2
;
dsp
->
spatial_compensation
[
3
]
=
spatial_compensation_3
;
dsp
->
spatial_compensation
[
4
]
=
spatial_compensation_4
;
dsp
->
spatial_compensation
[
5
]
=
spatial_compensation_5
;
dsp
->
spatial_compensation
[
6
]
=
spatial_compensation_6
;
dsp
->
spatial_compensation
[
7
]
=
spatial_compensation_7
;
dsp
->
spatial_compensation
[
8
]
=
spatial_compensation_8
;
dsp
->
spatial_compensation
[
9
]
=
spatial_compensation_9
;
dsp
->
spatial_compensation
[
10
]
=
spatial_compensation_10
;
dsp
->
spatial_compensation
[
11
]
=
spatial_compensation_11
;
}
libavcodec/intrax8dsp.h
View file @
2ade1cda
...
...
@@ -25,7 +25,7 @@ typedef struct IntraX8DSPContext {
void
(
*
v_loop_filter
)(
uint8_t
*
src
,
int
stride
,
int
qscale
);
void
(
*
h_loop_filter
)(
uint8_t
*
src
,
int
stride
,
int
qscale
);
void
(
*
spatial_compensation
[
12
])(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
);
void
(
*
spatial_compensation
[
12
])(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
);
void
(
*
setup_spatial_compensation
)(
uint8_t
*
src
,
uint8_t
*
dst
,
int
linesize
,
int
*
range
,
int
*
sum
,
int
edges
);
}
IntraX8DSPContext
;
...
...
libavcodec/intrax8huf.h
View file @
2ade1cda
This source diff could not be displayed because it is too large. You can
view the blob
instead.
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